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    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscription: gpui::Subscription,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                        cx,
  552                    )
  553                    .await?;
  554
  555                    match (&mut initialization_options, override_options) {
  556                        (Some(initialization_options), Some(override_options)) => {
  557                            merge_json_value_into(override_options, initialization_options);
  558                        }
  559                        (None, override_options) => initialization_options = override_options,
  560                        _ => {}
  561                    }
  562
  563                    let initialization_params = cx.update(|cx| {
  564                        let mut params = language_server.default_initialize_params(
  565                            pull_diagnostics,
  566                            augments_syntax_tokens,
  567                            cx,
  568                        );
  569                        params.initialization_options = initialization_options;
  570                        adapter.adapter.prepare_initialize_params(params, cx)
  571                    })?;
  572
  573                    Self::setup_lsp_messages(
  574                        lsp_store.clone(),
  575                        &language_server,
  576                        delegate.clone(),
  577                        adapter.clone(),
  578                    );
  579
  580                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  581                        settings: workspace_config,
  582                    };
  583                    let language_server = cx
  584                        .update(|cx| {
  585                            let request_timeout = ProjectSettings::get_global(cx)
  586                                .global_lsp_settings
  587                                .get_request_timeout();
  588
  589                            language_server.initialize(
  590                                initialization_params,
  591                                Arc::new(did_change_configuration_params.clone()),
  592                                request_timeout,
  593                                cx,
  594                            )
  595                        })
  596                        .await
  597                        .inspect_err(|_| {
  598                            if let Some(lsp_store) = lsp_store.upgrade() {
  599                                lsp_store.update(cx, |lsp_store, cx| {
  600                                    lsp_store.cleanup_lsp_data(server_id);
  601                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  602                                });
  603                            }
  604                        })?;
  605
  606                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  607                        did_change_configuration_params,
  608                    )?;
  609
  610                    anyhow::Ok(language_server)
  611                }
  612                .await;
  613
  614                match result {
  615                    Ok(server) => {
  616                        lsp_store
  617                            .update(cx, |lsp_store, cx| {
  618                                lsp_store.insert_newly_running_language_server(
  619                                    adapter,
  620                                    server.clone(),
  621                                    server_id,
  622                                    key,
  623                                    pending_workspace_folders,
  624                                    cx,
  625                                );
  626                            })
  627                            .ok();
  628                        stderr_capture.lock().take();
  629                        Some(server)
  630                    }
  631
  632                    Err(err) => {
  633                        let log = stderr_capture.lock().take().unwrap_or_default();
  634                        delegate.update_status(
  635                            adapter.name(),
  636                            BinaryStatus::Failed {
  637                                error: if log.is_empty() {
  638                                    format!("{err:#}")
  639                                } else {
  640                                    format!("{err:#}\n-- stderr --\n{log}")
  641                                },
  642                            },
  643                        );
  644                        log::error!(
  645                            "Failed to start language server {server_name:?}: {}",
  646                            redact_command(&format!("{err:?}"))
  647                        );
  648                        if !log.is_empty() {
  649                            log::error!("server stderr: {}", redact_command(&log));
  650                        }
  651                        None
  652                    }
  653                }
  654            })
  655        };
  656        let state = LanguageServerState::Starting {
  657            startup,
  658            pending_workspace_folders,
  659        };
  660
  661        if update_binary_status {
  662            self.languages
  663                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  664        }
  665
  666        self.language_servers.insert(server_id, state);
  667        self.language_server_ids
  668            .entry(key)
  669            .or_insert(UnifiedLanguageServer {
  670                id: server_id,
  671                project_roots: Default::default(),
  672            });
  673        server_id
  674    }
  675
  676    fn get_language_server_binary(
  677        &self,
  678        worktree_abs_path: Arc<Path>,
  679        adapter: Arc<CachedLspAdapter>,
  680        settings: Arc<LspSettings>,
  681        toolchain: Option<Toolchain>,
  682        delegate: Arc<dyn LspAdapterDelegate>,
  683        allow_binary_download: bool,
  684        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  685        cx: &mut App,
  686    ) -> Task<Result<LanguageServerBinary>> {
  687        if let Some(settings) = &settings.binary
  688            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  689        {
  690            let settings = settings.clone();
  691            let languages = self.languages.clone();
  692            return cx.background_spawn(async move {
  693                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  694                    let already_trusted =  *wait_until_worktree_trust.borrow();
  695                    if !already_trusted {
  696                        log::info!(
  697                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  698                            adapter.name(),
  699                        );
  700                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  701                            if worktree_trusted {
  702                                break;
  703                            }
  704                        }
  705                        log::info!(
  706                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  707                            adapter.name(),
  708                        );
  709                    }
  710                    languages
  711                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  712                }
  713                let mut env = delegate.shell_env().await;
  714                env.extend(settings.env.unwrap_or_default());
  715
  716                Ok(LanguageServerBinary {
  717                    path: delegate.resolve_relative_path(path),
  718                    env: Some(env),
  719                    arguments: settings
  720                        .arguments
  721                        .unwrap_or_default()
  722                        .iter()
  723                        .map(Into::into)
  724                        .collect(),
  725                })
  726            });
  727        }
  728        let lsp_binary_options = LanguageServerBinaryOptions {
  729            allow_path_lookup: !settings
  730                .binary
  731                .as_ref()
  732                .and_then(|b| b.ignore_system_version)
  733                .unwrap_or_default(),
  734            allow_binary_download,
  735            pre_release: settings
  736                .fetch
  737                .as_ref()
  738                .and_then(|f| f.pre_release)
  739                .unwrap_or(false),
  740        };
  741
  742        cx.spawn(async move |cx| {
  743            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  744                let already_trusted =  *wait_until_worktree_trust.borrow();
  745                if !already_trusted {
  746                    log::info!(
  747                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  748                        adapter.name(),
  749                    );
  750                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  751                        if worktree_trusted {
  752                            break;
  753                        }
  754                    }
  755                    log::info!(
  756                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  757                            adapter.name(),
  758                    );
  759                }
  760            }
  761
  762            let (existing_binary, maybe_download_binary) = adapter
  763                .clone()
  764                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  765                .await
  766                .await;
  767
  768            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  769
  770            let mut binary = match (existing_binary, maybe_download_binary) {
  771                (binary, None) => binary?,
  772                (Err(_), Some(downloader)) => downloader.await?,
  773                (Ok(existing_binary), Some(downloader)) => {
  774                    let mut download_timeout = cx
  775                        .background_executor()
  776                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  777                        .fuse();
  778                    let mut downloader = downloader.fuse();
  779                    futures::select! {
  780                        _ = download_timeout => {
  781                            // Return existing binary and kick the existing work to the background.
  782                            cx.spawn(async move |_| downloader.await).detach();
  783                            Ok(existing_binary)
  784                        },
  785                        downloaded_or_existing_binary = downloader => {
  786                            // If download fails, this results in the existing binary.
  787                            downloaded_or_existing_binary
  788                        }
  789                    }?
  790                }
  791            };
  792            let mut shell_env = delegate.shell_env().await;
  793
  794            shell_env.extend(binary.env.unwrap_or_default());
  795
  796            if let Some(settings) = settings.binary.as_ref() {
  797                if let Some(arguments) = &settings.arguments {
  798                    binary.arguments = arguments.iter().map(Into::into).collect();
  799                }
  800                if let Some(env) = &settings.env {
  801                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  802                }
  803            }
  804
  805            binary.env = Some(shell_env);
  806            Ok(binary)
  807        })
  808    }
  809
  810    fn setup_lsp_messages(
  811        lsp_store: WeakEntity<LspStore>,
  812        language_server: &LanguageServer,
  813        delegate: Arc<dyn LspAdapterDelegate>,
  814        adapter: Arc<CachedLspAdapter>,
  815    ) {
  816        let name = language_server.name();
  817        let server_id = language_server.server_id();
  818        language_server
  819            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  820                let adapter = adapter.clone();
  821                let this = lsp_store.clone();
  822                move |mut params, cx| {
  823                    let adapter = adapter.clone();
  824                    if let Some(this) = this.upgrade() {
  825                        this.update(cx, |this, cx| {
  826                            {
  827                                let buffer = params
  828                                    .uri
  829                                    .to_file_path()
  830                                    .map(|file_path| this.get_buffer(&file_path, cx))
  831                                    .ok()
  832                                    .flatten();
  833                                adapter.process_diagnostics(&mut params, server_id, buffer);
  834                            }
  835
  836                            this.merge_lsp_diagnostics(
  837                                DiagnosticSourceKind::Pushed,
  838                                vec![DocumentDiagnosticsUpdate {
  839                                    server_id,
  840                                    diagnostics: params,
  841                                    result_id: None,
  842                                    disk_based_sources: Cow::Borrowed(
  843                                        &adapter.disk_based_diagnostic_sources,
  844                                    ),
  845                                    registration_id: None,
  846                                }],
  847                                |_, diagnostic, cx| match diagnostic.source_kind {
  848                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  849                                        adapter.retain_old_diagnostic(diagnostic, cx)
  850                                    }
  851                                    DiagnosticSourceKind::Pulled => true,
  852                                },
  853                                cx,
  854                            )
  855                            .log_err();
  856                        });
  857                    }
  858                }
  859            })
  860            .detach();
  861        language_server
  862            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  863                let adapter = adapter.adapter.clone();
  864                let delegate = delegate.clone();
  865                let this = lsp_store.clone();
  866                move |params, cx| {
  867                    let adapter = adapter.clone();
  868                    let delegate = delegate.clone();
  869                    let this = this.clone();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let toolchain_for_id = this
  873                            .update(&mut cx, |this, _| {
  874                                this.as_local()?.language_server_ids.iter().find_map(
  875                                    |(seed, value)| {
  876                                        (value.id == server_id).then(|| seed.toolchain.clone())
  877                                    },
  878                                )
  879                            })?
  880                            .context("Expected the LSP store to be in a local mode")?;
  881
  882                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  883                        for item in &params.items {
  884                            let scope_uri = item.scope_uri.clone();
  885                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  886                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  887                            else {
  888                                // We've already queried workspace configuration of this URI.
  889                                continue;
  890                            };
  891                            let workspace_config = Self::workspace_configuration_for_adapter(
  892                                adapter.clone(),
  893                                &delegate,
  894                                toolchain_for_id.clone(),
  895                                scope_uri,
  896                                &mut cx,
  897                            )
  898                            .await?;
  899                            new_scope_uri.insert(workspace_config);
  900                        }
  901
  902                        Ok(params
  903                            .items
  904                            .into_iter()
  905                            .filter_map(|item| {
  906                                let workspace_config =
  907                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  908                                if let Some(section) = &item.section {
  909                                    Some(
  910                                        workspace_config
  911                                            .get(section)
  912                                            .cloned()
  913                                            .unwrap_or(serde_json::Value::Null),
  914                                    )
  915                                } else {
  916                                    Some(workspace_config.clone())
  917                                }
  918                            })
  919                            .collect())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  927                let this = lsp_store.clone();
  928                move |_, cx| {
  929                    let this = this.clone();
  930                    let cx = cx.clone();
  931                    async move {
  932                        let Some(server) =
  933                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  934                        else {
  935                            return Ok(None);
  936                        };
  937                        let root = server.workspace_folders();
  938                        Ok(Some(
  939                            root.into_iter()
  940                                .map(|uri| WorkspaceFolder {
  941                                    uri,
  942                                    name: Default::default(),
  943                                })
  944                                .collect(),
  945                        ))
  946                    }
  947                }
  948            })
  949            .detach();
  950        // Even though we don't have handling for these requests, respond to them to
  951        // avoid stalling any language server like `gopls` which waits for a response
  952        // to these requests when initializing.
  953        language_server
  954            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let this = this.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        this.update(&mut cx, |this, _| {
  961                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  962                            {
  963                                status
  964                                    .progress_tokens
  965                                    .insert(ProgressToken::from_lsp(params.token));
  966                            }
  967                        })?;
  968
  969                        Ok(())
  970                    }
  971                }
  972            })
  973            .detach();
  974
  975        language_server
  976            .on_request::<lsp::request::RegisterCapability, _, _>({
  977                let lsp_store = lsp_store.clone();
  978                move |params, cx| {
  979                    let lsp_store = lsp_store.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                if lsp_store.as_local().is_some() {
  985                                    match lsp_store
  986                                        .register_server_capabilities(server_id, params, cx)
  987                                    {
  988                                        Ok(()) => {}
  989                                        Err(e) => {
  990                                            log::error!(
  991                                                "Failed to register server capabilities: {e:#}"
  992                                            );
  993                                        }
  994                                    };
  995                                }
  996                            })
  997                            .ok();
  998                        Ok(())
  999                    }
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        language_server
 1005            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1006                let lsp_store = lsp_store.clone();
 1007                move |params, cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let mut cx = cx.clone();
 1010                    async move {
 1011                        lsp_store
 1012                            .update(&mut cx, |lsp_store, cx| {
 1013                                if lsp_store.as_local().is_some() {
 1014                                    match lsp_store
 1015                                        .unregister_server_capabilities(server_id, params, cx)
 1016                                    {
 1017                                        Ok(()) => {}
 1018                                        Err(e) => {
 1019                                            log::error!(
 1020                                                "Failed to unregister server capabilities: {e:#}"
 1021                                            );
 1022                                        }
 1023                                    }
 1024                                }
 1025                            })
 1026                            .ok();
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |params, cx| {
 1037                    let mut cx = cx.clone();
 1038                    let this = this.clone();
 1039                    async move {
 1040                        LocalLspStore::on_lsp_workspace_edit(
 1041                            this.clone(),
 1042                            params,
 1043                            server_id,
 1044                            &mut cx,
 1045                        )
 1046                        .await
 1047                    }
 1048                }
 1049            })
 1050            .detach();
 1051
 1052        language_server
 1053            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1054                let lsp_store = lsp_store.clone();
 1055                let request_id = Arc::new(AtomicUsize::new(0));
 1056                move |(), cx| {
 1057                    let lsp_store = lsp_store.clone();
 1058                    let request_id = request_id.clone();
 1059                    let mut cx = cx.clone();
 1060                    async move {
 1061                        lsp_store
 1062                            .update(&mut cx, |lsp_store, cx| {
 1063                                let request_id =
 1064                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1065                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1066                                    server_id,
 1067                                    request_id,
 1068                                });
 1069                                lsp_store
 1070                                    .downstream_client
 1071                                    .as_ref()
 1072                                    .map(|(client, project_id)| {
 1073                                        client.send(proto::RefreshInlayHints {
 1074                                            project_id: *project_id,
 1075                                            server_id: server_id.to_proto(),
 1076                                            request_id: request_id.map(|id| id as u64),
 1077                                        })
 1078                                    })
 1079                            })?
 1080                            .transpose()?;
 1081                        Ok(())
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        language_server
 1088            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1089                let this = lsp_store.clone();
 1090                move |(), cx| {
 1091                    let this = this.clone();
 1092                    let mut cx = cx.clone();
 1093                    async move {
 1094                        this.update(&mut cx, |this, cx| {
 1095                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1096                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1097                                client.send(proto::RefreshCodeLens {
 1098                                    project_id: *project_id,
 1099                                })
 1100                            })
 1101                        })?
 1102                        .transpose()?;
 1103                        Ok(())
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108
 1109        language_server
 1110            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1111                let lsp_store = lsp_store.clone();
 1112                let request_id = Arc::new(AtomicUsize::new(0));
 1113                move |(), cx| {
 1114                    let lsp_store = lsp_store.clone();
 1115                    let request_id = request_id.clone();
 1116                    let mut cx = cx.clone();
 1117                    async move {
 1118                        lsp_store
 1119                            .update(&mut cx, |lsp_store, cx| {
 1120                                let request_id =
 1121                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1122                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1123                                    server_id,
 1124                                    request_id,
 1125                                });
 1126                                lsp_store
 1127                                    .downstream_client
 1128                                    .as_ref()
 1129                                    .map(|(client, project_id)| {
 1130                                        client.send(proto::RefreshSemanticTokens {
 1131                                            project_id: *project_id,
 1132                                            server_id: server_id.to_proto(),
 1133                                            request_id: request_id.map(|id| id as u64),
 1134                                        })
 1135                                    })
 1136                            })?
 1137                            .transpose()?;
 1138                        Ok(())
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1146                let this = lsp_store.clone();
 1147                move |(), cx| {
 1148                    let this = this.clone();
 1149                    let mut cx = cx.clone();
 1150                    async move {
 1151                        this.update(&mut cx, |lsp_store, cx| {
 1152                            lsp_store.pull_workspace_diagnostics(server_id);
 1153                            lsp_store
 1154                                .downstream_client
 1155                                .as_ref()
 1156                                .map(|(client, project_id)| {
 1157                                    client.send(proto::PullWorkspaceDiagnostics {
 1158                                        project_id: *project_id,
 1159                                        server_id: server_id.to_proto(),
 1160                                    })
 1161                                })
 1162                                .transpose()?;
 1163                            anyhow::Ok(
 1164                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1165                            )
 1166                        })??
 1167                        .await;
 1168                        Ok(())
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1176                let this = lsp_store.clone();
 1177                let name = name.to_string();
 1178                let adapter = adapter.clone();
 1179                move |params, cx| {
 1180                    let this = this.clone();
 1181                    let name = name.to_string();
 1182                    let adapter = adapter.clone();
 1183                    let mut cx = cx.clone();
 1184                    async move {
 1185                        let actions = params.actions.unwrap_or_default();
 1186                        let message = params.message.clone();
 1187                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1188                        let level = match params.typ {
 1189                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1190                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1191                            _ => PromptLevel::Info,
 1192                        };
 1193                        let request = LanguageServerPromptRequest::new(
 1194                            level,
 1195                            params.message,
 1196                            actions,
 1197                            name.clone(),
 1198                            tx,
 1199                        );
 1200
 1201                        let did_update = this
 1202                            .update(&mut cx, |_, cx| {
 1203                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1204                            })
 1205                            .is_ok();
 1206                        if did_update {
 1207                            let response = rx.recv().await.ok();
 1208                            if let Some(ref selected_action) = response {
 1209                                let context = language::PromptResponseContext {
 1210                                    message,
 1211                                    selected_action: selected_action.clone(),
 1212                                };
 1213                                adapter.process_prompt_response(&context, &mut cx)
 1214                            }
 1215
 1216                            Ok(response)
 1217                        } else {
 1218                            Ok(None)
 1219                        }
 1220                    }
 1221                }
 1222            })
 1223            .detach();
 1224        language_server
 1225            .on_notification::<lsp::notification::ShowMessage, _>({
 1226                let this = lsp_store.clone();
 1227                let name = name.to_string();
 1228                move |params, cx| {
 1229                    let this = this.clone();
 1230                    let name = name.to_string();
 1231                    let mut cx = cx.clone();
 1232
 1233                    let (tx, _) = smol::channel::bounded(1);
 1234                    let level = match params.typ {
 1235                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1236                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1237                        _ => PromptLevel::Info,
 1238                    };
 1239                    let request =
 1240                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1241
 1242                    let _ = this.update(&mut cx, |_, cx| {
 1243                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1244                    });
 1245                }
 1246            })
 1247            .detach();
 1248
 1249        let disk_based_diagnostics_progress_token =
 1250            adapter.disk_based_diagnostics_progress_token.clone();
 1251
 1252        language_server
 1253            .on_notification::<lsp::notification::Progress, _>({
 1254                let this = lsp_store.clone();
 1255                move |params, cx| {
 1256                    if let Some(this) = this.upgrade() {
 1257                        this.update(cx, |this, cx| {
 1258                            this.on_lsp_progress(
 1259                                params,
 1260                                server_id,
 1261                                disk_based_diagnostics_progress_token.clone(),
 1262                                cx,
 1263                            );
 1264                        });
 1265                    }
 1266                }
 1267            })
 1268            .detach();
 1269
 1270        language_server
 1271            .on_notification::<lsp::notification::LogMessage, _>({
 1272                let this = lsp_store.clone();
 1273                move |params, cx| {
 1274                    if let Some(this) = this.upgrade() {
 1275                        this.update(cx, |_, cx| {
 1276                            cx.emit(LspStoreEvent::LanguageServerLog(
 1277                                server_id,
 1278                                LanguageServerLogType::Log(params.typ),
 1279                                params.message,
 1280                            ));
 1281                        });
 1282                    }
 1283                }
 1284            })
 1285            .detach();
 1286
 1287        language_server
 1288            .on_notification::<lsp::notification::LogTrace, _>({
 1289                let this = lsp_store.clone();
 1290                move |params, cx| {
 1291                    let mut cx = cx.clone();
 1292                    if let Some(this) = this.upgrade() {
 1293                        this.update(&mut cx, |_, cx| {
 1294                            cx.emit(LspStoreEvent::LanguageServerLog(
 1295                                server_id,
 1296                                LanguageServerLogType::Trace {
 1297                                    verbose_info: params.verbose,
 1298                                },
 1299                                params.message,
 1300                            ));
 1301                        });
 1302                    }
 1303                }
 1304            })
 1305            .detach();
 1306
 1307        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1309        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1310        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1311    }
 1312
 1313    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1314        let shutdown_futures = self
 1315            .language_servers
 1316            .drain()
 1317            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1318            .collect::<Vec<_>>();
 1319
 1320        async move {
 1321            join_all(shutdown_futures).await;
 1322        }
 1323    }
 1324
 1325    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1326        match server_state {
 1327            LanguageServerState::Running { server, .. } => {
 1328                if let Some(shutdown) = server.shutdown() {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332            LanguageServerState::Starting { startup, .. } => {
 1333                if let Some(server) = startup.await
 1334                    && let Some(shutdown) = server.shutdown()
 1335                {
 1336                    shutdown.await;
 1337                }
 1338            }
 1339        }
 1340        Ok(())
 1341    }
 1342
 1343    fn language_servers_for_worktree(
 1344        &self,
 1345        worktree_id: WorktreeId,
 1346    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1347        self.language_server_ids
 1348            .iter()
 1349            .filter_map(move |(seed, state)| {
 1350                if seed.worktree_id != worktree_id {
 1351                    return None;
 1352                }
 1353
 1354                if let Some(LanguageServerState::Running { server, .. }) =
 1355                    self.language_servers.get(&state.id)
 1356                {
 1357                    Some(server)
 1358                } else {
 1359                    None
 1360                }
 1361            })
 1362    }
 1363
 1364    fn language_server_ids_for_project_path(
 1365        &self,
 1366        project_path: ProjectPath,
 1367        language: &Language,
 1368        cx: &mut App,
 1369    ) -> Vec<LanguageServerId> {
 1370        let Some(worktree) = self
 1371            .worktree_store
 1372            .read(cx)
 1373            .worktree_for_id(project_path.worktree_id, cx)
 1374        else {
 1375            return Vec::new();
 1376        };
 1377        let delegate: Arc<dyn ManifestDelegate> =
 1378            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1379
 1380        self.lsp_tree
 1381            .get(
 1382                project_path,
 1383                language.name(),
 1384                language.manifest(),
 1385                &delegate,
 1386                cx,
 1387            )
 1388            .collect::<Vec<_>>()
 1389    }
 1390
 1391    fn language_server_ids_for_buffer(
 1392        &self,
 1393        buffer: &Buffer,
 1394        cx: &mut App,
 1395    ) -> Vec<LanguageServerId> {
 1396        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1397            let worktree_id = file.worktree_id(cx);
 1398
 1399            let path: Arc<RelPath> = file
 1400                .path()
 1401                .parent()
 1402                .map(Arc::from)
 1403                .unwrap_or_else(|| file.path().clone());
 1404            let worktree_path = ProjectPath { worktree_id, path };
 1405            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1406        } else {
 1407            Vec::new()
 1408        }
 1409    }
 1410
 1411    fn language_servers_for_buffer<'a>(
 1412        &'a self,
 1413        buffer: &'a Buffer,
 1414        cx: &'a mut App,
 1415    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1416        self.language_server_ids_for_buffer(buffer, cx)
 1417            .into_iter()
 1418            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1419                LanguageServerState::Running {
 1420                    adapter, server, ..
 1421                } => Some((adapter, server)),
 1422                _ => None,
 1423            })
 1424    }
 1425
 1426    async fn execute_code_action_kind_locally(
 1427        lsp_store: WeakEntity<LspStore>,
 1428        mut buffers: Vec<Entity<Buffer>>,
 1429        kind: CodeActionKind,
 1430        push_to_history: bool,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent code actions requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.read(cx).remote_id())
 1440            });
 1441        })?;
 1442        let _cleanup = defer({
 1443            let this = lsp_store.clone();
 1444            let mut cx = cx.clone();
 1445            let buffers = &buffers;
 1446            move || {
 1447                this.update(&mut cx, |this, cx| {
 1448                    let this = this.as_local_mut().unwrap();
 1449                    for buffer in buffers {
 1450                        this.buffers_being_formatted
 1451                            .remove(&buffer.read(cx).remote_id());
 1452                    }
 1453                })
 1454                .ok();
 1455            }
 1456        });
 1457        let mut project_transaction = ProjectTransaction::default();
 1458
 1459        for buffer in &buffers {
 1460            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1461                buffer.update(cx, |buffer, cx| {
 1462                    lsp_store
 1463                        .as_local()
 1464                        .unwrap()
 1465                        .language_servers_for_buffer(buffer, cx)
 1466                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1467                        .collect::<Vec<_>>()
 1468                })
 1469            })?;
 1470            for (_, language_server) in adapters_and_servers.iter() {
 1471                let actions = Self::get_server_code_actions_from_action_kinds(
 1472                    &lsp_store,
 1473                    language_server.server_id(),
 1474                    vec![kind.clone()],
 1475                    buffer,
 1476                    cx,
 1477                )
 1478                .await?;
 1479                Self::execute_code_actions_on_server(
 1480                    &lsp_store,
 1481                    language_server,
 1482                    actions,
 1483                    push_to_history,
 1484                    &mut project_transaction,
 1485                    cx,
 1486                )
 1487                .await?;
 1488            }
 1489        }
 1490        Ok(project_transaction)
 1491    }
 1492
 1493    async fn format_locally(
 1494        lsp_store: WeakEntity<LspStore>,
 1495        mut buffers: Vec<FormattableBuffer>,
 1496        push_to_history: bool,
 1497        trigger: FormatTrigger,
 1498        logger: zlog::Logger,
 1499        cx: &mut AsyncApp,
 1500    ) -> anyhow::Result<ProjectTransaction> {
 1501        // Do not allow multiple concurrent formatting requests for the
 1502        // same buffer.
 1503        lsp_store.update(cx, |this, cx| {
 1504            let this = this.as_local_mut().unwrap();
 1505            buffers.retain(|buffer| {
 1506                this.buffers_being_formatted
 1507                    .insert(buffer.handle.read(cx).remote_id())
 1508            });
 1509        })?;
 1510
 1511        let _cleanup = defer({
 1512            let this = lsp_store.clone();
 1513            let mut cx = cx.clone();
 1514            let buffers = &buffers;
 1515            move || {
 1516                this.update(&mut cx, |this, cx| {
 1517                    let this = this.as_local_mut().unwrap();
 1518                    for buffer in buffers {
 1519                        this.buffers_being_formatted
 1520                            .remove(&buffer.handle.read(cx).remote_id());
 1521                    }
 1522                })
 1523                .ok();
 1524            }
 1525        });
 1526
 1527        let mut project_transaction = ProjectTransaction::default();
 1528
 1529        for buffer in &buffers {
 1530            zlog::debug!(
 1531                logger =>
 1532                "formatting buffer '{:?}'",
 1533                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1534            );
 1535            // Create an empty transaction to hold all of the formatting edits.
 1536            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1537                // ensure no transactions created while formatting are
 1538                // grouped with the previous transaction in the history
 1539                // based on the transaction group interval
 1540                buffer.finalize_last_transaction();
 1541                buffer
 1542                    .start_transaction()
 1543                    .context("transaction already open")?;
 1544                buffer.end_transaction(cx);
 1545                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1546                buffer.finalize_last_transaction();
 1547                anyhow::Ok(transaction_id)
 1548            })?;
 1549
 1550            let result = Self::format_buffer_locally(
 1551                lsp_store.clone(),
 1552                buffer,
 1553                formatting_transaction_id,
 1554                trigger,
 1555                logger,
 1556                cx,
 1557            )
 1558            .await;
 1559
 1560            buffer.handle.update(cx, |buffer, cx| {
 1561                let Some(formatting_transaction) =
 1562                    buffer.get_transaction(formatting_transaction_id).cloned()
 1563                else {
 1564                    zlog::warn!(logger => "no formatting transaction");
 1565                    return;
 1566                };
 1567                if formatting_transaction.edit_ids.is_empty() {
 1568                    zlog::debug!(logger => "no changes made while formatting");
 1569                    buffer.forget_transaction(formatting_transaction_id);
 1570                    return;
 1571                }
 1572                if !push_to_history {
 1573                    zlog::trace!(logger => "forgetting format transaction");
 1574                    buffer.forget_transaction(formatting_transaction.id);
 1575                }
 1576                project_transaction
 1577                    .0
 1578                    .insert(cx.entity(), formatting_transaction);
 1579            });
 1580
 1581            result?;
 1582        }
 1583
 1584        Ok(project_transaction)
 1585    }
 1586
 1587    async fn format_buffer_locally(
 1588        lsp_store: WeakEntity<LspStore>,
 1589        buffer: &FormattableBuffer,
 1590        formatting_transaction_id: clock::Lamport,
 1591        trigger: FormatTrigger,
 1592        logger: zlog::Logger,
 1593        cx: &mut AsyncApp,
 1594    ) -> Result<()> {
 1595        let (adapters_and_servers, settings, request_timeout) =
 1596            lsp_store.update(cx, |lsp_store, cx| {
 1597                buffer.handle.update(cx, |buffer, cx| {
 1598                    let adapters_and_servers = lsp_store
 1599                        .as_local()
 1600                        .unwrap()
 1601                        .language_servers_for_buffer(buffer, cx)
 1602                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1603                        .collect::<Vec<_>>();
 1604                    let settings =
 1605                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1606                            .into_owned();
 1607                    let request_timeout = ProjectSettings::get_global(cx)
 1608                        .global_lsp_settings
 1609                        .get_request_timeout();
 1610                    (adapters_and_servers, settings, request_timeout)
 1611                })
 1612            })?;
 1613
 1614        // handle whitespace formatting
 1615        if settings.remove_trailing_whitespace_on_save {
 1616            zlog::trace!(logger => "removing trailing whitespace");
 1617            let diff = buffer
 1618                .handle
 1619                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1620                .await;
 1621            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1622                buffer.apply_diff(diff, cx);
 1623            })?;
 1624        }
 1625
 1626        if settings.ensure_final_newline_on_save {
 1627            zlog::trace!(logger => "ensuring final newline");
 1628            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1629                buffer.ensure_final_newline(cx);
 1630            })?;
 1631        }
 1632
 1633        // Formatter for `code_actions_on_format` that runs before
 1634        // the rest of the formatters
 1635        let mut code_actions_on_format_formatters = None;
 1636        let should_run_code_actions_on_format = !matches!(
 1637            (trigger, &settings.format_on_save),
 1638            (FormatTrigger::Save, &FormatOnSave::Off)
 1639        );
 1640        if should_run_code_actions_on_format {
 1641            let have_code_actions_to_run_on_format = settings
 1642                .code_actions_on_format
 1643                .values()
 1644                .any(|enabled| *enabled);
 1645            if have_code_actions_to_run_on_format {
 1646                zlog::trace!(logger => "going to run code actions on format");
 1647                code_actions_on_format_formatters = Some(
 1648                    settings
 1649                        .code_actions_on_format
 1650                        .iter()
 1651                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1652                        .cloned()
 1653                        .map(Formatter::CodeAction)
 1654                        .collect::<Vec<_>>(),
 1655                );
 1656            }
 1657        }
 1658
 1659        let formatters = match (trigger, &settings.format_on_save) {
 1660            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1661            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1662                settings.formatter.as_ref()
 1663            }
 1664        };
 1665
 1666        let formatters = code_actions_on_format_formatters
 1667            .iter()
 1668            .flatten()
 1669            .chain(formatters);
 1670
 1671        for formatter in formatters {
 1672            let formatter = if formatter == &Formatter::Auto {
 1673                if settings.prettier.allowed {
 1674                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1675                    &Formatter::Prettier
 1676                } else {
 1677                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1678                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1679                }
 1680            } else {
 1681                formatter
 1682            };
 1683            if let Err(err) = Self::apply_formatter(
 1684                formatter,
 1685                &lsp_store,
 1686                buffer,
 1687                formatting_transaction_id,
 1688                &adapters_and_servers,
 1689                &settings,
 1690                request_timeout,
 1691                logger,
 1692                cx,
 1693            )
 1694            .await
 1695            {
 1696                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1697            }
 1698        }
 1699
 1700        Ok(())
 1701    }
 1702
 1703    async fn apply_formatter(
 1704        formatter: &Formatter,
 1705        lsp_store: &WeakEntity<LspStore>,
 1706        buffer: &FormattableBuffer,
 1707        formatting_transaction_id: clock::Lamport,
 1708        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1709        settings: &LanguageSettings,
 1710        request_timeout: Duration,
 1711        logger: zlog::Logger,
 1712        cx: &mut AsyncApp,
 1713    ) -> anyhow::Result<()> {
 1714        match formatter {
 1715            Formatter::None => {
 1716                zlog::trace!(logger => "skipping formatter 'none'");
 1717                return Ok(());
 1718            }
 1719            Formatter::Auto => {
 1720                debug_panic!("Auto resolved above");
 1721                return Ok(());
 1722            }
 1723            Formatter::Prettier => {
 1724                let logger = zlog::scoped!(logger => "prettier");
 1725                zlog::trace!(logger => "formatting");
 1726                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1727
 1728                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1729                    lsp_store.prettier_store().unwrap().downgrade()
 1730                })?;
 1731                let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1732                    .await
 1733                    .transpose()?;
 1734                let Some(diff) = diff else {
 1735                    zlog::trace!(logger => "No changes");
 1736                    return Ok(());
 1737                };
 1738
 1739                extend_formatting_transaction(
 1740                    buffer,
 1741                    formatting_transaction_id,
 1742                    cx,
 1743                    |buffer, cx| {
 1744                        buffer.apply_diff(diff, cx);
 1745                    },
 1746                )?;
 1747            }
 1748            Formatter::External { command, arguments } => {
 1749                let logger = zlog::scoped!(logger => "command");
 1750                zlog::trace!(logger => "formatting");
 1751                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1752
 1753                let diff =
 1754                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1755                        .await
 1756                        .with_context(|| {
 1757                            format!("Failed to format buffer via external command: {}", command)
 1758                        })?;
 1759                let Some(diff) = diff else {
 1760                    zlog::trace!(logger => "No changes");
 1761                    return Ok(());
 1762                };
 1763
 1764                extend_formatting_transaction(
 1765                    buffer,
 1766                    formatting_transaction_id,
 1767                    cx,
 1768                    |buffer, cx| {
 1769                        buffer.apply_diff(diff, cx);
 1770                    },
 1771                )?;
 1772            }
 1773            Formatter::LanguageServer(specifier) => {
 1774                let logger = zlog::scoped!(logger => "language-server");
 1775                zlog::trace!(logger => "formatting");
 1776                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1777
 1778                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1779                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1780                    return Ok(());
 1781                };
 1782
 1783                let language_server = match specifier {
 1784                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1785                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1786                            if adapter.name.0.as_ref() == name {
 1787                                Some(server.clone())
 1788                            } else {
 1789                                None
 1790                            }
 1791                        })
 1792                    }
 1793                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1794                        .iter()
 1795                        .find(|(_, server)| Self::server_supports_formatting(server))
 1796                        .map(|(_, server)| server.clone()),
 1797                };
 1798
 1799                let Some(language_server) = language_server else {
 1800                    log::debug!(
 1801                        "No language server found to format buffer '{:?}'. Skipping",
 1802                        buffer_path_abs.as_path().to_string_lossy()
 1803                    );
 1804                    return Ok(());
 1805                };
 1806
 1807                zlog::trace!(
 1808                    logger =>
 1809                    "Formatting buffer '{:?}' using language server '{:?}'",
 1810                    buffer_path_abs.as_path().to_string_lossy(),
 1811                    language_server.name()
 1812                );
 1813
 1814                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1815                    zlog::trace!(logger => "formatting ranges");
 1816                    Self::format_ranges_via_lsp(
 1817                        &lsp_store,
 1818                        &buffer.handle,
 1819                        ranges,
 1820                        buffer_path_abs,
 1821                        &language_server,
 1822                        &settings,
 1823                        cx,
 1824                    )
 1825                    .await
 1826                    .context("Failed to format ranges via language server")?
 1827                } else {
 1828                    zlog::trace!(logger => "formatting full");
 1829                    Self::format_via_lsp(
 1830                        &lsp_store,
 1831                        &buffer.handle,
 1832                        buffer_path_abs,
 1833                        &language_server,
 1834                        &settings,
 1835                        cx,
 1836                    )
 1837                    .await
 1838                    .context("failed to format via language server")?
 1839                };
 1840
 1841                if edits.is_empty() {
 1842                    zlog::trace!(logger => "No changes");
 1843                    return Ok(());
 1844                }
 1845                extend_formatting_transaction(
 1846                    buffer,
 1847                    formatting_transaction_id,
 1848                    cx,
 1849                    |buffer, cx| {
 1850                        buffer.edit(edits, None, cx);
 1851                    },
 1852                )?;
 1853            }
 1854            Formatter::CodeAction(code_action_name) => {
 1855                let logger = zlog::scoped!(logger => "code-actions");
 1856                zlog::trace!(logger => "formatting");
 1857                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1858
 1859                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1860                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1861                    return Ok(());
 1862                };
 1863
 1864                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1865                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1866
 1867                let mut actions_and_servers = Vec::new();
 1868
 1869                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1870                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1871                        &lsp_store,
 1872                        language_server.server_id(),
 1873                        vec![code_action_kind.clone()],
 1874                        &buffer.handle,
 1875                        cx,
 1876                    )
 1877                    .await
 1878                    .with_context(|| {
 1879                        format!(
 1880                            "Failed to resolve code action {:?} with language server {}",
 1881                            code_action_kind,
 1882                            language_server.name()
 1883                        )
 1884                    });
 1885                    let Ok(actions) = actions_result else {
 1886                        // note: it may be better to set result to the error and break formatters here
 1887                        // but for now we try to execute the actions that we can resolve and skip the rest
 1888                        zlog::error!(
 1889                            logger =>
 1890                            "Failed to resolve code action {:?} with language server {}",
 1891                            code_action_kind,
 1892                            language_server.name()
 1893                        );
 1894                        continue;
 1895                    };
 1896                    for action in actions {
 1897                        actions_and_servers.push((action, index));
 1898                    }
 1899                }
 1900
 1901                if actions_and_servers.is_empty() {
 1902                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1903                    return Ok(());
 1904                }
 1905
 1906                'actions: for (mut action, server_index) in actions_and_servers {
 1907                    let server = &adapters_and_servers[server_index].1;
 1908
 1909                    let describe_code_action = |action: &CodeAction| {
 1910                        format!(
 1911                            "code action '{}' with title \"{}\" on server {}",
 1912                            action
 1913                                .lsp_action
 1914                                .action_kind()
 1915                                .unwrap_or("unknown".into())
 1916                                .as_str(),
 1917                            action.lsp_action.title(),
 1918                            server.name(),
 1919                        )
 1920                    };
 1921
 1922                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1923
 1924                    if let Err(err) =
 1925                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1926                    {
 1927                        zlog::error!(
 1928                            logger =>
 1929                            "Failed to resolve {}. Error: {}",
 1930                            describe_code_action(&action),
 1931                            err
 1932                        );
 1933                        continue;
 1934                    }
 1935
 1936                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1937                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1938                        // but filters out and logs warnings for code actions that require unreasonably
 1939                        // difficult handling on our part, such as:
 1940                        // - applying edits that call commands
 1941                        //   which can result in arbitrary workspace edits being sent from the server that
 1942                        //   have no way of being tied back to the command that initiated them (i.e. we
 1943                        //   can't know which edits are part of the format request, or if the server is done sending
 1944                        //   actions in response to the command)
 1945                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1946                        //   as we then would need to handle such changes correctly in the local history as well
 1947                        //   as the remote history through the ProjectTransaction
 1948                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1949                        // Supporting these actions is not impossible, but not supported as of yet.
 1950                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1951                            zlog::trace!(
 1952                                logger =>
 1953                                "No changes for code action. Skipping {}",
 1954                                describe_code_action(&action),
 1955                            );
 1956                            continue;
 1957                        }
 1958
 1959                        let mut operations = Vec::new();
 1960                        if let Some(document_changes) = edit.document_changes {
 1961                            match document_changes {
 1962                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 1963                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1964                                ),
 1965                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 1966                            }
 1967                        } else if let Some(changes) = edit.changes {
 1968                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 1969                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1970                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 1971                                        uri,
 1972                                        version: None,
 1973                                    },
 1974                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 1975                                })
 1976                            }));
 1977                        }
 1978
 1979                        let mut edits = Vec::with_capacity(operations.len());
 1980
 1981                        if operations.is_empty() {
 1982                            zlog::trace!(
 1983                                logger =>
 1984                                "No changes for code action. Skipping {}",
 1985                                describe_code_action(&action),
 1986                            );
 1987                            continue;
 1988                        }
 1989                        for operation in operations {
 1990                            let op = match operation {
 1991                                lsp::DocumentChangeOperation::Edit(op) => op,
 1992                                lsp::DocumentChangeOperation::Op(_) => {
 1993                                    zlog::warn!(
 1994                                        logger =>
 1995                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1996                                        describe_code_action(&action),
 1997                                    );
 1998                                    continue 'actions;
 1999                                }
 2000                            };
 2001                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2002                                zlog::warn!(
 2003                                    logger =>
 2004                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2005                                    &op.text_document.uri,
 2006                                    describe_code_action(&action),
 2007                                );
 2008                                continue 'actions;
 2009                            };
 2010                            if &file_path != buffer_path_abs {
 2011                                zlog::warn!(
 2012                                    logger =>
 2013                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2014                                    file_path,
 2015                                    buffer_path_abs,
 2016                                    describe_code_action(&action),
 2017                                );
 2018                                continue 'actions;
 2019                            }
 2020
 2021                            let mut lsp_edits = Vec::new();
 2022                            for edit in op.edits {
 2023                                match edit {
 2024                                    Edit::Plain(edit) => {
 2025                                        if !lsp_edits.contains(&edit) {
 2026                                            lsp_edits.push(edit);
 2027                                        }
 2028                                    }
 2029                                    Edit::Annotated(edit) => {
 2030                                        if !lsp_edits.contains(&edit.text_edit) {
 2031                                            lsp_edits.push(edit.text_edit);
 2032                                        }
 2033                                    }
 2034                                    Edit::Snippet(_) => {
 2035                                        zlog::warn!(
 2036                                            logger =>
 2037                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2038                                            describe_code_action(&action),
 2039                                        );
 2040                                        continue 'actions;
 2041                                    }
 2042                                }
 2043                            }
 2044                            let edits_result = lsp_store
 2045                                .update(cx, |lsp_store, cx| {
 2046                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2047                                        &buffer.handle,
 2048                                        lsp_edits,
 2049                                        server.server_id(),
 2050                                        op.text_document.version,
 2051                                        cx,
 2052                                    )
 2053                                })?
 2054                                .await;
 2055                            let Ok(resolved_edits) = edits_result else {
 2056                                zlog::warn!(
 2057                                    logger =>
 2058                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2059                                    buffer_path_abs.as_path(),
 2060                                    describe_code_action(&action),
 2061                                );
 2062                                continue 'actions;
 2063                            };
 2064                            edits.extend(resolved_edits);
 2065                        }
 2066
 2067                        if edits.is_empty() {
 2068                            zlog::warn!(logger => "No edits resolved from LSP");
 2069                            continue;
 2070                        }
 2071
 2072                        extend_formatting_transaction(
 2073                            buffer,
 2074                            formatting_transaction_id,
 2075                            cx,
 2076                            |buffer, cx| {
 2077                                zlog::info!(
 2078                                    "Applying edits {edits:?}. Content: {:?}",
 2079                                    buffer.text()
 2080                                );
 2081                                buffer.edit(edits, None, cx);
 2082                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2083                            },
 2084                        )?;
 2085                    }
 2086
 2087                    let Some(command) = action.lsp_action.command() else {
 2088                        continue;
 2089                    };
 2090
 2091                    zlog::warn!(
 2092                        logger =>
 2093                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2094                        &command.command,
 2095                    );
 2096
 2097                    let server_capabilities = server.capabilities();
 2098                    let available_commands = server_capabilities
 2099                        .execute_command_provider
 2100                        .as_ref()
 2101                        .map(|options| options.commands.as_slice())
 2102                        .unwrap_or_default();
 2103                    if !available_commands.contains(&command.command) {
 2104                        zlog::warn!(
 2105                            logger =>
 2106                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2107                            command.command,
 2108                            server.name(),
 2109                        );
 2110                        continue;
 2111                    }
 2112
 2113                    extend_formatting_transaction(
 2114                        buffer,
 2115                        formatting_transaction_id,
 2116                        cx,
 2117                        |_, _| {},
 2118                    )?;
 2119                    zlog::info!(logger => "Executing command {}", &command.command);
 2120
 2121                    lsp_store.update(cx, |this, _| {
 2122                        this.as_local_mut()
 2123                            .unwrap()
 2124                            .last_workspace_edits_by_language_server
 2125                            .remove(&server.server_id());
 2126                    })?;
 2127
 2128                    let execute_command_result = server
 2129                        .request::<lsp::request::ExecuteCommand>(
 2130                            lsp::ExecuteCommandParams {
 2131                                command: command.command.clone(),
 2132                                arguments: command.arguments.clone().unwrap_or_default(),
 2133                                ..Default::default()
 2134                            },
 2135                            request_timeout,
 2136                        )
 2137                        .await
 2138                        .into_response();
 2139
 2140                    if execute_command_result.is_err() {
 2141                        zlog::error!(
 2142                            logger =>
 2143                            "Failed to execute command '{}' as part of {}",
 2144                            &command.command,
 2145                            describe_code_action(&action),
 2146                        );
 2147                        continue 'actions;
 2148                    }
 2149
 2150                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2151                        this.as_local_mut()
 2152                            .unwrap()
 2153                            .last_workspace_edits_by_language_server
 2154                            .remove(&server.server_id())
 2155                            .unwrap_or_default()
 2156                    })?;
 2157
 2158                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2159                    {
 2160                        zlog::trace!(
 2161                            logger =>
 2162                            "Successfully captured {} edits that resulted from command {}",
 2163                            transaction.edit_ids.len(),
 2164                            &command.command,
 2165                        );
 2166                        let transaction_id_project_transaction = transaction.id;
 2167                        buffer.handle.update(cx, |buffer, _| {
 2168                            // it may have been removed from history if push_to_history was
 2169                            // false in deserialize_workspace_edit. If so push it so we
 2170                            // can merge it with the format transaction
 2171                            // and pop the combined transaction off the history stack
 2172                            // later if push_to_history is false
 2173                            if buffer.get_transaction(transaction.id).is_none() {
 2174                                buffer.push_transaction(transaction, Instant::now());
 2175                            }
 2176                            buffer.merge_transactions(
 2177                                transaction_id_project_transaction,
 2178                                formatting_transaction_id,
 2179                            );
 2180                        });
 2181                    }
 2182
 2183                    if project_transaction_command.0.is_empty() {
 2184                        continue;
 2185                    }
 2186
 2187                    let mut extra_buffers = String::new();
 2188                    for buffer in project_transaction_command.0.keys() {
 2189                        buffer.read_with(cx, |b, cx| {
 2190                            let Some(path) = b.project_path(cx) else {
 2191                                return;
 2192                            };
 2193
 2194                            if !extra_buffers.is_empty() {
 2195                                extra_buffers.push_str(", ");
 2196                            }
 2197                            extra_buffers.push_str(path.path.as_unix_str());
 2198                        });
 2199                    }
 2200                    zlog::warn!(
 2201                        logger =>
 2202                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2203                        &command.command,
 2204                        extra_buffers,
 2205                    );
 2206                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2207                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2208                    // add it so it's included, and merge it into the format transaction when its created later
 2209                }
 2210            }
 2211        }
 2212
 2213        Ok(())
 2214    }
 2215
 2216    pub async fn format_ranges_via_lsp(
 2217        this: &WeakEntity<LspStore>,
 2218        buffer_handle: &Entity<Buffer>,
 2219        ranges: &[Range<Anchor>],
 2220        abs_path: &Path,
 2221        language_server: &Arc<LanguageServer>,
 2222        settings: &LanguageSettings,
 2223        cx: &mut AsyncApp,
 2224    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2225        let capabilities = &language_server.capabilities();
 2226        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2227        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2228            anyhow::bail!(
 2229                "{} language server does not support range formatting",
 2230                language_server.name()
 2231            );
 2232        }
 2233
 2234        let uri = file_path_to_lsp_url(abs_path)?;
 2235        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2236
 2237        let request_timeout = cx.update(|app| {
 2238            ProjectSettings::get_global(app)
 2239                .global_lsp_settings
 2240                .get_request_timeout()
 2241        });
 2242        let lsp_edits = {
 2243            let mut lsp_ranges = Vec::new();
 2244            this.update(cx, |_this, cx| {
 2245                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2246                // not have been sent to the language server. This seems like a fairly systemic
 2247                // issue, though, the resolution probably is not specific to formatting.
 2248                //
 2249                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2250                // LSP.
 2251                let snapshot = buffer_handle.read(cx).snapshot();
 2252                for range in ranges {
 2253                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2254                }
 2255                anyhow::Ok(())
 2256            })??;
 2257
 2258            let mut edits = None;
 2259            for range in lsp_ranges {
 2260                if let Some(mut edit) = language_server
 2261                    .request::<lsp::request::RangeFormatting>(
 2262                        lsp::DocumentRangeFormattingParams {
 2263                            text_document: text_document.clone(),
 2264                            range,
 2265                            options: lsp_command::lsp_formatting_options(settings),
 2266                            work_done_progress_params: Default::default(),
 2267                        },
 2268                        request_timeout,
 2269                    )
 2270                    .await
 2271                    .into_response()?
 2272                {
 2273                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2274                }
 2275            }
 2276            edits
 2277        };
 2278
 2279        if let Some(lsp_edits) = lsp_edits {
 2280            this.update(cx, |this, cx| {
 2281                this.as_local_mut().unwrap().edits_from_lsp(
 2282                    buffer_handle,
 2283                    lsp_edits,
 2284                    language_server.server_id(),
 2285                    None,
 2286                    cx,
 2287                )
 2288            })?
 2289            .await
 2290        } else {
 2291            Ok(Vec::with_capacity(0))
 2292        }
 2293    }
 2294
 2295    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2296        let capabilities = server.capabilities();
 2297        let formatting = capabilities.document_formatting_provider.as_ref();
 2298        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2299        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2300            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2301    }
 2302
 2303    async fn format_via_lsp(
 2304        this: &WeakEntity<LspStore>,
 2305        buffer: &Entity<Buffer>,
 2306        abs_path: &Path,
 2307        language_server: &Arc<LanguageServer>,
 2308        settings: &LanguageSettings,
 2309        cx: &mut AsyncApp,
 2310    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2311        let logger = zlog::scoped!("lsp_format");
 2312        zlog::debug!(logger => "Formatting via LSP");
 2313
 2314        let uri = file_path_to_lsp_url(abs_path)?;
 2315        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2316        let capabilities = &language_server.capabilities();
 2317
 2318        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2319        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2320
 2321        let request_timeout = cx.update(|app| {
 2322            ProjectSettings::get_global(app)
 2323                .global_lsp_settings
 2324                .get_request_timeout()
 2325        });
 2326
 2327        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2328            let _timer = zlog::time!(logger => "format-full");
 2329            language_server
 2330                .request::<lsp::request::Formatting>(
 2331                    lsp::DocumentFormattingParams {
 2332                        text_document,
 2333                        options: lsp_command::lsp_formatting_options(settings),
 2334                        work_done_progress_params: Default::default(),
 2335                    },
 2336                    request_timeout,
 2337                )
 2338                .await
 2339                .into_response()?
 2340        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2341            let _timer = zlog::time!(logger => "format-range");
 2342            let buffer_start = lsp::Position::new(0, 0);
 2343            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2344            language_server
 2345                .request::<lsp::request::RangeFormatting>(
 2346                    lsp::DocumentRangeFormattingParams {
 2347                        text_document: text_document.clone(),
 2348                        range: lsp::Range::new(buffer_start, buffer_end),
 2349                        options: lsp_command::lsp_formatting_options(settings),
 2350                        work_done_progress_params: Default::default(),
 2351                    },
 2352                    request_timeout,
 2353                )
 2354                .await
 2355                .into_response()?
 2356        } else {
 2357            None
 2358        };
 2359
 2360        if let Some(lsp_edits) = lsp_edits {
 2361            this.update(cx, |this, cx| {
 2362                this.as_local_mut().unwrap().edits_from_lsp(
 2363                    buffer,
 2364                    lsp_edits,
 2365                    language_server.server_id(),
 2366                    None,
 2367                    cx,
 2368                )
 2369            })?
 2370            .await
 2371        } else {
 2372            Ok(Vec::with_capacity(0))
 2373        }
 2374    }
 2375
 2376    async fn format_via_external_command(
 2377        buffer: &FormattableBuffer,
 2378        command: &str,
 2379        arguments: Option<&[String]>,
 2380        cx: &mut AsyncApp,
 2381    ) -> Result<Option<Diff>> {
 2382        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2383            let file = File::from_dyn(buffer.file())?;
 2384            let worktree = file.worktree.read(cx);
 2385            let mut worktree_path = worktree.abs_path().to_path_buf();
 2386            if worktree.root_entry()?.is_file() {
 2387                worktree_path.pop();
 2388            }
 2389            Some(worktree_path)
 2390        });
 2391
 2392        use util::command::Stdio;
 2393        let mut child = util::command::new_command(command);
 2394
 2395        if let Some(buffer_env) = buffer.env.as_ref() {
 2396            child.envs(buffer_env);
 2397        }
 2398
 2399        if let Some(working_dir_path) = working_dir_path {
 2400            child.current_dir(working_dir_path);
 2401        }
 2402
 2403        if let Some(arguments) = arguments {
 2404            child.args(arguments.iter().map(|arg| {
 2405                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2406                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2407                } else {
 2408                    arg.replace("{buffer_path}", "Untitled")
 2409                }
 2410            }));
 2411        }
 2412
 2413        let mut child = child
 2414            .stdin(Stdio::piped())
 2415            .stdout(Stdio::piped())
 2416            .stderr(Stdio::piped())
 2417            .spawn()?;
 2418
 2419        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2420        let text = buffer
 2421            .handle
 2422            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2423        for chunk in text.chunks() {
 2424            stdin.write_all(chunk.as_bytes()).await?;
 2425        }
 2426        stdin.flush().await?;
 2427
 2428        let output = child.output().await?;
 2429        anyhow::ensure!(
 2430            output.status.success(),
 2431            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2432            output.status.code(),
 2433            String::from_utf8_lossy(&output.stdout),
 2434            String::from_utf8_lossy(&output.stderr),
 2435        );
 2436
 2437        let stdout = String::from_utf8(output.stdout)?;
 2438        Ok(Some(
 2439            buffer
 2440                .handle
 2441                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2442                .await,
 2443        ))
 2444    }
 2445
 2446    async fn try_resolve_code_action(
 2447        lang_server: &LanguageServer,
 2448        action: &mut CodeAction,
 2449        request_timeout: Duration,
 2450    ) -> anyhow::Result<()> {
 2451        match &mut action.lsp_action {
 2452            LspAction::Action(lsp_action) => {
 2453                if !action.resolved
 2454                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2455                    && lsp_action.data.is_some()
 2456                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2457                {
 2458                    **lsp_action = lang_server
 2459                        .request::<lsp::request::CodeActionResolveRequest>(
 2460                            *lsp_action.clone(),
 2461                            request_timeout,
 2462                        )
 2463                        .await
 2464                        .into_response()?;
 2465                }
 2466            }
 2467            LspAction::CodeLens(lens) => {
 2468                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2469                    *lens = lang_server
 2470                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2471                        .await
 2472                        .into_response()?;
 2473                }
 2474            }
 2475            LspAction::Command(_) => {}
 2476        }
 2477
 2478        action.resolved = true;
 2479        anyhow::Ok(())
 2480    }
 2481
 2482    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2483        let buffer = buffer_handle.read(cx);
 2484
 2485        let file = buffer.file().cloned();
 2486
 2487        let Some(file) = File::from_dyn(file.as_ref()) else {
 2488            return;
 2489        };
 2490        if !file.is_local() {
 2491            return;
 2492        }
 2493        let path = ProjectPath::from_file(file, cx);
 2494        let worktree_id = file.worktree_id(cx);
 2495        let language = buffer.language().cloned();
 2496
 2497        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2498            for (server_id, diagnostics) in
 2499                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2500            {
 2501                self.update_buffer_diagnostics(
 2502                    buffer_handle,
 2503                    server_id,
 2504                    None,
 2505                    None,
 2506                    None,
 2507                    Vec::new(),
 2508                    diagnostics,
 2509                    cx,
 2510                )
 2511                .log_err();
 2512            }
 2513        }
 2514        let Some(language) = language else {
 2515            return;
 2516        };
 2517        let Some(snapshot) = self
 2518            .worktree_store
 2519            .read(cx)
 2520            .worktree_for_id(worktree_id, cx)
 2521            .map(|worktree| worktree.read(cx).snapshot())
 2522        else {
 2523            return;
 2524        };
 2525        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2526
 2527        for server_id in
 2528            self.lsp_tree
 2529                .get(path, language.name(), language.manifest(), &delegate, cx)
 2530        {
 2531            let server = self
 2532                .language_servers
 2533                .get(&server_id)
 2534                .and_then(|server_state| {
 2535                    if let LanguageServerState::Running { server, .. } = server_state {
 2536                        Some(server.clone())
 2537                    } else {
 2538                        None
 2539                    }
 2540                });
 2541            let server = match server {
 2542                Some(server) => server,
 2543                None => continue,
 2544            };
 2545
 2546            buffer_handle.update(cx, |buffer, cx| {
 2547                buffer.set_completion_triggers(
 2548                    server.server_id(),
 2549                    server
 2550                        .capabilities()
 2551                        .completion_provider
 2552                        .as_ref()
 2553                        .and_then(|provider| {
 2554                            provider
 2555                                .trigger_characters
 2556                                .as_ref()
 2557                                .map(|characters| characters.iter().cloned().collect())
 2558                        })
 2559                        .unwrap_or_default(),
 2560                    cx,
 2561                );
 2562            });
 2563        }
 2564    }
 2565
 2566    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2567        buffer.update(cx, |buffer, cx| {
 2568            let Some(language) = buffer.language() else {
 2569                return;
 2570            };
 2571            let path = ProjectPath {
 2572                worktree_id: old_file.worktree_id(cx),
 2573                path: old_file.path.clone(),
 2574            };
 2575            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2576                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2577                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2578            }
 2579        });
 2580    }
 2581
 2582    fn update_buffer_diagnostics(
 2583        &mut self,
 2584        buffer: &Entity<Buffer>,
 2585        server_id: LanguageServerId,
 2586        registration_id: Option<Option<SharedString>>,
 2587        result_id: Option<SharedString>,
 2588        version: Option<i32>,
 2589        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2590        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2591        cx: &mut Context<LspStore>,
 2592    ) -> Result<()> {
 2593        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2594            Ordering::Equal
 2595                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2596                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2597                .then_with(|| a.severity.cmp(&b.severity))
 2598                .then_with(|| a.message.cmp(&b.message))
 2599        }
 2600
 2601        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2602        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2603        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2604
 2605        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2606            Ordering::Equal
 2607                .then_with(|| a.range.start.cmp(&b.range.start))
 2608                .then_with(|| b.range.end.cmp(&a.range.end))
 2609                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2610        });
 2611
 2612        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2613
 2614        let edits_since_save = std::cell::LazyCell::new(|| {
 2615            let saved_version = buffer.read(cx).saved_version();
 2616            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2617        });
 2618
 2619        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2620
 2621        for (new_diagnostic, entry) in diagnostics {
 2622            let start;
 2623            let end;
 2624            if new_diagnostic && entry.diagnostic.is_disk_based {
 2625                // Some diagnostics are based on files on disk instead of buffers'
 2626                // current contents. Adjust these diagnostics' ranges to reflect
 2627                // any unsaved edits.
 2628                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2629                // and were properly adjusted on reuse.
 2630                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2631                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2632            } else {
 2633                start = entry.range.start;
 2634                end = entry.range.end;
 2635            }
 2636
 2637            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2638                ..snapshot.clip_point_utf16(end, Bias::Right);
 2639
 2640            // Expand empty ranges by one codepoint
 2641            if range.start == range.end {
 2642                // This will be go to the next boundary when being clipped
 2643                range.end.column += 1;
 2644                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2645                if range.start == range.end && range.end.column > 0 {
 2646                    range.start.column -= 1;
 2647                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2648                }
 2649            }
 2650
 2651            sanitized_diagnostics.push(DiagnosticEntry {
 2652                range,
 2653                diagnostic: entry.diagnostic,
 2654            });
 2655        }
 2656        drop(edits_since_save);
 2657
 2658        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2659        buffer.update(cx, |buffer, cx| {
 2660            if let Some(registration_id) = registration_id {
 2661                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2662                    self.buffer_pull_diagnostics_result_ids
 2663                        .entry(server_id)
 2664                        .or_default()
 2665                        .entry(registration_id)
 2666                        .or_default()
 2667                        .insert(abs_path, result_id);
 2668                }
 2669            }
 2670
 2671            buffer.update_diagnostics(server_id, set, cx)
 2672        });
 2673
 2674        Ok(())
 2675    }
 2676
 2677    fn register_language_server_for_invisible_worktree(
 2678        &mut self,
 2679        worktree: &Entity<Worktree>,
 2680        language_server_id: LanguageServerId,
 2681        cx: &mut App,
 2682    ) {
 2683        let worktree = worktree.read(cx);
 2684        let worktree_id = worktree.id();
 2685        debug_assert!(!worktree.is_visible());
 2686        let Some(mut origin_seed) = self
 2687            .language_server_ids
 2688            .iter()
 2689            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2690        else {
 2691            return;
 2692        };
 2693        origin_seed.worktree_id = worktree_id;
 2694        self.language_server_ids
 2695            .entry(origin_seed)
 2696            .or_insert_with(|| UnifiedLanguageServer {
 2697                id: language_server_id,
 2698                project_roots: Default::default(),
 2699            });
 2700    }
 2701
 2702    fn register_buffer_with_language_servers(
 2703        &mut self,
 2704        buffer_handle: &Entity<Buffer>,
 2705        only_register_servers: HashSet<LanguageServerSelector>,
 2706        cx: &mut Context<LspStore>,
 2707    ) {
 2708        let buffer = buffer_handle.read(cx);
 2709        let buffer_id = buffer.remote_id();
 2710
 2711        let Some(file) = File::from_dyn(buffer.file()) else {
 2712            return;
 2713        };
 2714        if !file.is_local() {
 2715            return;
 2716        }
 2717
 2718        let abs_path = file.abs_path(cx);
 2719        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2720            return;
 2721        };
 2722        let initial_snapshot = buffer.text_snapshot();
 2723        let worktree_id = file.worktree_id(cx);
 2724
 2725        let Some(language) = buffer.language().cloned() else {
 2726            return;
 2727        };
 2728        let path: Arc<RelPath> = file
 2729            .path()
 2730            .parent()
 2731            .map(Arc::from)
 2732            .unwrap_or_else(|| file.path().clone());
 2733        let Some(worktree) = self
 2734            .worktree_store
 2735            .read(cx)
 2736            .worktree_for_id(worktree_id, cx)
 2737        else {
 2738            return;
 2739        };
 2740        let language_name = language.name();
 2741        let (reused, delegate, servers) = self
 2742            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2743            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2744            .unwrap_or_else(|| {
 2745                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2746                let delegate: Arc<dyn ManifestDelegate> =
 2747                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2748
 2749                let servers = self
 2750                    .lsp_tree
 2751                    .walk(
 2752                        ProjectPath { worktree_id, path },
 2753                        language.name(),
 2754                        language.manifest(),
 2755                        &delegate,
 2756                        cx,
 2757                    )
 2758                    .collect::<Vec<_>>();
 2759                (false, lsp_delegate, servers)
 2760            });
 2761        let servers_and_adapters = servers
 2762            .into_iter()
 2763            .filter_map(|server_node| {
 2764                if reused && server_node.server_id().is_none() {
 2765                    return None;
 2766                }
 2767                if !only_register_servers.is_empty() {
 2768                    if let Some(server_id) = server_node.server_id()
 2769                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2770                    {
 2771                        return None;
 2772                    }
 2773                    if let Some(name) = server_node.name()
 2774                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2775                    {
 2776                        return None;
 2777                    }
 2778                }
 2779
 2780                let server_id = server_node.server_id_or_init(|disposition| {
 2781                    let path = &disposition.path;
 2782
 2783                    {
 2784                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2785
 2786                        let server_id = self.get_or_insert_language_server(
 2787                            &worktree,
 2788                            delegate.clone(),
 2789                            disposition,
 2790                            &language_name,
 2791                            cx,
 2792                        );
 2793
 2794                        if let Some(state) = self.language_servers.get(&server_id)
 2795                            && let Ok(uri) = uri
 2796                        {
 2797                            state.add_workspace_folder(uri);
 2798                        };
 2799                        server_id
 2800                    }
 2801                })?;
 2802                let server_state = self.language_servers.get(&server_id)?;
 2803                if let LanguageServerState::Running {
 2804                    server, adapter, ..
 2805                } = server_state
 2806                {
 2807                    Some((server.clone(), adapter.clone()))
 2808                } else {
 2809                    None
 2810                }
 2811            })
 2812            .collect::<Vec<_>>();
 2813        for (server, adapter) in servers_and_adapters {
 2814            buffer_handle.update(cx, |buffer, cx| {
 2815                buffer.set_completion_triggers(
 2816                    server.server_id(),
 2817                    server
 2818                        .capabilities()
 2819                        .completion_provider
 2820                        .as_ref()
 2821                        .and_then(|provider| {
 2822                            provider
 2823                                .trigger_characters
 2824                                .as_ref()
 2825                                .map(|characters| characters.iter().cloned().collect())
 2826                        })
 2827                        .unwrap_or_default(),
 2828                    cx,
 2829                );
 2830            });
 2831
 2832            let snapshot = LspBufferSnapshot {
 2833                version: 0,
 2834                snapshot: initial_snapshot.clone(),
 2835            };
 2836
 2837            let mut registered = false;
 2838            self.buffer_snapshots
 2839                .entry(buffer_id)
 2840                .or_default()
 2841                .entry(server.server_id())
 2842                .or_insert_with(|| {
 2843                    registered = true;
 2844                    server.register_buffer(
 2845                        uri.clone(),
 2846                        adapter.language_id(&language.name()),
 2847                        0,
 2848                        initial_snapshot.text(),
 2849                    );
 2850
 2851                    vec![snapshot]
 2852                });
 2853
 2854            self.buffers_opened_in_servers
 2855                .entry(buffer_id)
 2856                .or_default()
 2857                .insert(server.server_id());
 2858            if registered {
 2859                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2860                    language_server_id: server.server_id(),
 2861                    name: None,
 2862                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2863                        proto::RegisteredForBuffer {
 2864                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2865                            buffer_id: buffer_id.to_proto(),
 2866                        },
 2867                    ),
 2868                });
 2869            }
 2870        }
 2871    }
 2872
 2873    fn reuse_existing_language_server<'lang_name>(
 2874        &self,
 2875        server_tree: &LanguageServerTree,
 2876        worktree: &Entity<Worktree>,
 2877        language_name: &'lang_name LanguageName,
 2878        cx: &mut App,
 2879    ) -> Option<(
 2880        Arc<LocalLspAdapterDelegate>,
 2881        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2882    )> {
 2883        if worktree.read(cx).is_visible() {
 2884            return None;
 2885        }
 2886
 2887        let worktree_store = self.worktree_store.read(cx);
 2888        let servers = server_tree
 2889            .instances
 2890            .iter()
 2891            .filter(|(worktree_id, _)| {
 2892                worktree_store
 2893                    .worktree_for_id(**worktree_id, cx)
 2894                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2895            })
 2896            .flat_map(|(worktree_id, servers)| {
 2897                servers
 2898                    .roots
 2899                    .iter()
 2900                    .flat_map(|(_, language_servers)| language_servers)
 2901                    .map(move |(_, (server_node, server_languages))| {
 2902                        (worktree_id, server_node, server_languages)
 2903                    })
 2904                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2905                    .map(|(worktree_id, server_node, _)| {
 2906                        (
 2907                            *worktree_id,
 2908                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2909                        )
 2910                    })
 2911            })
 2912            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2913                acc.entry(worktree_id)
 2914                    .or_insert_with(Vec::new)
 2915                    .push(server_node);
 2916                acc
 2917            })
 2918            .into_values()
 2919            .max_by_key(|servers| servers.len())?;
 2920
 2921        let worktree_id = worktree.read(cx).id();
 2922        let apply = move |tree: &mut LanguageServerTree| {
 2923            for server_node in &servers {
 2924                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2925            }
 2926            servers
 2927        };
 2928
 2929        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2930        Some((delegate, apply))
 2931    }
 2932
 2933    pub(crate) fn unregister_old_buffer_from_language_servers(
 2934        &mut self,
 2935        buffer: &Entity<Buffer>,
 2936        old_file: &File,
 2937        cx: &mut App,
 2938    ) {
 2939        let old_path = match old_file.as_local() {
 2940            Some(local) => local.abs_path(cx),
 2941            None => return,
 2942        };
 2943
 2944        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2945            debug_panic!("{old_path:?} is not parseable as an URI");
 2946            return;
 2947        };
 2948        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2949    }
 2950
 2951    pub(crate) fn unregister_buffer_from_language_servers(
 2952        &mut self,
 2953        buffer: &Entity<Buffer>,
 2954        file_url: &lsp::Uri,
 2955        cx: &mut App,
 2956    ) {
 2957        buffer.update(cx, |buffer, cx| {
 2958            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2959
 2960            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2961                if snapshots
 2962                    .as_mut()
 2963                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2964                {
 2965                    language_server.unregister_buffer(file_url.clone());
 2966                }
 2967            }
 2968        });
 2969    }
 2970
 2971    fn buffer_snapshot_for_lsp_version(
 2972        &mut self,
 2973        buffer: &Entity<Buffer>,
 2974        server_id: LanguageServerId,
 2975        version: Option<i32>,
 2976        cx: &App,
 2977    ) -> Result<TextBufferSnapshot> {
 2978        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2979
 2980        if let Some(version) = version {
 2981            let buffer_id = buffer.read(cx).remote_id();
 2982            let snapshots = if let Some(snapshots) = self
 2983                .buffer_snapshots
 2984                .get_mut(&buffer_id)
 2985                .and_then(|m| m.get_mut(&server_id))
 2986            {
 2987                snapshots
 2988            } else if version == 0 {
 2989                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2990                // We detect this case and treat it as if the version was `None`.
 2991                return Ok(buffer.read(cx).text_snapshot());
 2992            } else {
 2993                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2994            };
 2995
 2996            let found_snapshot = snapshots
 2997                    .binary_search_by_key(&version, |e| e.version)
 2998                    .map(|ix| snapshots[ix].snapshot.clone())
 2999                    .map_err(|_| {
 3000                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3001                    })?;
 3002
 3003            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3004            Ok(found_snapshot)
 3005        } else {
 3006            Ok((buffer.read(cx)).text_snapshot())
 3007        }
 3008    }
 3009
 3010    async fn get_server_code_actions_from_action_kinds(
 3011        lsp_store: &WeakEntity<LspStore>,
 3012        language_server_id: LanguageServerId,
 3013        code_action_kinds: Vec<lsp::CodeActionKind>,
 3014        buffer: &Entity<Buffer>,
 3015        cx: &mut AsyncApp,
 3016    ) -> Result<Vec<CodeAction>> {
 3017        let actions = lsp_store
 3018            .update(cx, move |this, cx| {
 3019                let request = GetCodeActions {
 3020                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3021                    kinds: Some(code_action_kinds),
 3022                };
 3023                let server = LanguageServerToQuery::Other(language_server_id);
 3024                this.request_lsp(buffer.clone(), server, request, cx)
 3025            })?
 3026            .await?;
 3027        Ok(actions)
 3028    }
 3029
 3030    pub async fn execute_code_actions_on_server(
 3031        lsp_store: &WeakEntity<LspStore>,
 3032        language_server: &Arc<LanguageServer>,
 3033        actions: Vec<CodeAction>,
 3034        push_to_history: bool,
 3035        project_transaction: &mut ProjectTransaction,
 3036        cx: &mut AsyncApp,
 3037    ) -> anyhow::Result<()> {
 3038        let request_timeout = cx.update(|app| {
 3039            ProjectSettings::get_global(app)
 3040                .global_lsp_settings
 3041                .get_request_timeout()
 3042        });
 3043
 3044        for mut action in actions {
 3045            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3046                .await
 3047                .context("resolving a formatting code action")?;
 3048
 3049            if let Some(edit) = action.lsp_action.edit() {
 3050                if edit.changes.is_none() && edit.document_changes.is_none() {
 3051                    continue;
 3052                }
 3053
 3054                let new = Self::deserialize_workspace_edit(
 3055                    lsp_store.upgrade().context("project dropped")?,
 3056                    edit.clone(),
 3057                    push_to_history,
 3058                    language_server.clone(),
 3059                    cx,
 3060                )
 3061                .await?;
 3062                project_transaction.0.extend(new.0);
 3063            }
 3064
 3065            let Some(command) = action.lsp_action.command() else {
 3066                continue;
 3067            };
 3068
 3069            let server_capabilities = language_server.capabilities();
 3070            let available_commands = server_capabilities
 3071                .execute_command_provider
 3072                .as_ref()
 3073                .map(|options| options.commands.as_slice())
 3074                .unwrap_or_default();
 3075            if !available_commands.contains(&command.command) {
 3076                log::warn!(
 3077                    "Cannot execute a command {} not listed in the language server capabilities",
 3078                    command.command
 3079                );
 3080                continue;
 3081            }
 3082
 3083            lsp_store.update(cx, |lsp_store, _| {
 3084                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3085                    mode.last_workspace_edits_by_language_server
 3086                        .remove(&language_server.server_id());
 3087                }
 3088            })?;
 3089
 3090            language_server
 3091                .request::<lsp::request::ExecuteCommand>(
 3092                    lsp::ExecuteCommandParams {
 3093                        command: command.command.clone(),
 3094                        arguments: command.arguments.clone().unwrap_or_default(),
 3095                        ..Default::default()
 3096                    },
 3097                    request_timeout,
 3098                )
 3099                .await
 3100                .into_response()
 3101                .context("execute command")?;
 3102
 3103            lsp_store.update(cx, |this, _| {
 3104                if let LspStoreMode::Local(mode) = &mut this.mode {
 3105                    project_transaction.0.extend(
 3106                        mode.last_workspace_edits_by_language_server
 3107                            .remove(&language_server.server_id())
 3108                            .unwrap_or_default()
 3109                            .0,
 3110                    )
 3111                }
 3112            })?;
 3113        }
 3114        Ok(())
 3115    }
 3116
 3117    pub async fn deserialize_text_edits(
 3118        this: Entity<LspStore>,
 3119        buffer_to_edit: Entity<Buffer>,
 3120        edits: Vec<lsp::TextEdit>,
 3121        push_to_history: bool,
 3122        _: Arc<CachedLspAdapter>,
 3123        language_server: Arc<LanguageServer>,
 3124        cx: &mut AsyncApp,
 3125    ) -> Result<Option<Transaction>> {
 3126        let edits = this
 3127            .update(cx, |this, cx| {
 3128                this.as_local_mut().unwrap().edits_from_lsp(
 3129                    &buffer_to_edit,
 3130                    edits,
 3131                    language_server.server_id(),
 3132                    None,
 3133                    cx,
 3134                )
 3135            })
 3136            .await?;
 3137
 3138        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3139            buffer.finalize_last_transaction();
 3140            buffer.start_transaction();
 3141            for (range, text) in edits {
 3142                buffer.edit([(range, text)], None, cx);
 3143            }
 3144
 3145            if buffer.end_transaction(cx).is_some() {
 3146                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3147                if !push_to_history {
 3148                    buffer.forget_transaction(transaction.id);
 3149                }
 3150                Some(transaction)
 3151            } else {
 3152                None
 3153            }
 3154        });
 3155
 3156        Ok(transaction)
 3157    }
 3158
 3159    #[allow(clippy::type_complexity)]
 3160    pub fn edits_from_lsp(
 3161        &mut self,
 3162        buffer: &Entity<Buffer>,
 3163        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3164        server_id: LanguageServerId,
 3165        version: Option<i32>,
 3166        cx: &mut Context<LspStore>,
 3167    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3168        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3169        cx.background_spawn(async move {
 3170            let snapshot = snapshot?;
 3171            let mut lsp_edits = lsp_edits
 3172                .into_iter()
 3173                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3174                .collect::<Vec<_>>();
 3175
 3176            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3177
 3178            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3179            let mut edits = Vec::new();
 3180            while let Some((range, mut new_text)) = lsp_edits.next() {
 3181                // Clip invalid ranges provided by the language server.
 3182                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3183                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3184
 3185                // Combine any LSP edits that are adjacent.
 3186                //
 3187                // Also, combine LSP edits that are separated from each other by only
 3188                // a newline. This is important because for some code actions,
 3189                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3190                // are separated by unchanged newline characters.
 3191                //
 3192                // In order for the diffing logic below to work properly, any edits that
 3193                // cancel each other out must be combined into one.
 3194                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3195                    if next_range.start.0 > range.end {
 3196                        if next_range.start.0.row > range.end.row + 1
 3197                            || next_range.start.0.column > 0
 3198                            || snapshot.clip_point_utf16(
 3199                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3200                                Bias::Left,
 3201                            ) > range.end
 3202                        {
 3203                            break;
 3204                        }
 3205                        new_text.push('\n');
 3206                    }
 3207                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3208                    new_text.push_str(next_text);
 3209                    lsp_edits.next();
 3210                }
 3211
 3212                // For multiline edits, perform a diff of the old and new text so that
 3213                // we can identify the changes more precisely, preserving the locations
 3214                // of any anchors positioned in the unchanged regions.
 3215                if range.end.row > range.start.row {
 3216                    let offset = range.start.to_offset(&snapshot);
 3217                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3218                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3219                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3220                        (
 3221                            snapshot.anchor_after(offset + range.start)
 3222                                ..snapshot.anchor_before(offset + range.end),
 3223                            replacement,
 3224                        )
 3225                    }));
 3226                } else if range.end == range.start {
 3227                    let anchor = snapshot.anchor_after(range.start);
 3228                    edits.push((anchor..anchor, new_text.into()));
 3229                } else {
 3230                    let edit_start = snapshot.anchor_after(range.start);
 3231                    let edit_end = snapshot.anchor_before(range.end);
 3232                    edits.push((edit_start..edit_end, new_text.into()));
 3233                }
 3234            }
 3235
 3236            Ok(edits)
 3237        })
 3238    }
 3239
 3240    pub(crate) async fn deserialize_workspace_edit(
 3241        this: Entity<LspStore>,
 3242        edit: lsp::WorkspaceEdit,
 3243        push_to_history: bool,
 3244        language_server: Arc<LanguageServer>,
 3245        cx: &mut AsyncApp,
 3246    ) -> Result<ProjectTransaction> {
 3247        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3248
 3249        let mut operations = Vec::new();
 3250        if let Some(document_changes) = edit.document_changes {
 3251            match document_changes {
 3252                lsp::DocumentChanges::Edits(edits) => {
 3253                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3254                }
 3255                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3256            }
 3257        } else if let Some(changes) = edit.changes {
 3258            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3259                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3260                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3261                        uri,
 3262                        version: None,
 3263                    },
 3264                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3265                })
 3266            }));
 3267        }
 3268
 3269        let mut project_transaction = ProjectTransaction::default();
 3270        for operation in operations {
 3271            match operation {
 3272                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3273                    let abs_path = op
 3274                        .uri
 3275                        .to_file_path()
 3276                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3277
 3278                    if let Some(parent_path) = abs_path.parent() {
 3279                        fs.create_dir(parent_path).await?;
 3280                    }
 3281                    if abs_path.ends_with("/") {
 3282                        fs.create_dir(&abs_path).await?;
 3283                    } else {
 3284                        fs.create_file(
 3285                            &abs_path,
 3286                            op.options
 3287                                .map(|options| fs::CreateOptions {
 3288                                    overwrite: options.overwrite.unwrap_or(false),
 3289                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3290                                })
 3291                                .unwrap_or_default(),
 3292                        )
 3293                        .await?;
 3294                    }
 3295                }
 3296
 3297                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3298                    let source_abs_path = op
 3299                        .old_uri
 3300                        .to_file_path()
 3301                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3302                    let target_abs_path = op
 3303                        .new_uri
 3304                        .to_file_path()
 3305                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3306
 3307                    let options = fs::RenameOptions {
 3308                        overwrite: op
 3309                            .options
 3310                            .as_ref()
 3311                            .and_then(|options| options.overwrite)
 3312                            .unwrap_or(false),
 3313                        ignore_if_exists: op
 3314                            .options
 3315                            .as_ref()
 3316                            .and_then(|options| options.ignore_if_exists)
 3317                            .unwrap_or(false),
 3318                        create_parents: true,
 3319                    };
 3320
 3321                    fs.rename(&source_abs_path, &target_abs_path, options)
 3322                        .await?;
 3323                }
 3324
 3325                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3326                    let abs_path = op
 3327                        .uri
 3328                        .to_file_path()
 3329                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3330                    let options = op
 3331                        .options
 3332                        .map(|options| fs::RemoveOptions {
 3333                            recursive: options.recursive.unwrap_or(false),
 3334                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3335                        })
 3336                        .unwrap_or_default();
 3337                    if abs_path.ends_with("/") {
 3338                        fs.remove_dir(&abs_path, options).await?;
 3339                    } else {
 3340                        fs.remove_file(&abs_path, options).await?;
 3341                    }
 3342                }
 3343
 3344                lsp::DocumentChangeOperation::Edit(op) => {
 3345                    let buffer_to_edit = this
 3346                        .update(cx, |this, cx| {
 3347                            this.open_local_buffer_via_lsp(
 3348                                op.text_document.uri.clone(),
 3349                                language_server.server_id(),
 3350                                cx,
 3351                            )
 3352                        })
 3353                        .await?;
 3354
 3355                    let edits = this
 3356                        .update(cx, |this, cx| {
 3357                            let path = buffer_to_edit.read(cx).project_path(cx);
 3358                            let active_entry = this.active_entry;
 3359                            let is_active_entry = path.is_some_and(|project_path| {
 3360                                this.worktree_store
 3361                                    .read(cx)
 3362                                    .entry_for_path(&project_path, cx)
 3363                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3364                            });
 3365                            let local = this.as_local_mut().unwrap();
 3366
 3367                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3368                            for edit in op.edits {
 3369                                match edit {
 3370                                    Edit::Plain(edit) => {
 3371                                        if !edits.contains(&edit) {
 3372                                            edits.push(edit)
 3373                                        }
 3374                                    }
 3375                                    Edit::Annotated(edit) => {
 3376                                        if !edits.contains(&edit.text_edit) {
 3377                                            edits.push(edit.text_edit)
 3378                                        }
 3379                                    }
 3380                                    Edit::Snippet(edit) => {
 3381                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3382                                        else {
 3383                                            continue;
 3384                                        };
 3385
 3386                                        if is_active_entry {
 3387                                            snippet_edits.push((edit.range, snippet));
 3388                                        } else {
 3389                                            // Since this buffer is not focused, apply a normal edit.
 3390                                            let new_edit = TextEdit {
 3391                                                range: edit.range,
 3392                                                new_text: snippet.text,
 3393                                            };
 3394                                            if !edits.contains(&new_edit) {
 3395                                                edits.push(new_edit);
 3396                                            }
 3397                                        }
 3398                                    }
 3399                                }
 3400                            }
 3401                            if !snippet_edits.is_empty() {
 3402                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3403                                let version = if let Some(buffer_version) = op.text_document.version
 3404                                {
 3405                                    local
 3406                                        .buffer_snapshot_for_lsp_version(
 3407                                            &buffer_to_edit,
 3408                                            language_server.server_id(),
 3409                                            Some(buffer_version),
 3410                                            cx,
 3411                                        )
 3412                                        .ok()
 3413                                        .map(|snapshot| snapshot.version)
 3414                                } else {
 3415                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3416                                };
 3417
 3418                                let most_recent_edit =
 3419                                    version.and_then(|version| version.most_recent());
 3420                                // Check if the edit that triggered that edit has been made by this participant.
 3421
 3422                                if let Some(most_recent_edit) = most_recent_edit {
 3423                                    cx.emit(LspStoreEvent::SnippetEdit {
 3424                                        buffer_id,
 3425                                        edits: snippet_edits,
 3426                                        most_recent_edit,
 3427                                    });
 3428                                }
 3429                            }
 3430
 3431                            local.edits_from_lsp(
 3432                                &buffer_to_edit,
 3433                                edits,
 3434                                language_server.server_id(),
 3435                                op.text_document.version,
 3436                                cx,
 3437                            )
 3438                        })
 3439                        .await?;
 3440
 3441                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3442                        buffer.finalize_last_transaction();
 3443                        buffer.start_transaction();
 3444                        for (range, text) in edits {
 3445                            buffer.edit([(range, text)], None, cx);
 3446                        }
 3447
 3448                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3449                            if push_to_history {
 3450                                buffer.finalize_last_transaction();
 3451                                buffer.get_transaction(transaction_id).cloned()
 3452                            } else {
 3453                                buffer.forget_transaction(transaction_id)
 3454                            }
 3455                        })
 3456                    });
 3457                    if let Some(transaction) = transaction {
 3458                        project_transaction.0.insert(buffer_to_edit, transaction);
 3459                    }
 3460                }
 3461            }
 3462        }
 3463
 3464        Ok(project_transaction)
 3465    }
 3466
 3467    async fn on_lsp_workspace_edit(
 3468        this: WeakEntity<LspStore>,
 3469        params: lsp::ApplyWorkspaceEditParams,
 3470        server_id: LanguageServerId,
 3471        cx: &mut AsyncApp,
 3472    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3473        let this = this.upgrade().context("project project closed")?;
 3474        let language_server = this
 3475            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3476            .context("language server not found")?;
 3477        let transaction = Self::deserialize_workspace_edit(
 3478            this.clone(),
 3479            params.edit,
 3480            true,
 3481            language_server.clone(),
 3482            cx,
 3483        )
 3484        .await
 3485        .log_err();
 3486        this.update(cx, |this, cx| {
 3487            if let Some(transaction) = transaction {
 3488                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3489
 3490                this.as_local_mut()
 3491                    .unwrap()
 3492                    .last_workspace_edits_by_language_server
 3493                    .insert(server_id, transaction);
 3494            }
 3495        });
 3496        Ok(lsp::ApplyWorkspaceEditResponse {
 3497            applied: true,
 3498            failed_change: None,
 3499            failure_reason: None,
 3500        })
 3501    }
 3502
 3503    fn remove_worktree(
 3504        &mut self,
 3505        id_to_remove: WorktreeId,
 3506        cx: &mut Context<LspStore>,
 3507    ) -> Vec<LanguageServerId> {
 3508        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3509        self.diagnostics.remove(&id_to_remove);
 3510        self.prettier_store.update(cx, |prettier_store, cx| {
 3511            prettier_store.remove_worktree(id_to_remove, cx);
 3512        });
 3513
 3514        let mut servers_to_remove = BTreeSet::default();
 3515        let mut servers_to_preserve = HashSet::default();
 3516        for (seed, state) in &self.language_server_ids {
 3517            if seed.worktree_id == id_to_remove {
 3518                servers_to_remove.insert(state.id);
 3519            } else {
 3520                servers_to_preserve.insert(state.id);
 3521            }
 3522        }
 3523        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3524        self.language_server_ids
 3525            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3526        for server_id_to_remove in &servers_to_remove {
 3527            self.language_server_watched_paths
 3528                .remove(server_id_to_remove);
 3529            self.language_server_paths_watched_for_rename
 3530                .remove(server_id_to_remove);
 3531            self.last_workspace_edits_by_language_server
 3532                .remove(server_id_to_remove);
 3533            self.language_servers.remove(server_id_to_remove);
 3534            self.buffer_pull_diagnostics_result_ids
 3535                .remove(server_id_to_remove);
 3536            self.workspace_pull_diagnostics_result_ids
 3537                .remove(server_id_to_remove);
 3538            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3539                buffer_servers.remove(server_id_to_remove);
 3540            }
 3541            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3542        }
 3543        servers_to_remove.into_iter().collect()
 3544    }
 3545
 3546    fn rebuild_watched_paths_inner<'a>(
 3547        &'a self,
 3548        language_server_id: LanguageServerId,
 3549        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3550        cx: &mut Context<LspStore>,
 3551    ) -> LanguageServerWatchedPathsBuilder {
 3552        let worktrees = self
 3553            .worktree_store
 3554            .read(cx)
 3555            .worktrees()
 3556            .filter_map(|worktree| {
 3557                self.language_servers_for_worktree(worktree.read(cx).id())
 3558                    .find(|server| server.server_id() == language_server_id)
 3559                    .map(|_| worktree)
 3560            })
 3561            .collect::<Vec<_>>();
 3562
 3563        let mut worktree_globs = HashMap::default();
 3564        let mut abs_globs = HashMap::default();
 3565        log::trace!(
 3566            "Processing new watcher paths for language server with id {}",
 3567            language_server_id
 3568        );
 3569
 3570        for watcher in watchers {
 3571            if let Some((worktree, literal_prefix, pattern)) =
 3572                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3573            {
 3574                worktree.update(cx, |worktree, _| {
 3575                    if let Some((tree, glob)) =
 3576                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3577                    {
 3578                        tree.add_path_prefix_to_scan(literal_prefix);
 3579                        worktree_globs
 3580                            .entry(tree.id())
 3581                            .or_insert_with(GlobSetBuilder::new)
 3582                            .add(glob);
 3583                    }
 3584                });
 3585            } else {
 3586                let (path, pattern) = match &watcher.glob_pattern {
 3587                    lsp::GlobPattern::String(s) => {
 3588                        let watcher_path = SanitizedPath::new(s);
 3589                        let path = glob_literal_prefix(watcher_path.as_path());
 3590                        let pattern = watcher_path
 3591                            .as_path()
 3592                            .strip_prefix(&path)
 3593                            .map(|p| p.to_string_lossy().into_owned())
 3594                            .unwrap_or_else(|e| {
 3595                                debug_panic!(
 3596                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3597                                    s,
 3598                                    path.display(),
 3599                                    e
 3600                                );
 3601                                watcher_path.as_path().to_string_lossy().into_owned()
 3602                            });
 3603                        (path, pattern)
 3604                    }
 3605                    lsp::GlobPattern::Relative(rp) => {
 3606                        let Ok(mut base_uri) = match &rp.base_uri {
 3607                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3608                            lsp::OneOf::Right(base_uri) => base_uri,
 3609                        }
 3610                        .to_file_path() else {
 3611                            continue;
 3612                        };
 3613
 3614                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3615                        let pattern = Path::new(&rp.pattern)
 3616                            .strip_prefix(&path)
 3617                            .map(|p| p.to_string_lossy().into_owned())
 3618                            .unwrap_or_else(|e| {
 3619                                debug_panic!(
 3620                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3621                                    rp.pattern,
 3622                                    path.display(),
 3623                                    e
 3624                                );
 3625                                rp.pattern.clone()
 3626                            });
 3627                        base_uri.push(path);
 3628                        (base_uri, pattern)
 3629                    }
 3630                };
 3631
 3632                if let Some(glob) = Glob::new(&pattern).log_err() {
 3633                    if !path
 3634                        .components()
 3635                        .any(|c| matches!(c, path::Component::Normal(_)))
 3636                    {
 3637                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3638                        // rather than adding a new watcher for `/`.
 3639                        for worktree in &worktrees {
 3640                            worktree_globs
 3641                                .entry(worktree.read(cx).id())
 3642                                .or_insert_with(GlobSetBuilder::new)
 3643                                .add(glob.clone());
 3644                        }
 3645                    } else {
 3646                        abs_globs
 3647                            .entry(path.into())
 3648                            .or_insert_with(GlobSetBuilder::new)
 3649                            .add(glob);
 3650                    }
 3651                }
 3652            }
 3653        }
 3654
 3655        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3656        for (worktree_id, builder) in worktree_globs {
 3657            if let Ok(globset) = builder.build() {
 3658                watch_builder.watch_worktree(worktree_id, globset);
 3659            }
 3660        }
 3661        for (abs_path, builder) in abs_globs {
 3662            if let Ok(globset) = builder.build() {
 3663                watch_builder.watch_abs_path(abs_path, globset);
 3664            }
 3665        }
 3666        watch_builder
 3667    }
 3668
 3669    fn worktree_and_path_for_file_watcher(
 3670        worktrees: &[Entity<Worktree>],
 3671        watcher: &FileSystemWatcher,
 3672        cx: &App,
 3673    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3674        worktrees.iter().find_map(|worktree| {
 3675            let tree = worktree.read(cx);
 3676            let worktree_root_path = tree.abs_path();
 3677            let path_style = tree.path_style();
 3678            match &watcher.glob_pattern {
 3679                lsp::GlobPattern::String(s) => {
 3680                    let watcher_path = SanitizedPath::new(s);
 3681                    let relative = watcher_path
 3682                        .as_path()
 3683                        .strip_prefix(&worktree_root_path)
 3684                        .ok()?;
 3685                    let literal_prefix = glob_literal_prefix(relative);
 3686                    Some((
 3687                        worktree.clone(),
 3688                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3689                        relative.to_string_lossy().into_owned(),
 3690                    ))
 3691                }
 3692                lsp::GlobPattern::Relative(rp) => {
 3693                    let base_uri = match &rp.base_uri {
 3694                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3695                        lsp::OneOf::Right(base_uri) => base_uri,
 3696                    }
 3697                    .to_file_path()
 3698                    .ok()?;
 3699                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3700                    let mut literal_prefix = relative.to_owned();
 3701                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3702                    Some((
 3703                        worktree.clone(),
 3704                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3705                        rp.pattern.clone(),
 3706                    ))
 3707                }
 3708            }
 3709        })
 3710    }
 3711
 3712    fn rebuild_watched_paths(
 3713        &mut self,
 3714        language_server_id: LanguageServerId,
 3715        cx: &mut Context<LspStore>,
 3716    ) {
 3717        let Some(registrations) = self
 3718            .language_server_dynamic_registrations
 3719            .get(&language_server_id)
 3720        else {
 3721            return;
 3722        };
 3723
 3724        let watch_builder = self.rebuild_watched_paths_inner(
 3725            language_server_id,
 3726            registrations.did_change_watched_files.values().flatten(),
 3727            cx,
 3728        );
 3729        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3730        self.language_server_watched_paths
 3731            .insert(language_server_id, watcher);
 3732
 3733        cx.notify();
 3734    }
 3735
 3736    fn on_lsp_did_change_watched_files(
 3737        &mut self,
 3738        language_server_id: LanguageServerId,
 3739        registration_id: &str,
 3740        params: DidChangeWatchedFilesRegistrationOptions,
 3741        cx: &mut Context<LspStore>,
 3742    ) {
 3743        let registrations = self
 3744            .language_server_dynamic_registrations
 3745            .entry(language_server_id)
 3746            .or_default();
 3747
 3748        registrations
 3749            .did_change_watched_files
 3750            .insert(registration_id.to_string(), params.watchers);
 3751
 3752        self.rebuild_watched_paths(language_server_id, cx);
 3753    }
 3754
 3755    fn on_lsp_unregister_did_change_watched_files(
 3756        &mut self,
 3757        language_server_id: LanguageServerId,
 3758        registration_id: &str,
 3759        cx: &mut Context<LspStore>,
 3760    ) {
 3761        let registrations = self
 3762            .language_server_dynamic_registrations
 3763            .entry(language_server_id)
 3764            .or_default();
 3765
 3766        if registrations
 3767            .did_change_watched_files
 3768            .remove(registration_id)
 3769            .is_some()
 3770        {
 3771            log::info!(
 3772                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3773                language_server_id,
 3774                registration_id
 3775            );
 3776        } else {
 3777            log::warn!(
 3778                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3779                language_server_id,
 3780                registration_id
 3781            );
 3782        }
 3783
 3784        self.rebuild_watched_paths(language_server_id, cx);
 3785    }
 3786
 3787    async fn initialization_options_for_adapter(
 3788        adapter: Arc<dyn LspAdapter>,
 3789        delegate: &Arc<dyn LspAdapterDelegate>,
 3790        cx: &mut AsyncApp,
 3791    ) -> Result<Option<serde_json::Value>> {
 3792        let Some(mut initialization_config) =
 3793            adapter.clone().initialization_options(delegate, cx).await?
 3794        else {
 3795            return Ok(None);
 3796        };
 3797
 3798        for other_adapter in delegate.registered_lsp_adapters() {
 3799            if other_adapter.name() == adapter.name() {
 3800                continue;
 3801            }
 3802            if let Ok(Some(target_config)) = other_adapter
 3803                .clone()
 3804                .additional_initialization_options(adapter.name(), delegate)
 3805                .await
 3806            {
 3807                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3808            }
 3809        }
 3810
 3811        Ok(Some(initialization_config))
 3812    }
 3813
 3814    async fn workspace_configuration_for_adapter(
 3815        adapter: Arc<dyn LspAdapter>,
 3816        delegate: &Arc<dyn LspAdapterDelegate>,
 3817        toolchain: Option<Toolchain>,
 3818        requested_uri: Option<Uri>,
 3819        cx: &mut AsyncApp,
 3820    ) -> Result<serde_json::Value> {
 3821        let mut workspace_config = adapter
 3822            .clone()
 3823            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3824            .await?;
 3825
 3826        for other_adapter in delegate.registered_lsp_adapters() {
 3827            if other_adapter.name() == adapter.name() {
 3828                continue;
 3829            }
 3830            if let Ok(Some(target_config)) = other_adapter
 3831                .clone()
 3832                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3833                .await
 3834            {
 3835                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3836            }
 3837        }
 3838
 3839        Ok(workspace_config)
 3840    }
 3841
 3842    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3843        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3844            Some(server.clone())
 3845        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3846            Some(Arc::clone(server))
 3847        } else {
 3848            None
 3849        }
 3850    }
 3851}
 3852
 3853fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3854    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3855        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3856            language_server_id: server.server_id(),
 3857            name: Some(server.name()),
 3858            message: proto::update_language_server::Variant::MetadataUpdated(
 3859                proto::ServerMetadataUpdated {
 3860                    capabilities: Some(capabilities),
 3861                    binary: Some(proto::LanguageServerBinaryInfo {
 3862                        path: server.binary().path.to_string_lossy().into_owned(),
 3863                        arguments: server
 3864                            .binary()
 3865                            .arguments
 3866                            .iter()
 3867                            .map(|arg| arg.to_string_lossy().into_owned())
 3868                            .collect(),
 3869                    }),
 3870                    configuration: serde_json::to_string(server.configuration()).ok(),
 3871                    workspace_folders: server
 3872                        .workspace_folders()
 3873                        .iter()
 3874                        .map(|uri| uri.to_string())
 3875                        .collect(),
 3876                },
 3877            ),
 3878        });
 3879    }
 3880}
 3881
 3882#[derive(Debug)]
 3883pub struct FormattableBuffer {
 3884    handle: Entity<Buffer>,
 3885    abs_path: Option<PathBuf>,
 3886    env: Option<HashMap<String, String>>,
 3887    ranges: Option<Vec<Range<Anchor>>>,
 3888}
 3889
 3890pub struct RemoteLspStore {
 3891    upstream_client: Option<AnyProtoClient>,
 3892    upstream_project_id: u64,
 3893}
 3894
 3895pub(crate) enum LspStoreMode {
 3896    Local(LocalLspStore),   // ssh host and collab host
 3897    Remote(RemoteLspStore), // collab guest
 3898}
 3899
 3900impl LspStoreMode {
 3901    fn is_local(&self) -> bool {
 3902        matches!(self, LspStoreMode::Local(_))
 3903    }
 3904}
 3905
 3906pub struct LspStore {
 3907    mode: LspStoreMode,
 3908    last_formatting_failure: Option<String>,
 3909    downstream_client: Option<(AnyProtoClient, u64)>,
 3910    nonce: u128,
 3911    buffer_store: Entity<BufferStore>,
 3912    worktree_store: Entity<WorktreeStore>,
 3913    pub languages: Arc<LanguageRegistry>,
 3914    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3915    active_entry: Option<ProjectEntryId>,
 3916    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3917    _maintain_buffer_languages: Task<()>,
 3918    diagnostic_summaries:
 3919        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3920    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3921    semantic_token_config: SemanticTokenConfig,
 3922    lsp_data: HashMap<BufferId, BufferLspData>,
 3923    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3924    next_hint_id: Arc<AtomicUsize>,
 3925}
 3926
 3927#[derive(Debug)]
 3928pub struct BufferLspData {
 3929    buffer_version: Global,
 3930    document_colors: Option<DocumentColorData>,
 3931    code_lens: Option<CodeLensData>,
 3932    semantic_tokens: Option<SemanticTokensData>,
 3933    folding_ranges: Option<FoldingRangeData>,
 3934    document_symbols: Option<DocumentSymbolsData>,
 3935    inlay_hints: BufferInlayHints,
 3936    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3937    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3938}
 3939
 3940#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3941struct LspKey {
 3942    request_type: TypeId,
 3943    server_queried: Option<LanguageServerId>,
 3944}
 3945
 3946impl BufferLspData {
 3947    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3948        Self {
 3949            buffer_version: buffer.read(cx).version(),
 3950            document_colors: None,
 3951            code_lens: None,
 3952            semantic_tokens: None,
 3953            folding_ranges: None,
 3954            document_symbols: None,
 3955            inlay_hints: BufferInlayHints::new(buffer, cx),
 3956            lsp_requests: HashMap::default(),
 3957            chunk_lsp_requests: HashMap::default(),
 3958        }
 3959    }
 3960
 3961    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3962        if let Some(document_colors) = &mut self.document_colors {
 3963            document_colors.remove_server_data(for_server);
 3964        }
 3965
 3966        if let Some(code_lens) = &mut self.code_lens {
 3967            code_lens.remove_server_data(for_server);
 3968        }
 3969
 3970        self.inlay_hints.remove_server_data(for_server);
 3971
 3972        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3973            semantic_tokens.remove_server_data(for_server);
 3974        }
 3975
 3976        if let Some(folding_ranges) = &mut self.folding_ranges {
 3977            folding_ranges.ranges.remove(&for_server);
 3978        }
 3979
 3980        if let Some(document_symbols) = &mut self.document_symbols {
 3981            document_symbols.remove_server_data(for_server);
 3982        }
 3983    }
 3984
 3985    #[cfg(any(test, feature = "test-support"))]
 3986    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3987        &self.inlay_hints
 3988    }
 3989}
 3990
 3991#[derive(Debug)]
 3992pub enum LspStoreEvent {
 3993    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3994    LanguageServerRemoved(LanguageServerId),
 3995    LanguageServerUpdate {
 3996        language_server_id: LanguageServerId,
 3997        name: Option<LanguageServerName>,
 3998        message: proto::update_language_server::Variant,
 3999    },
 4000    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4001    LanguageServerPrompt(LanguageServerPromptRequest),
 4002    LanguageDetected {
 4003        buffer: Entity<Buffer>,
 4004        new_language: Option<Arc<Language>>,
 4005    },
 4006    Notification(String),
 4007    RefreshInlayHints {
 4008        server_id: LanguageServerId,
 4009        request_id: Option<usize>,
 4010    },
 4011    RefreshSemanticTokens {
 4012        server_id: LanguageServerId,
 4013        request_id: Option<usize>,
 4014    },
 4015    RefreshCodeLens,
 4016    DiagnosticsUpdated {
 4017        server_id: LanguageServerId,
 4018        paths: Vec<ProjectPath>,
 4019    },
 4020    DiskBasedDiagnosticsStarted {
 4021        language_server_id: LanguageServerId,
 4022    },
 4023    DiskBasedDiagnosticsFinished {
 4024        language_server_id: LanguageServerId,
 4025    },
 4026    SnippetEdit {
 4027        buffer_id: BufferId,
 4028        edits: Vec<(lsp::Range, Snippet)>,
 4029        most_recent_edit: clock::Lamport,
 4030    },
 4031    WorkspaceEditApplied(ProjectTransaction),
 4032}
 4033
 4034#[derive(Clone, Debug, Serialize)]
 4035pub struct LanguageServerStatus {
 4036    pub name: LanguageServerName,
 4037    pub server_version: Option<SharedString>,
 4038    pub server_readable_version: Option<SharedString>,
 4039    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4040    pub has_pending_diagnostic_updates: bool,
 4041    pub progress_tokens: HashSet<ProgressToken>,
 4042    pub worktree: Option<WorktreeId>,
 4043    pub binary: Option<LanguageServerBinary>,
 4044    pub configuration: Option<Value>,
 4045    pub workspace_folders: BTreeSet<Uri>,
 4046    pub process_id: Option<u32>,
 4047}
 4048
 4049#[derive(Clone, Debug)]
 4050struct CoreSymbol {
 4051    pub language_server_name: LanguageServerName,
 4052    pub source_worktree_id: WorktreeId,
 4053    pub source_language_server_id: LanguageServerId,
 4054    pub path: SymbolLocation,
 4055    pub name: String,
 4056    pub kind: lsp::SymbolKind,
 4057    pub range: Range<Unclipped<PointUtf16>>,
 4058    pub container_name: Option<String>,
 4059}
 4060
 4061#[derive(Clone, Debug, PartialEq, Eq)]
 4062pub enum SymbolLocation {
 4063    InProject(ProjectPath),
 4064    OutsideProject {
 4065        abs_path: Arc<Path>,
 4066        signature: [u8; 32],
 4067    },
 4068}
 4069
 4070impl SymbolLocation {
 4071    fn file_name(&self) -> Option<&str> {
 4072        match self {
 4073            Self::InProject(path) => path.path.file_name(),
 4074            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4075        }
 4076    }
 4077}
 4078
 4079impl LspStore {
 4080    pub fn init(client: &AnyProtoClient) {
 4081        client.add_entity_request_handler(Self::handle_lsp_query);
 4082        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4083        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4084        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4085        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4086        client.add_entity_message_handler(Self::handle_start_language_server);
 4087        client.add_entity_message_handler(Self::handle_update_language_server);
 4088        client.add_entity_message_handler(Self::handle_language_server_log);
 4089        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4090        client.add_entity_request_handler(Self::handle_format_buffers);
 4091        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4092        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4093        client.add_entity_request_handler(Self::handle_apply_code_action);
 4094        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4095        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4096        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4097        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4098        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4099        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4100        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4101        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4102        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4103        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4104        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4105        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4106        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4107        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4109        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4110        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4111        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4112
 4113        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4114        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4115        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4116        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4117        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4118        client.add_entity_request_handler(
 4119            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4120        );
 4121        client.add_entity_request_handler(
 4122            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4123        );
 4124        client.add_entity_request_handler(
 4125            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4126        );
 4127    }
 4128
 4129    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4130        match &self.mode {
 4131            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4132            _ => None,
 4133        }
 4134    }
 4135
 4136    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4137        match &self.mode {
 4138            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4139            _ => None,
 4140        }
 4141    }
 4142
 4143    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4144        match &mut self.mode {
 4145            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4146            _ => None,
 4147        }
 4148    }
 4149
 4150    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4151        match &self.mode {
 4152            LspStoreMode::Remote(RemoteLspStore {
 4153                upstream_client: Some(upstream_client),
 4154                upstream_project_id,
 4155                ..
 4156            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4157
 4158            LspStoreMode::Remote(RemoteLspStore {
 4159                upstream_client: None,
 4160                ..
 4161            }) => None,
 4162            LspStoreMode::Local(_) => None,
 4163        }
 4164    }
 4165
 4166    pub fn new_local(
 4167        buffer_store: Entity<BufferStore>,
 4168        worktree_store: Entity<WorktreeStore>,
 4169        prettier_store: Entity<PrettierStore>,
 4170        toolchain_store: Entity<LocalToolchainStore>,
 4171        environment: Entity<ProjectEnvironment>,
 4172        manifest_tree: Entity<ManifestTree>,
 4173        languages: Arc<LanguageRegistry>,
 4174        http_client: Arc<dyn HttpClient>,
 4175        fs: Arc<dyn Fs>,
 4176        cx: &mut Context<Self>,
 4177    ) -> Self {
 4178        let yarn = YarnPathStore::new(fs.clone(), cx);
 4179        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4180            .detach();
 4181        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4182            .detach();
 4183        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4184            .detach();
 4185        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4186            .detach();
 4187        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4188            .detach();
 4189        subscribe_to_binary_statuses(&languages, cx).detach();
 4190
 4191        let _maintain_workspace_config = {
 4192            let (sender, receiver) = watch::channel();
 4193            (Self::maintain_workspace_config(receiver, cx), sender)
 4194        };
 4195
 4196        Self {
 4197            mode: LspStoreMode::Local(LocalLspStore {
 4198                weak: cx.weak_entity(),
 4199                worktree_store: worktree_store.clone(),
 4200
 4201                supplementary_language_servers: Default::default(),
 4202                languages: languages.clone(),
 4203                language_server_ids: Default::default(),
 4204                language_servers: Default::default(),
 4205                last_workspace_edits_by_language_server: Default::default(),
 4206                language_server_watched_paths: Default::default(),
 4207                language_server_paths_watched_for_rename: Default::default(),
 4208                language_server_dynamic_registrations: Default::default(),
 4209                buffers_being_formatted: Default::default(),
 4210                buffers_to_refresh_hash_set: HashSet::default(),
 4211                buffers_to_refresh_queue: VecDeque::new(),
 4212                _background_diagnostics_worker: Task::ready(()).shared(),
 4213                buffer_snapshots: Default::default(),
 4214                prettier_store,
 4215                environment,
 4216                http_client,
 4217                fs,
 4218                yarn,
 4219                next_diagnostic_group_id: Default::default(),
 4220                diagnostics: Default::default(),
 4221                _subscription: cx.on_app_quit(|this, _| {
 4222                    this.as_local_mut()
 4223                        .unwrap()
 4224                        .shutdown_language_servers_on_quit()
 4225                }),
 4226                lsp_tree: LanguageServerTree::new(
 4227                    manifest_tree,
 4228                    languages.clone(),
 4229                    toolchain_store.clone(),
 4230                ),
 4231                toolchain_store,
 4232                registered_buffers: HashMap::default(),
 4233                buffers_opened_in_servers: HashMap::default(),
 4234                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4235                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4236                restricted_worktrees_tasks: HashMap::default(),
 4237                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4238                    .manifest_file_names(),
 4239            }),
 4240            last_formatting_failure: None,
 4241            downstream_client: None,
 4242            buffer_store,
 4243            worktree_store,
 4244            languages: languages.clone(),
 4245            language_server_statuses: Default::default(),
 4246            nonce: StdRng::from_os_rng().random(),
 4247            diagnostic_summaries: HashMap::default(),
 4248            lsp_server_capabilities: HashMap::default(),
 4249            semantic_token_config: SemanticTokenConfig::new(cx),
 4250            lsp_data: HashMap::default(),
 4251            buffer_reload_tasks: HashMap::default(),
 4252            next_hint_id: Arc::default(),
 4253            active_entry: None,
 4254            _maintain_workspace_config,
 4255            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4256        }
 4257    }
 4258
 4259    fn send_lsp_proto_request<R: LspCommand>(
 4260        &self,
 4261        buffer: Entity<Buffer>,
 4262        client: AnyProtoClient,
 4263        upstream_project_id: u64,
 4264        request: R,
 4265        cx: &mut Context<LspStore>,
 4266    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4267        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4268            return Task::ready(Ok(R::Response::default()));
 4269        }
 4270        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4271        cx.spawn(async move |this, cx| {
 4272            let response = client.request(message).await?;
 4273            let this = this.upgrade().context("project dropped")?;
 4274            request
 4275                .response_from_proto(response, this, buffer, cx.clone())
 4276                .await
 4277        })
 4278    }
 4279
 4280    pub(super) fn new_remote(
 4281        buffer_store: Entity<BufferStore>,
 4282        worktree_store: Entity<WorktreeStore>,
 4283        languages: Arc<LanguageRegistry>,
 4284        upstream_client: AnyProtoClient,
 4285        project_id: u64,
 4286        cx: &mut Context<Self>,
 4287    ) -> Self {
 4288        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4289            .detach();
 4290        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4291            .detach();
 4292        subscribe_to_binary_statuses(&languages, cx).detach();
 4293        let _maintain_workspace_config = {
 4294            let (sender, receiver) = watch::channel();
 4295            (Self::maintain_workspace_config(receiver, cx), sender)
 4296        };
 4297        Self {
 4298            mode: LspStoreMode::Remote(RemoteLspStore {
 4299                upstream_client: Some(upstream_client),
 4300                upstream_project_id: project_id,
 4301            }),
 4302            downstream_client: None,
 4303            last_formatting_failure: None,
 4304            buffer_store,
 4305            worktree_store,
 4306            languages: languages.clone(),
 4307            language_server_statuses: Default::default(),
 4308            nonce: StdRng::from_os_rng().random(),
 4309            diagnostic_summaries: HashMap::default(),
 4310            lsp_server_capabilities: HashMap::default(),
 4311            semantic_token_config: SemanticTokenConfig::new(cx),
 4312            next_hint_id: Arc::default(),
 4313            lsp_data: HashMap::default(),
 4314            buffer_reload_tasks: HashMap::default(),
 4315            active_entry: None,
 4316
 4317            _maintain_workspace_config,
 4318            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4319        }
 4320    }
 4321
 4322    fn on_buffer_store_event(
 4323        &mut self,
 4324        _: Entity<BufferStore>,
 4325        event: &BufferStoreEvent,
 4326        cx: &mut Context<Self>,
 4327    ) {
 4328        match event {
 4329            BufferStoreEvent::BufferAdded(buffer) => {
 4330                self.on_buffer_added(buffer, cx).log_err();
 4331            }
 4332            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4333                let buffer_id = buffer.read(cx).remote_id();
 4334                if let Some(local) = self.as_local_mut()
 4335                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4336                {
 4337                    local.reset_buffer(buffer, old_file, cx);
 4338
 4339                    if local.registered_buffers.contains_key(&buffer_id) {
 4340                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4341                    }
 4342                }
 4343
 4344                self.detect_language_for_buffer(buffer, cx);
 4345                if let Some(local) = self.as_local_mut() {
 4346                    local.initialize_buffer(buffer, cx);
 4347                    if local.registered_buffers.contains_key(&buffer_id) {
 4348                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4349                    }
 4350                }
 4351            }
 4352            _ => {}
 4353        }
 4354    }
 4355
 4356    fn on_worktree_store_event(
 4357        &mut self,
 4358        _: Entity<WorktreeStore>,
 4359        event: &WorktreeStoreEvent,
 4360        cx: &mut Context<Self>,
 4361    ) {
 4362        match event {
 4363            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4364                if !worktree.read(cx).is_local() {
 4365                    return;
 4366                }
 4367                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4368                    worktree::Event::UpdatedEntries(changes) => {
 4369                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4370                    }
 4371                    worktree::Event::UpdatedGitRepositories(_)
 4372                    | worktree::Event::DeletedEntry(_) => {}
 4373                })
 4374                .detach()
 4375            }
 4376            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4377            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4378                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4379            }
 4380            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4381                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4382            }
 4383            WorktreeStoreEvent::WorktreeReleased(..)
 4384            | WorktreeStoreEvent::WorktreeOrderChanged
 4385            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4386            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4387        }
 4388    }
 4389
 4390    fn on_prettier_store_event(
 4391        &mut self,
 4392        _: Entity<PrettierStore>,
 4393        event: &PrettierStoreEvent,
 4394        cx: &mut Context<Self>,
 4395    ) {
 4396        match event {
 4397            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4398                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4399            }
 4400            PrettierStoreEvent::LanguageServerAdded {
 4401                new_server_id,
 4402                name,
 4403                prettier_server,
 4404            } => {
 4405                self.register_supplementary_language_server(
 4406                    *new_server_id,
 4407                    name.clone(),
 4408                    prettier_server.clone(),
 4409                    cx,
 4410                );
 4411            }
 4412        }
 4413    }
 4414
 4415    fn on_toolchain_store_event(
 4416        &mut self,
 4417        _: Entity<LocalToolchainStore>,
 4418        event: &ToolchainStoreEvent,
 4419        _: &mut Context<Self>,
 4420    ) {
 4421        if let ToolchainStoreEvent::ToolchainActivated = event {
 4422            self.request_workspace_config_refresh()
 4423        }
 4424    }
 4425
 4426    fn request_workspace_config_refresh(&mut self) {
 4427        *self._maintain_workspace_config.1.borrow_mut() = ();
 4428    }
 4429
 4430    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4431        self.as_local().map(|local| local.prettier_store.clone())
 4432    }
 4433
 4434    fn on_buffer_event(
 4435        &mut self,
 4436        buffer: Entity<Buffer>,
 4437        event: &language::BufferEvent,
 4438        cx: &mut Context<Self>,
 4439    ) {
 4440        match event {
 4441            language::BufferEvent::Edited { .. } => {
 4442                self.on_buffer_edited(buffer, cx);
 4443            }
 4444
 4445            language::BufferEvent::Saved => {
 4446                self.on_buffer_saved(buffer, cx);
 4447            }
 4448
 4449            language::BufferEvent::Reloaded => {
 4450                self.on_buffer_reloaded(buffer, cx);
 4451            }
 4452
 4453            _ => {}
 4454        }
 4455    }
 4456
 4457    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4458        buffer
 4459            .read(cx)
 4460            .set_language_registry(self.languages.clone());
 4461
 4462        cx.subscribe(buffer, |this, buffer, event, cx| {
 4463            this.on_buffer_event(buffer, event, cx);
 4464        })
 4465        .detach();
 4466
 4467        self.detect_language_for_buffer(buffer, cx);
 4468        if let Some(local) = self.as_local_mut() {
 4469            local.initialize_buffer(buffer, cx);
 4470        }
 4471
 4472        Ok(())
 4473    }
 4474
 4475    pub fn refresh_background_diagnostics_for_buffers(
 4476        &mut self,
 4477        buffers: HashSet<BufferId>,
 4478        cx: &mut Context<Self>,
 4479    ) -> Shared<Task<()>> {
 4480        let Some(local) = self.as_local_mut() else {
 4481            return Task::ready(()).shared();
 4482        };
 4483        for buffer in buffers {
 4484            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4485                local.buffers_to_refresh_queue.push_back(buffer);
 4486                if local.buffers_to_refresh_queue.len() == 1 {
 4487                    local._background_diagnostics_worker =
 4488                        Self::background_diagnostics_worker(cx).shared();
 4489                }
 4490            }
 4491        }
 4492
 4493        local._background_diagnostics_worker.clone()
 4494    }
 4495
 4496    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4497        let buffer_store = self.buffer_store.clone();
 4498        let local = self.as_local_mut()?;
 4499        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4500            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4501            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4502                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4503            }
 4504        }
 4505        None
 4506    }
 4507
 4508    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4509        cx.spawn(async move |this, cx| {
 4510            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4511                task.await.log_err();
 4512            }
 4513        })
 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 detect_language_for_buffer(
 4740        &mut self,
 4741        buffer_handle: &Entity<Buffer>,
 4742        cx: &mut Context<Self>,
 4743    ) -> Option<language::AvailableLanguage> {
 4744        // If the buffer has a language, set it and start the language server if we haven't already.
 4745        let buffer = buffer_handle.read(cx);
 4746        let file = buffer.file()?;
 4747
 4748        let content = buffer.as_rope();
 4749        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4750        if let Some(available_language) = &available_language {
 4751            if let Some(Ok(Ok(new_language))) = self
 4752                .languages
 4753                .load_language(available_language)
 4754                .now_or_never()
 4755            {
 4756                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4757            }
 4758        } else {
 4759            cx.emit(LspStoreEvent::LanguageDetected {
 4760                buffer: buffer_handle.clone(),
 4761                new_language: None,
 4762            });
 4763        }
 4764
 4765        available_language
 4766    }
 4767
 4768    pub(crate) fn set_language_for_buffer(
 4769        &mut self,
 4770        buffer_entity: &Entity<Buffer>,
 4771        new_language: Arc<Language>,
 4772        cx: &mut Context<Self>,
 4773    ) {
 4774        let buffer = buffer_entity.read(cx);
 4775        let buffer_file = buffer.file().cloned();
 4776        let buffer_id = buffer.remote_id();
 4777        if let Some(local_store) = self.as_local_mut()
 4778            && local_store.registered_buffers.contains_key(&buffer_id)
 4779            && let Some(abs_path) =
 4780                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4781            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4782        {
 4783            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4784        }
 4785        buffer_entity.update(cx, |buffer, cx| {
 4786            if buffer
 4787                .language()
 4788                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4789            {
 4790                buffer.set_language_async(Some(new_language.clone()), cx);
 4791            }
 4792        });
 4793
 4794        let settings =
 4795            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4796        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4797
 4798        let worktree_id = if let Some(file) = buffer_file {
 4799            let worktree = file.worktree.clone();
 4800
 4801            if let Some(local) = self.as_local_mut()
 4802                && local.registered_buffers.contains_key(&buffer_id)
 4803            {
 4804                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4805            }
 4806            Some(worktree.read(cx).id())
 4807        } else {
 4808            None
 4809        };
 4810
 4811        if settings.prettier.allowed
 4812            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4813        {
 4814            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4815            if let Some(prettier_store) = prettier_store {
 4816                prettier_store.update(cx, |prettier_store, cx| {
 4817                    prettier_store.install_default_prettier(
 4818                        worktree_id,
 4819                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4820                        cx,
 4821                    )
 4822                })
 4823            }
 4824        }
 4825
 4826        cx.emit(LspStoreEvent::LanguageDetected {
 4827            buffer: buffer_entity.clone(),
 4828            new_language: Some(new_language),
 4829        })
 4830    }
 4831
 4832    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4833        self.buffer_store.clone()
 4834    }
 4835
 4836    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4837        self.active_entry = active_entry;
 4838    }
 4839
 4840    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4841        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4842            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4843        {
 4844            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4845                summaries
 4846                    .iter()
 4847                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4848            });
 4849            if let Some(summary) = summaries.next() {
 4850                client
 4851                    .send(proto::UpdateDiagnosticSummary {
 4852                        project_id: downstream_project_id,
 4853                        worktree_id: worktree.id().to_proto(),
 4854                        summary: Some(summary),
 4855                        more_summaries: summaries.collect(),
 4856                    })
 4857                    .log_err();
 4858            }
 4859        }
 4860    }
 4861
 4862    fn is_capable_for_proto_request<R>(
 4863        &self,
 4864        buffer: &Entity<Buffer>,
 4865        request: &R,
 4866        cx: &App,
 4867    ) -> bool
 4868    where
 4869        R: LspCommand,
 4870    {
 4871        self.check_if_capable_for_proto_request(
 4872            buffer,
 4873            |capabilities| {
 4874                request.check_capabilities(AdapterServerCapabilities {
 4875                    server_capabilities: capabilities.clone(),
 4876                    code_action_kinds: None,
 4877                })
 4878            },
 4879            cx,
 4880        )
 4881    }
 4882
 4883    fn check_if_capable_for_proto_request<F>(
 4884        &self,
 4885        buffer: &Entity<Buffer>,
 4886        check: F,
 4887        cx: &App,
 4888    ) -> bool
 4889    where
 4890        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4891    {
 4892        let Some(language) = buffer.read(cx).language().cloned() else {
 4893            return false;
 4894        };
 4895        let registered_language_servers = self
 4896            .languages
 4897            .lsp_adapters(&language.name())
 4898            .into_iter()
 4899            .map(|lsp_adapter| lsp_adapter.name())
 4900            .collect::<HashSet<_>>();
 4901        self.language_server_statuses
 4902            .iter()
 4903            .filter_map(|(server_id, server_status)| {
 4904                // Include servers that are either registered for this language OR
 4905                // available to be loaded (for SSH remote mode where adapters like
 4906                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4907                // but only loaded on the server side)
 4908                let is_relevant = registered_language_servers.contains(&server_status.name)
 4909                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4910                is_relevant.then_some(server_id)
 4911            })
 4912            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4913            .any(check)
 4914    }
 4915
 4916    fn all_capable_for_proto_request<F>(
 4917        &self,
 4918        buffer: &Entity<Buffer>,
 4919        mut check: F,
 4920        cx: &App,
 4921    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4922    where
 4923        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4924    {
 4925        let Some(language) = buffer.read(cx).language().cloned() else {
 4926            return Vec::default();
 4927        };
 4928        let registered_language_servers = self
 4929            .languages
 4930            .lsp_adapters(&language.name())
 4931            .into_iter()
 4932            .map(|lsp_adapter| lsp_adapter.name())
 4933            .collect::<HashSet<_>>();
 4934        self.language_server_statuses
 4935            .iter()
 4936            .filter_map(|(server_id, server_status)| {
 4937                // Include servers that are either registered for this language OR
 4938                // available to be loaded (for SSH remote mode where adapters like
 4939                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4940                // but only loaded on the server side)
 4941                let is_relevant = registered_language_servers.contains(&server_status.name)
 4942                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4943                is_relevant.then_some((server_id, &server_status.name))
 4944            })
 4945            .filter_map(|(server_id, server_name)| {
 4946                self.lsp_server_capabilities
 4947                    .get(server_id)
 4948                    .map(|c| (server_id, server_name, c))
 4949            })
 4950            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4951            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 4952            .collect()
 4953    }
 4954
 4955    pub fn request_lsp<R>(
 4956        &mut self,
 4957        buffer: Entity<Buffer>,
 4958        server: LanguageServerToQuery,
 4959        request: R,
 4960        cx: &mut Context<Self>,
 4961    ) -> Task<Result<R::Response>>
 4962    where
 4963        R: LspCommand,
 4964        <R::LspRequest as lsp::request::Request>::Result: Send,
 4965        <R::LspRequest as lsp::request::Request>::Params: Send,
 4966    {
 4967        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4968            return self.send_lsp_proto_request(
 4969                buffer,
 4970                upstream_client,
 4971                upstream_project_id,
 4972                request,
 4973                cx,
 4974            );
 4975        }
 4976
 4977        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4978            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4979                local
 4980                    .language_servers_for_buffer(buffer, cx)
 4981                    .find(|(_, server)| {
 4982                        request.check_capabilities(server.adapter_server_capabilities())
 4983                    })
 4984                    .map(|(_, server)| server.clone())
 4985            }),
 4986            LanguageServerToQuery::Other(id) => self
 4987                .language_server_for_local_buffer(buffer, id, cx)
 4988                .and_then(|(_, server)| {
 4989                    request
 4990                        .check_capabilities(server.adapter_server_capabilities())
 4991                        .then(|| Arc::clone(server))
 4992                }),
 4993        }) else {
 4994            return Task::ready(Ok(Default::default()));
 4995        };
 4996
 4997        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4998
 4999        let Some(file) = file else {
 5000            return Task::ready(Ok(Default::default()));
 5001        };
 5002
 5003        let lsp_params = match request.to_lsp_params_or_response(
 5004            &file.abs_path(cx),
 5005            buffer.read(cx),
 5006            &language_server,
 5007            cx,
 5008        ) {
 5009            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5010            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5011            Err(err) => {
 5012                let message = format!(
 5013                    "{} via {} failed: {}",
 5014                    request.display_name(),
 5015                    language_server.name(),
 5016                    err
 5017                );
 5018                // rust-analyzer likes to error with this when its still loading up
 5019                if !message.ends_with("content modified") {
 5020                    log::warn!("{message}");
 5021                }
 5022                return Task::ready(Err(anyhow!(message)));
 5023            }
 5024        };
 5025
 5026        let status = request.status();
 5027        let request_timeout = ProjectSettings::get_global(cx)
 5028            .global_lsp_settings
 5029            .get_request_timeout();
 5030
 5031        cx.spawn(async move |this, cx| {
 5032            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5033
 5034            let id = lsp_request.id();
 5035            let _cleanup = if status.is_some() {
 5036                cx.update(|cx| {
 5037                    this.update(cx, |this, cx| {
 5038                        this.on_lsp_work_start(
 5039                            language_server.server_id(),
 5040                            ProgressToken::Number(id),
 5041                            LanguageServerProgress {
 5042                                is_disk_based_diagnostics_progress: false,
 5043                                is_cancellable: false,
 5044                                title: None,
 5045                                message: status.clone(),
 5046                                percentage: None,
 5047                                last_update_at: cx.background_executor().now(),
 5048                            },
 5049                            cx,
 5050                        );
 5051                    })
 5052                })
 5053                .log_err();
 5054
 5055                Some(defer(|| {
 5056                    cx.update(|cx| {
 5057                        this.update(cx, |this, cx| {
 5058                            this.on_lsp_work_end(
 5059                                language_server.server_id(),
 5060                                ProgressToken::Number(id),
 5061                                cx,
 5062                            );
 5063                        })
 5064                    })
 5065                    .log_err();
 5066                }))
 5067            } else {
 5068                None
 5069            };
 5070
 5071            let result = lsp_request.await.into_response();
 5072
 5073            let response = result.map_err(|err| {
 5074                let message = format!(
 5075                    "{} via {} failed: {}",
 5076                    request.display_name(),
 5077                    language_server.name(),
 5078                    err
 5079                );
 5080                // rust-analyzer likes to error with this when its still loading up
 5081                if !message.ends_with("content modified") {
 5082                    log::warn!("{message}");
 5083                }
 5084                anyhow::anyhow!(message)
 5085            })?;
 5086
 5087            request
 5088                .response_from_lsp(
 5089                    response,
 5090                    this.upgrade().context("no app context")?,
 5091                    buffer,
 5092                    language_server.server_id(),
 5093                    cx.clone(),
 5094                )
 5095                .await
 5096        })
 5097    }
 5098
 5099    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5100        let mut language_formatters_to_check = Vec::new();
 5101        for buffer in self.buffer_store.read(cx).buffers() {
 5102            let buffer = buffer.read(cx);
 5103            let buffer_file = File::from_dyn(buffer.file());
 5104            let buffer_language = buffer.language();
 5105            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5106            if buffer_language.is_some() {
 5107                language_formatters_to_check.push((
 5108                    buffer_file.map(|f| f.worktree_id(cx)),
 5109                    settings.into_owned(),
 5110                ));
 5111            }
 5112        }
 5113
 5114        self.request_workspace_config_refresh();
 5115
 5116        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5117            prettier_store.update(cx, |prettier_store, cx| {
 5118                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5119            })
 5120        }
 5121
 5122        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5123            .global_lsp_settings
 5124            .semantic_token_rules
 5125            .clone();
 5126        self.semantic_token_config
 5127            .update_rules(new_semantic_token_rules);
 5128        // Always clear cached stylizers so that changes to language-specific
 5129        // semantic token rules (e.g. from extension install/uninstall) are
 5130        // picked up. Stylizers are recreated lazily, so this is cheap.
 5131        self.semantic_token_config.clear_stylizers();
 5132
 5133        let new_global_semantic_tokens_mode =
 5134            all_language_settings(None, cx).defaults.semantic_tokens;
 5135        if self
 5136            .semantic_token_config
 5137            .update_global_mode(new_global_semantic_tokens_mode)
 5138        {
 5139            self.restart_all_language_servers(cx);
 5140        }
 5141
 5142        cx.notify();
 5143    }
 5144
 5145    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5146        let buffer_store = self.buffer_store.clone();
 5147        let Some(local) = self.as_local_mut() else {
 5148            return;
 5149        };
 5150        let mut adapters = BTreeMap::default();
 5151        let get_adapter = {
 5152            let languages = local.languages.clone();
 5153            let environment = local.environment.clone();
 5154            let weak = local.weak.clone();
 5155            let worktree_store = local.worktree_store.clone();
 5156            let http_client = local.http_client.clone();
 5157            let fs = local.fs.clone();
 5158            move |worktree_id, cx: &mut App| {
 5159                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5160                Some(LocalLspAdapterDelegate::new(
 5161                    languages.clone(),
 5162                    &environment,
 5163                    weak.clone(),
 5164                    &worktree,
 5165                    http_client.clone(),
 5166                    fs.clone(),
 5167                    cx,
 5168                ))
 5169            }
 5170        };
 5171
 5172        let mut messages_to_report = Vec::new();
 5173        let (new_tree, to_stop) = {
 5174            let mut rebase = local.lsp_tree.rebase();
 5175            let buffers = buffer_store
 5176                .read(cx)
 5177                .buffers()
 5178                .filter_map(|buffer| {
 5179                    let raw_buffer = buffer.read(cx);
 5180                    if !local
 5181                        .registered_buffers
 5182                        .contains_key(&raw_buffer.remote_id())
 5183                    {
 5184                        return None;
 5185                    }
 5186                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5187                    let language = raw_buffer.language().cloned()?;
 5188                    Some((file, language, raw_buffer.remote_id()))
 5189                })
 5190                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5191            for (file, language, buffer_id) in buffers {
 5192                let worktree_id = file.worktree_id(cx);
 5193                let Some(worktree) = local
 5194                    .worktree_store
 5195                    .read(cx)
 5196                    .worktree_for_id(worktree_id, cx)
 5197                else {
 5198                    continue;
 5199                };
 5200
 5201                if let Some((_, apply)) = local.reuse_existing_language_server(
 5202                    rebase.server_tree(),
 5203                    &worktree,
 5204                    &language.name(),
 5205                    cx,
 5206                ) {
 5207                    (apply)(rebase.server_tree());
 5208                } else if let Some(lsp_delegate) = adapters
 5209                    .entry(worktree_id)
 5210                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5211                    .clone()
 5212                {
 5213                    let delegate =
 5214                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5215                    let path = file
 5216                        .path()
 5217                        .parent()
 5218                        .map(Arc::from)
 5219                        .unwrap_or_else(|| file.path().clone());
 5220                    let worktree_path = ProjectPath { worktree_id, path };
 5221                    let abs_path = file.abs_path(cx);
 5222                    let nodes = rebase
 5223                        .walk(
 5224                            worktree_path,
 5225                            language.name(),
 5226                            language.manifest(),
 5227                            delegate.clone(),
 5228                            cx,
 5229                        )
 5230                        .collect::<Vec<_>>();
 5231                    for node in nodes {
 5232                        let server_id = node.server_id_or_init(|disposition| {
 5233                            let path = &disposition.path;
 5234                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5235                            let key = LanguageServerSeed {
 5236                                worktree_id,
 5237                                name: disposition.server_name.clone(),
 5238                                settings: LanguageServerSeedSettings {
 5239                                    binary: disposition.settings.binary.clone(),
 5240                                    initialization_options: disposition
 5241                                        .settings
 5242                                        .initialization_options
 5243                                        .clone(),
 5244                                },
 5245                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5246                                    path.worktree_id,
 5247                                    &path.path,
 5248                                    language.name(),
 5249                                ),
 5250                            };
 5251                            local.language_server_ids.remove(&key);
 5252
 5253                            let server_id = local.get_or_insert_language_server(
 5254                                &worktree,
 5255                                lsp_delegate.clone(),
 5256                                disposition,
 5257                                &language.name(),
 5258                                cx,
 5259                            );
 5260                            if let Some(state) = local.language_servers.get(&server_id)
 5261                                && let Ok(uri) = uri
 5262                            {
 5263                                state.add_workspace_folder(uri);
 5264                            };
 5265                            server_id
 5266                        });
 5267
 5268                        if let Some(language_server_id) = server_id {
 5269                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5270                                language_server_id,
 5271                                name: node.name(),
 5272                                message:
 5273                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5274                                        proto::RegisteredForBuffer {
 5275                                            buffer_abs_path: abs_path
 5276                                                .to_string_lossy()
 5277                                                .into_owned(),
 5278                                            buffer_id: buffer_id.to_proto(),
 5279                                        },
 5280                                    ),
 5281                            });
 5282                        }
 5283                    }
 5284                } else {
 5285                    continue;
 5286                }
 5287            }
 5288            rebase.finish()
 5289        };
 5290        for message in messages_to_report {
 5291            cx.emit(message);
 5292        }
 5293        local.lsp_tree = new_tree;
 5294        for (id, _) in to_stop {
 5295            self.stop_local_language_server(id, cx).detach();
 5296        }
 5297    }
 5298
 5299    pub fn apply_code_action(
 5300        &self,
 5301        buffer_handle: Entity<Buffer>,
 5302        mut action: CodeAction,
 5303        push_to_history: bool,
 5304        cx: &mut Context<Self>,
 5305    ) -> Task<Result<ProjectTransaction>> {
 5306        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5307            let request = proto::ApplyCodeAction {
 5308                project_id,
 5309                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5310                action: Some(Self::serialize_code_action(&action)),
 5311            };
 5312            let buffer_store = self.buffer_store();
 5313            cx.spawn(async move |_, cx| {
 5314                let response = upstream_client
 5315                    .request(request)
 5316                    .await?
 5317                    .transaction
 5318                    .context("missing transaction")?;
 5319
 5320                buffer_store
 5321                    .update(cx, |buffer_store, cx| {
 5322                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5323                    })
 5324                    .await
 5325            })
 5326        } else if self.mode.is_local() {
 5327            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5328                let request_timeout = ProjectSettings::get_global(cx)
 5329                    .global_lsp_settings
 5330                    .get_request_timeout();
 5331                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5332                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5333            }) else {
 5334                return Task::ready(Ok(ProjectTransaction::default()));
 5335            };
 5336
 5337            cx.spawn(async move |this, cx| {
 5338                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5339                    .await
 5340                    .context("resolving a code action")?;
 5341                if let Some(edit) = action.lsp_action.edit()
 5342                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5343                        return LocalLspStore::deserialize_workspace_edit(
 5344                            this.upgrade().context("no app present")?,
 5345                            edit.clone(),
 5346                            push_to_history,
 5347
 5348                            lang_server.clone(),
 5349                            cx,
 5350                        )
 5351                        .await;
 5352                    }
 5353
 5354                let Some(command) = action.lsp_action.command() else {
 5355                    return Ok(ProjectTransaction::default())
 5356                };
 5357
 5358                let server_capabilities = lang_server.capabilities();
 5359                let available_commands = server_capabilities
 5360                    .execute_command_provider
 5361                    .as_ref()
 5362                    .map(|options| options.commands.as_slice())
 5363                    .unwrap_or_default();
 5364
 5365                if !available_commands.contains(&command.command) {
 5366                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5367                    return Ok(ProjectTransaction::default())
 5368                }
 5369
 5370                let request_timeout = cx.update(|app|
 5371                    ProjectSettings::get_global(app)
 5372                    .global_lsp_settings
 5373                    .get_request_timeout()
 5374                );
 5375
 5376                this.update(cx, |this, _| {
 5377                    this.as_local_mut()
 5378                        .unwrap()
 5379                        .last_workspace_edits_by_language_server
 5380                        .remove(&lang_server.server_id());
 5381                })?;
 5382
 5383                let _result = lang_server
 5384                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5385                        command: command.command.clone(),
 5386                        arguments: command.arguments.clone().unwrap_or_default(),
 5387                        ..lsp::ExecuteCommandParams::default()
 5388                    }, request_timeout)
 5389                    .await.into_response()
 5390                    .context("execute command")?;
 5391
 5392                return this.update(cx, |this, _| {
 5393                    this.as_local_mut()
 5394                        .unwrap()
 5395                        .last_workspace_edits_by_language_server
 5396                        .remove(&lang_server.server_id())
 5397                        .unwrap_or_default()
 5398                });
 5399            })
 5400        } else {
 5401            Task::ready(Err(anyhow!("no upstream client and not local")))
 5402        }
 5403    }
 5404
 5405    pub fn apply_code_action_kind(
 5406        &mut self,
 5407        buffers: HashSet<Entity<Buffer>>,
 5408        kind: CodeActionKind,
 5409        push_to_history: bool,
 5410        cx: &mut Context<Self>,
 5411    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5412        if self.as_local().is_some() {
 5413            cx.spawn(async move |lsp_store, cx| {
 5414                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5415                let result = LocalLspStore::execute_code_action_kind_locally(
 5416                    lsp_store.clone(),
 5417                    buffers,
 5418                    kind,
 5419                    push_to_history,
 5420                    cx,
 5421                )
 5422                .await;
 5423                lsp_store.update(cx, |lsp_store, _| {
 5424                    lsp_store.update_last_formatting_failure(&result);
 5425                })?;
 5426                result
 5427            })
 5428        } else if let Some((client, project_id)) = self.upstream_client() {
 5429            let buffer_store = self.buffer_store();
 5430            cx.spawn(async move |lsp_store, cx| {
 5431                let result = client
 5432                    .request(proto::ApplyCodeActionKind {
 5433                        project_id,
 5434                        kind: kind.as_str().to_owned(),
 5435                        buffer_ids: buffers
 5436                            .iter()
 5437                            .map(|buffer| {
 5438                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5439                            })
 5440                            .collect(),
 5441                    })
 5442                    .await
 5443                    .and_then(|result| result.transaction.context("missing transaction"));
 5444                lsp_store.update(cx, |lsp_store, _| {
 5445                    lsp_store.update_last_formatting_failure(&result);
 5446                })?;
 5447
 5448                let transaction_response = result?;
 5449                buffer_store
 5450                    .update(cx, |buffer_store, cx| {
 5451                        buffer_store.deserialize_project_transaction(
 5452                            transaction_response,
 5453                            push_to_history,
 5454                            cx,
 5455                        )
 5456                    })
 5457                    .await
 5458            })
 5459        } else {
 5460            Task::ready(Ok(ProjectTransaction::default()))
 5461        }
 5462    }
 5463
 5464    pub fn resolved_hint(
 5465        &mut self,
 5466        buffer_id: BufferId,
 5467        id: InlayId,
 5468        cx: &mut Context<Self>,
 5469    ) -> Option<ResolvedHint> {
 5470        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5471
 5472        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5473        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5474        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5475        let (server_id, resolve_data) = match &hint.resolve_state {
 5476            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5477            ResolveState::Resolving => {
 5478                return Some(ResolvedHint::Resolving(
 5479                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5480                ));
 5481            }
 5482            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5483        };
 5484
 5485        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5486        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5487        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5488            id,
 5489            cx.spawn(async move |lsp_store, cx| {
 5490                let resolved_hint = resolve_task.await;
 5491                lsp_store
 5492                    .update(cx, |lsp_store, _| {
 5493                        if let Some(old_inlay_hint) = lsp_store
 5494                            .lsp_data
 5495                            .get_mut(&buffer_id)
 5496                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5497                        {
 5498                            match resolved_hint {
 5499                                Ok(resolved_hint) => {
 5500                                    *old_inlay_hint = resolved_hint;
 5501                                }
 5502                                Err(e) => {
 5503                                    old_inlay_hint.resolve_state =
 5504                                        ResolveState::CanResolve(server_id, resolve_data);
 5505                                    log::error!("Inlay hint resolve failed: {e:#}");
 5506                                }
 5507                            }
 5508                        }
 5509                    })
 5510                    .ok();
 5511            })
 5512            .shared(),
 5513        );
 5514        debug_assert!(
 5515            previous_task.is_none(),
 5516            "Did not change hint's resolve state after spawning its resolve"
 5517        );
 5518        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5519        None
 5520    }
 5521
 5522    pub(crate) fn linked_edits(
 5523        &mut self,
 5524        buffer: &Entity<Buffer>,
 5525        position: Anchor,
 5526        cx: &mut Context<Self>,
 5527    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5528        let snapshot = buffer.read(cx).snapshot();
 5529        let scope = snapshot.language_scope_at(position);
 5530        let Some(server_id) = self
 5531            .as_local()
 5532            .and_then(|local| {
 5533                buffer.update(cx, |buffer, cx| {
 5534                    local
 5535                        .language_servers_for_buffer(buffer, cx)
 5536                        .filter(|(_, server)| {
 5537                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5538                        })
 5539                        .filter(|(adapter, _)| {
 5540                            scope
 5541                                .as_ref()
 5542                                .map(|scope| scope.language_allowed(&adapter.name))
 5543                                .unwrap_or(true)
 5544                        })
 5545                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5546                        .next()
 5547                })
 5548            })
 5549            .or_else(|| {
 5550                self.upstream_client()
 5551                    .is_some()
 5552                    .then_some(LanguageServerToQuery::FirstCapable)
 5553            })
 5554            .filter(|_| {
 5555                maybe!({
 5556                    let language = buffer.read(cx).language_at(position)?;
 5557                    Some(
 5558                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5559                            .linked_edits,
 5560                    )
 5561                }) == Some(true)
 5562            })
 5563        else {
 5564            return Task::ready(Ok(Vec::new()));
 5565        };
 5566
 5567        self.request_lsp(
 5568            buffer.clone(),
 5569            server_id,
 5570            LinkedEditingRange { position },
 5571            cx,
 5572        )
 5573    }
 5574
 5575    fn apply_on_type_formatting(
 5576        &mut self,
 5577        buffer: Entity<Buffer>,
 5578        position: Anchor,
 5579        trigger: String,
 5580        cx: &mut Context<Self>,
 5581    ) -> Task<Result<Option<Transaction>>> {
 5582        if let Some((client, project_id)) = self.upstream_client() {
 5583            if !self.check_if_capable_for_proto_request(
 5584                &buffer,
 5585                |capabilities| {
 5586                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5587                },
 5588                cx,
 5589            ) {
 5590                return Task::ready(Ok(None));
 5591            }
 5592            let request = proto::OnTypeFormatting {
 5593                project_id,
 5594                buffer_id: buffer.read(cx).remote_id().into(),
 5595                position: Some(serialize_anchor(&position)),
 5596                trigger,
 5597                version: serialize_version(&buffer.read(cx).version()),
 5598            };
 5599            cx.background_spawn(async move {
 5600                client
 5601                    .request(request)
 5602                    .await?
 5603                    .transaction
 5604                    .map(language::proto::deserialize_transaction)
 5605                    .transpose()
 5606            })
 5607        } else if let Some(local) = self.as_local_mut() {
 5608            let buffer_id = buffer.read(cx).remote_id();
 5609            local.buffers_being_formatted.insert(buffer_id);
 5610            cx.spawn(async move |this, cx| {
 5611                let _cleanup = defer({
 5612                    let this = this.clone();
 5613                    let mut cx = cx.clone();
 5614                    move || {
 5615                        this.update(&mut cx, |this, _| {
 5616                            if let Some(local) = this.as_local_mut() {
 5617                                local.buffers_being_formatted.remove(&buffer_id);
 5618                            }
 5619                        })
 5620                        .ok();
 5621                    }
 5622                });
 5623
 5624                buffer
 5625                    .update(cx, |buffer, _| {
 5626                        buffer.wait_for_edits(Some(position.timestamp()))
 5627                    })
 5628                    .await?;
 5629                this.update(cx, |this, cx| {
 5630                    let position = position.to_point_utf16(buffer.read(cx));
 5631                    this.on_type_format(buffer, position, trigger, false, cx)
 5632                })?
 5633                .await
 5634            })
 5635        } else {
 5636            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5637        }
 5638    }
 5639
 5640    pub fn on_type_format<T: ToPointUtf16>(
 5641        &mut self,
 5642        buffer: Entity<Buffer>,
 5643        position: T,
 5644        trigger: String,
 5645        push_to_history: bool,
 5646        cx: &mut Context<Self>,
 5647    ) -> Task<Result<Option<Transaction>>> {
 5648        let position = position.to_point_utf16(buffer.read(cx));
 5649        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5650    }
 5651
 5652    fn on_type_format_impl(
 5653        &mut self,
 5654        buffer: Entity<Buffer>,
 5655        position: PointUtf16,
 5656        trigger: String,
 5657        push_to_history: bool,
 5658        cx: &mut Context<Self>,
 5659    ) -> Task<Result<Option<Transaction>>> {
 5660        let options = buffer.update(cx, |buffer, cx| {
 5661            lsp_command::lsp_formatting_options(
 5662                language_settings(
 5663                    buffer.language_at(position).map(|l| l.name()),
 5664                    buffer.file(),
 5665                    cx,
 5666                )
 5667                .as_ref(),
 5668            )
 5669        });
 5670
 5671        cx.spawn(async move |this, cx| {
 5672            if let Some(waiter) =
 5673                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5674            {
 5675                waiter.await?;
 5676            }
 5677            cx.update(|cx| {
 5678                this.update(cx, |this, cx| {
 5679                    this.request_lsp(
 5680                        buffer.clone(),
 5681                        LanguageServerToQuery::FirstCapable,
 5682                        OnTypeFormatting {
 5683                            position,
 5684                            trigger,
 5685                            options,
 5686                            push_to_history,
 5687                        },
 5688                        cx,
 5689                    )
 5690                })
 5691            })?
 5692            .await
 5693        })
 5694    }
 5695
 5696    pub fn definitions(
 5697        &mut self,
 5698        buffer: &Entity<Buffer>,
 5699        position: PointUtf16,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5702        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5703            let request = GetDefinitions { position };
 5704            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5705                return Task::ready(Ok(None));
 5706            }
 5707
 5708            let request_timeout = ProjectSettings::get_global(cx)
 5709                .global_lsp_settings
 5710                .get_request_timeout();
 5711
 5712            let request_task = upstream_client.request_lsp(
 5713                project_id,
 5714                None,
 5715                request_timeout,
 5716                cx.background_executor().clone(),
 5717                request.to_proto(project_id, buffer.read(cx)),
 5718            );
 5719            let buffer = buffer.clone();
 5720            cx.spawn(async move |weak_lsp_store, cx| {
 5721                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5722                    return Ok(None);
 5723                };
 5724                let Some(responses) = request_task.await? else {
 5725                    return Ok(None);
 5726                };
 5727                let actions = join_all(responses.payload.into_iter().map(|response| {
 5728                    GetDefinitions { position }.response_from_proto(
 5729                        response.response,
 5730                        lsp_store.clone(),
 5731                        buffer.clone(),
 5732                        cx.clone(),
 5733                    )
 5734                }))
 5735                .await;
 5736
 5737                Ok(Some(
 5738                    actions
 5739                        .into_iter()
 5740                        .collect::<Result<Vec<Vec<_>>>>()?
 5741                        .into_iter()
 5742                        .flatten()
 5743                        .dedup()
 5744                        .collect(),
 5745                ))
 5746            })
 5747        } else {
 5748            let definitions_task = self.request_multiple_lsp_locally(
 5749                buffer,
 5750                Some(position),
 5751                GetDefinitions { position },
 5752                cx,
 5753            );
 5754            cx.background_spawn(async move {
 5755                Ok(Some(
 5756                    definitions_task
 5757                        .await
 5758                        .into_iter()
 5759                        .flat_map(|(_, definitions)| definitions)
 5760                        .dedup()
 5761                        .collect(),
 5762                ))
 5763            })
 5764        }
 5765    }
 5766
 5767    pub fn declarations(
 5768        &mut self,
 5769        buffer: &Entity<Buffer>,
 5770        position: PointUtf16,
 5771        cx: &mut Context<Self>,
 5772    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5773        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5774            let request = GetDeclarations { position };
 5775            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5776                return Task::ready(Ok(None));
 5777            }
 5778            let request_timeout = ProjectSettings::get_global(cx)
 5779                .global_lsp_settings
 5780                .get_request_timeout();
 5781            let request_task = upstream_client.request_lsp(
 5782                project_id,
 5783                None,
 5784                request_timeout,
 5785                cx.background_executor().clone(),
 5786                request.to_proto(project_id, buffer.read(cx)),
 5787            );
 5788            let buffer = buffer.clone();
 5789            cx.spawn(async move |weak_lsp_store, cx| {
 5790                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5791                    return Ok(None);
 5792                };
 5793                let Some(responses) = request_task.await? else {
 5794                    return Ok(None);
 5795                };
 5796                let actions = join_all(responses.payload.into_iter().map(|response| {
 5797                    GetDeclarations { position }.response_from_proto(
 5798                        response.response,
 5799                        lsp_store.clone(),
 5800                        buffer.clone(),
 5801                        cx.clone(),
 5802                    )
 5803                }))
 5804                .await;
 5805
 5806                Ok(Some(
 5807                    actions
 5808                        .into_iter()
 5809                        .collect::<Result<Vec<Vec<_>>>>()?
 5810                        .into_iter()
 5811                        .flatten()
 5812                        .dedup()
 5813                        .collect(),
 5814                ))
 5815            })
 5816        } else {
 5817            let declarations_task = self.request_multiple_lsp_locally(
 5818                buffer,
 5819                Some(position),
 5820                GetDeclarations { position },
 5821                cx,
 5822            );
 5823            cx.background_spawn(async move {
 5824                Ok(Some(
 5825                    declarations_task
 5826                        .await
 5827                        .into_iter()
 5828                        .flat_map(|(_, declarations)| declarations)
 5829                        .dedup()
 5830                        .collect(),
 5831                ))
 5832            })
 5833        }
 5834    }
 5835
 5836    pub fn type_definitions(
 5837        &mut self,
 5838        buffer: &Entity<Buffer>,
 5839        position: PointUtf16,
 5840        cx: &mut Context<Self>,
 5841    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5842        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5843            let request = GetTypeDefinitions { position };
 5844            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5845                return Task::ready(Ok(None));
 5846            }
 5847            let request_timeout = ProjectSettings::get_global(cx)
 5848                .global_lsp_settings
 5849                .get_request_timeout();
 5850            let request_task = upstream_client.request_lsp(
 5851                project_id,
 5852                None,
 5853                request_timeout,
 5854                cx.background_executor().clone(),
 5855                request.to_proto(project_id, buffer.read(cx)),
 5856            );
 5857            let buffer = buffer.clone();
 5858            cx.spawn(async move |weak_lsp_store, cx| {
 5859                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5860                    return Ok(None);
 5861                };
 5862                let Some(responses) = request_task.await? else {
 5863                    return Ok(None);
 5864                };
 5865                let actions = join_all(responses.payload.into_iter().map(|response| {
 5866                    GetTypeDefinitions { position }.response_from_proto(
 5867                        response.response,
 5868                        lsp_store.clone(),
 5869                        buffer.clone(),
 5870                        cx.clone(),
 5871                    )
 5872                }))
 5873                .await;
 5874
 5875                Ok(Some(
 5876                    actions
 5877                        .into_iter()
 5878                        .collect::<Result<Vec<Vec<_>>>>()?
 5879                        .into_iter()
 5880                        .flatten()
 5881                        .dedup()
 5882                        .collect(),
 5883                ))
 5884            })
 5885        } else {
 5886            let type_definitions_task = self.request_multiple_lsp_locally(
 5887                buffer,
 5888                Some(position),
 5889                GetTypeDefinitions { position },
 5890                cx,
 5891            );
 5892            cx.background_spawn(async move {
 5893                Ok(Some(
 5894                    type_definitions_task
 5895                        .await
 5896                        .into_iter()
 5897                        .flat_map(|(_, type_definitions)| type_definitions)
 5898                        .dedup()
 5899                        .collect(),
 5900                ))
 5901            })
 5902        }
 5903    }
 5904
 5905    pub fn implementations(
 5906        &mut self,
 5907        buffer: &Entity<Buffer>,
 5908        position: PointUtf16,
 5909        cx: &mut Context<Self>,
 5910    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5911        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5912            let request = GetImplementations { position };
 5913            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5914                return Task::ready(Ok(None));
 5915            }
 5916
 5917            let request_timeout = ProjectSettings::get_global(cx)
 5918                .global_lsp_settings
 5919                .get_request_timeout();
 5920            let request_task = upstream_client.request_lsp(
 5921                project_id,
 5922                None,
 5923                request_timeout,
 5924                cx.background_executor().clone(),
 5925                request.to_proto(project_id, buffer.read(cx)),
 5926            );
 5927            let buffer = buffer.clone();
 5928            cx.spawn(async move |weak_lsp_store, cx| {
 5929                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5930                    return Ok(None);
 5931                };
 5932                let Some(responses) = request_task.await? else {
 5933                    return Ok(None);
 5934                };
 5935                let actions = join_all(responses.payload.into_iter().map(|response| {
 5936                    GetImplementations { position }.response_from_proto(
 5937                        response.response,
 5938                        lsp_store.clone(),
 5939                        buffer.clone(),
 5940                        cx.clone(),
 5941                    )
 5942                }))
 5943                .await;
 5944
 5945                Ok(Some(
 5946                    actions
 5947                        .into_iter()
 5948                        .collect::<Result<Vec<Vec<_>>>>()?
 5949                        .into_iter()
 5950                        .flatten()
 5951                        .dedup()
 5952                        .collect(),
 5953                ))
 5954            })
 5955        } else {
 5956            let implementations_task = self.request_multiple_lsp_locally(
 5957                buffer,
 5958                Some(position),
 5959                GetImplementations { position },
 5960                cx,
 5961            );
 5962            cx.background_spawn(async move {
 5963                Ok(Some(
 5964                    implementations_task
 5965                        .await
 5966                        .into_iter()
 5967                        .flat_map(|(_, implementations)| implementations)
 5968                        .dedup()
 5969                        .collect(),
 5970                ))
 5971            })
 5972        }
 5973    }
 5974
 5975    pub fn references(
 5976        &mut self,
 5977        buffer: &Entity<Buffer>,
 5978        position: PointUtf16,
 5979        cx: &mut Context<Self>,
 5980    ) -> Task<Result<Option<Vec<Location>>>> {
 5981        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5982            let request = GetReferences { position };
 5983            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5984                return Task::ready(Ok(None));
 5985            }
 5986
 5987            let request_timeout = ProjectSettings::get_global(cx)
 5988                .global_lsp_settings
 5989                .get_request_timeout();
 5990            let request_task = upstream_client.request_lsp(
 5991                project_id,
 5992                None,
 5993                request_timeout,
 5994                cx.background_executor().clone(),
 5995                request.to_proto(project_id, buffer.read(cx)),
 5996            );
 5997            let buffer = buffer.clone();
 5998            cx.spawn(async move |weak_lsp_store, cx| {
 5999                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6000                    return Ok(None);
 6001                };
 6002                let Some(responses) = request_task.await? else {
 6003                    return Ok(None);
 6004                };
 6005
 6006                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6007                    GetReferences { position }.response_from_proto(
 6008                        lsp_response.response,
 6009                        lsp_store.clone(),
 6010                        buffer.clone(),
 6011                        cx.clone(),
 6012                    )
 6013                }))
 6014                .await
 6015                .into_iter()
 6016                .collect::<Result<Vec<Vec<_>>>>()?
 6017                .into_iter()
 6018                .flatten()
 6019                .dedup()
 6020                .collect();
 6021                Ok(Some(locations))
 6022            })
 6023        } else {
 6024            let references_task = self.request_multiple_lsp_locally(
 6025                buffer,
 6026                Some(position),
 6027                GetReferences { position },
 6028                cx,
 6029            );
 6030            cx.background_spawn(async move {
 6031                Ok(Some(
 6032                    references_task
 6033                        .await
 6034                        .into_iter()
 6035                        .flat_map(|(_, references)| references)
 6036                        .dedup()
 6037                        .collect(),
 6038                ))
 6039            })
 6040        }
 6041    }
 6042
 6043    pub fn code_actions(
 6044        &mut self,
 6045        buffer: &Entity<Buffer>,
 6046        range: Range<Anchor>,
 6047        kinds: Option<Vec<CodeActionKind>>,
 6048        cx: &mut Context<Self>,
 6049    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6050        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6051            let request = GetCodeActions {
 6052                range: range.clone(),
 6053                kinds: kinds.clone(),
 6054            };
 6055            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6056                return Task::ready(Ok(None));
 6057            }
 6058            let request_timeout = ProjectSettings::get_global(cx)
 6059                .global_lsp_settings
 6060                .get_request_timeout();
 6061            let request_task = upstream_client.request_lsp(
 6062                project_id,
 6063                None,
 6064                request_timeout,
 6065                cx.background_executor().clone(),
 6066                request.to_proto(project_id, buffer.read(cx)),
 6067            );
 6068            let buffer = buffer.clone();
 6069            cx.spawn(async move |weak_lsp_store, cx| {
 6070                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6071                    return Ok(None);
 6072                };
 6073                let Some(responses) = request_task.await? else {
 6074                    return Ok(None);
 6075                };
 6076                let actions = join_all(responses.payload.into_iter().map(|response| {
 6077                    GetCodeActions {
 6078                        range: range.clone(),
 6079                        kinds: kinds.clone(),
 6080                    }
 6081                    .response_from_proto(
 6082                        response.response,
 6083                        lsp_store.clone(),
 6084                        buffer.clone(),
 6085                        cx.clone(),
 6086                    )
 6087                }))
 6088                .await;
 6089
 6090                Ok(Some(
 6091                    actions
 6092                        .into_iter()
 6093                        .collect::<Result<Vec<Vec<_>>>>()?
 6094                        .into_iter()
 6095                        .flatten()
 6096                        .collect(),
 6097                ))
 6098            })
 6099        } else {
 6100            let all_actions_task = self.request_multiple_lsp_locally(
 6101                buffer,
 6102                Some(range.start),
 6103                GetCodeActions { range, kinds },
 6104                cx,
 6105            );
 6106            cx.background_spawn(async move {
 6107                Ok(Some(
 6108                    all_actions_task
 6109                        .await
 6110                        .into_iter()
 6111                        .flat_map(|(_, actions)| actions)
 6112                        .collect(),
 6113                ))
 6114            })
 6115        }
 6116    }
 6117
 6118    #[inline(never)]
 6119    pub fn completions(
 6120        &self,
 6121        buffer: &Entity<Buffer>,
 6122        position: PointUtf16,
 6123        context: CompletionContext,
 6124        cx: &mut Context<Self>,
 6125    ) -> Task<Result<Vec<CompletionResponse>>> {
 6126        let language_registry = self.languages.clone();
 6127
 6128        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6129            let snapshot = buffer.read(cx).snapshot();
 6130            let offset = position.to_offset(&snapshot);
 6131            let scope = snapshot.language_scope_at(offset);
 6132            let capable_lsps = self.all_capable_for_proto_request(
 6133                buffer,
 6134                |server_name, capabilities| {
 6135                    capabilities.completion_provider.is_some()
 6136                        && scope
 6137                            .as_ref()
 6138                            .map(|scope| scope.language_allowed(server_name))
 6139                            .unwrap_or(true)
 6140                },
 6141                cx,
 6142            );
 6143            if capable_lsps.is_empty() {
 6144                return Task::ready(Ok(Vec::new()));
 6145            }
 6146
 6147            let language = buffer.read(cx).language().cloned();
 6148
 6149            let buffer = buffer.clone();
 6150
 6151            cx.spawn(async move |this, cx| {
 6152                let requests = join_all(
 6153                    capable_lsps
 6154                        .into_iter()
 6155                        .map(|(id, server_name)| {
 6156                            let request = GetCompletions {
 6157                                position,
 6158                                context: context.clone(),
 6159                                server_id: Some(id),
 6160                            };
 6161                            let buffer = buffer.clone();
 6162                            let language = language.clone();
 6163                            let lsp_adapter = language.as_ref().and_then(|language| {
 6164                                let adapters = language_registry.lsp_adapters(&language.name());
 6165                                adapters
 6166                                    .iter()
 6167                                    .find(|adapter| adapter.name() == server_name)
 6168                                    .or_else(|| adapters.first())
 6169                                    .cloned()
 6170                            });
 6171                            let upstream_client = upstream_client.clone();
 6172                            let response = this
 6173                                .update(cx, |this, cx| {
 6174                                    this.send_lsp_proto_request(
 6175                                        buffer,
 6176                                        upstream_client,
 6177                                        project_id,
 6178                                        request,
 6179                                        cx,
 6180                                    )
 6181                                })
 6182                                .log_err();
 6183                            async move {
 6184                                let response = response?.await.log_err()?;
 6185
 6186                                let completions = populate_labels_for_completions(
 6187                                    response.completions,
 6188                                    language,
 6189                                    lsp_adapter,
 6190                                )
 6191                                .await;
 6192
 6193                                Some(CompletionResponse {
 6194                                    completions,
 6195                                    display_options: CompletionDisplayOptions::default(),
 6196                                    is_incomplete: response.is_incomplete,
 6197                                })
 6198                            }
 6199                        })
 6200                        .collect::<Vec<_>>(),
 6201                );
 6202                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6203            })
 6204        } else if let Some(local) = self.as_local() {
 6205            let snapshot = buffer.read(cx).snapshot();
 6206            let offset = position.to_offset(&snapshot);
 6207            let scope = snapshot.language_scope_at(offset);
 6208            let language = snapshot.language().cloned();
 6209            let completion_settings = language_settings(
 6210                language.as_ref().map(|language| language.name()),
 6211                buffer.read(cx).file(),
 6212                cx,
 6213            )
 6214            .completions
 6215            .clone();
 6216            if !completion_settings.lsp {
 6217                return Task::ready(Ok(Vec::new()));
 6218            }
 6219
 6220            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6221                local
 6222                    .language_servers_for_buffer(buffer, cx)
 6223                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6224                    .filter(|(adapter, _)| {
 6225                        scope
 6226                            .as_ref()
 6227                            .map(|scope| scope.language_allowed(&adapter.name))
 6228                            .unwrap_or(true)
 6229                    })
 6230                    .map(|(_, server)| server.server_id())
 6231                    .collect()
 6232            });
 6233
 6234            let buffer = buffer.clone();
 6235            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6236            let lsp_timeout = if lsp_timeout > 0 {
 6237                Some(Duration::from_millis(lsp_timeout))
 6238            } else {
 6239                None
 6240            };
 6241            cx.spawn(async move |this,  cx| {
 6242                let mut tasks = Vec::with_capacity(server_ids.len());
 6243                this.update(cx, |lsp_store, cx| {
 6244                    for server_id in server_ids {
 6245                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6246                        let lsp_timeout = lsp_timeout
 6247                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6248                        let mut timeout = cx.background_spawn(async move {
 6249                            match lsp_timeout {
 6250                                Some(lsp_timeout) => {
 6251                                    lsp_timeout.await;
 6252                                    true
 6253                                },
 6254                                None => false,
 6255                            }
 6256                        }).fuse();
 6257                        let mut lsp_request = lsp_store.request_lsp(
 6258                            buffer.clone(),
 6259                            LanguageServerToQuery::Other(server_id),
 6260                            GetCompletions {
 6261                                position,
 6262                                context: context.clone(),
 6263                                server_id: Some(server_id),
 6264                            },
 6265                            cx,
 6266                        ).fuse();
 6267                        let new_task = cx.background_spawn(async move {
 6268                            select_biased! {
 6269                                response = lsp_request => anyhow::Ok(Some(response?)),
 6270                                timeout_happened = timeout => {
 6271                                    if timeout_happened {
 6272                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6273                                        Ok(None)
 6274                                    } else {
 6275                                        let completions = lsp_request.await?;
 6276                                        Ok(Some(completions))
 6277                                    }
 6278                                },
 6279                            }
 6280                        });
 6281                        tasks.push((lsp_adapter, new_task));
 6282                    }
 6283                })?;
 6284
 6285                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6286                    let completion_response = task.await.ok()??;
 6287                    let completions = populate_labels_for_completions(
 6288                            completion_response.completions,
 6289                            language.clone(),
 6290                            lsp_adapter,
 6291                        )
 6292                        .await;
 6293                    Some(CompletionResponse {
 6294                        completions,
 6295                        display_options: CompletionDisplayOptions::default(),
 6296                        is_incomplete: completion_response.is_incomplete,
 6297                    })
 6298                });
 6299
 6300                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6301
 6302                Ok(responses.into_iter().flatten().collect())
 6303            })
 6304        } else {
 6305            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6306        }
 6307    }
 6308
 6309    pub fn resolve_completions(
 6310        &self,
 6311        buffer: Entity<Buffer>,
 6312        completion_indices: Vec<usize>,
 6313        completions: Rc<RefCell<Box<[Completion]>>>,
 6314        cx: &mut Context<Self>,
 6315    ) -> Task<Result<bool>> {
 6316        let client = self.upstream_client();
 6317        let buffer_id = buffer.read(cx).remote_id();
 6318        let buffer_snapshot = buffer.read(cx).snapshot();
 6319
 6320        if !self.check_if_capable_for_proto_request(
 6321            &buffer,
 6322            GetCompletions::can_resolve_completions,
 6323            cx,
 6324        ) {
 6325            return Task::ready(Ok(false));
 6326        }
 6327        cx.spawn(async move |lsp_store, cx| {
 6328            let request_timeout = cx.update(|app| {
 6329                ProjectSettings::get_global(app)
 6330                    .global_lsp_settings
 6331                    .get_request_timeout()
 6332            });
 6333
 6334            let mut did_resolve = false;
 6335            if let Some((client, project_id)) = client {
 6336                for completion_index in completion_indices {
 6337                    let server_id = {
 6338                        let completion = &completions.borrow()[completion_index];
 6339                        completion.source.server_id()
 6340                    };
 6341                    if let Some(server_id) = server_id {
 6342                        if Self::resolve_completion_remote(
 6343                            project_id,
 6344                            server_id,
 6345                            buffer_id,
 6346                            completions.clone(),
 6347                            completion_index,
 6348                            client.clone(),
 6349                        )
 6350                        .await
 6351                        .log_err()
 6352                        .is_some()
 6353                        {
 6354                            did_resolve = true;
 6355                        }
 6356                    } else {
 6357                        resolve_word_completion(
 6358                            &buffer_snapshot,
 6359                            &mut completions.borrow_mut()[completion_index],
 6360                        );
 6361                    }
 6362                }
 6363            } else {
 6364                for completion_index in completion_indices {
 6365                    let server_id = {
 6366                        let completion = &completions.borrow()[completion_index];
 6367                        completion.source.server_id()
 6368                    };
 6369                    if let Some(server_id) = server_id {
 6370                        let server_and_adapter = lsp_store
 6371                            .read_with(cx, |lsp_store, _| {
 6372                                let server = lsp_store.language_server_for_id(server_id)?;
 6373                                let adapter =
 6374                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6375                                Some((server, adapter))
 6376                            })
 6377                            .ok()
 6378                            .flatten();
 6379                        let Some((server, adapter)) = server_and_adapter else {
 6380                            continue;
 6381                        };
 6382
 6383                        let resolved = Self::resolve_completion_local(
 6384                            server,
 6385                            completions.clone(),
 6386                            completion_index,
 6387                            request_timeout,
 6388                        )
 6389                        .await
 6390                        .log_err()
 6391                        .is_some();
 6392                        if resolved {
 6393                            Self::regenerate_completion_labels(
 6394                                adapter,
 6395                                &buffer_snapshot,
 6396                                completions.clone(),
 6397                                completion_index,
 6398                            )
 6399                            .await
 6400                            .log_err();
 6401                            did_resolve = true;
 6402                        }
 6403                    } else {
 6404                        resolve_word_completion(
 6405                            &buffer_snapshot,
 6406                            &mut completions.borrow_mut()[completion_index],
 6407                        );
 6408                    }
 6409                }
 6410            }
 6411
 6412            Ok(did_resolve)
 6413        })
 6414    }
 6415
 6416    async fn resolve_completion_local(
 6417        server: Arc<lsp::LanguageServer>,
 6418        completions: Rc<RefCell<Box<[Completion]>>>,
 6419        completion_index: usize,
 6420        request_timeout: Duration,
 6421    ) -> Result<()> {
 6422        let server_id = server.server_id();
 6423        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6424            return Ok(());
 6425        }
 6426
 6427        let request = {
 6428            let completion = &completions.borrow()[completion_index];
 6429            match &completion.source {
 6430                CompletionSource::Lsp {
 6431                    lsp_completion,
 6432                    resolved,
 6433                    server_id: completion_server_id,
 6434                    ..
 6435                } => {
 6436                    if *resolved {
 6437                        return Ok(());
 6438                    }
 6439                    anyhow::ensure!(
 6440                        server_id == *completion_server_id,
 6441                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6442                    );
 6443                    server.request::<lsp::request::ResolveCompletionItem>(
 6444                        *lsp_completion.clone(),
 6445                        request_timeout,
 6446                    )
 6447                }
 6448                CompletionSource::BufferWord { .. }
 6449                | CompletionSource::Dap { .. }
 6450                | CompletionSource::Custom => {
 6451                    return Ok(());
 6452                }
 6453            }
 6454        };
 6455        let resolved_completion = request
 6456            .await
 6457            .into_response()
 6458            .context("resolve completion")?;
 6459
 6460        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6461        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6462
 6463        let mut completions = completions.borrow_mut();
 6464        let completion = &mut completions[completion_index];
 6465        if let CompletionSource::Lsp {
 6466            lsp_completion,
 6467            resolved,
 6468            server_id: completion_server_id,
 6469            ..
 6470        } = &mut completion.source
 6471        {
 6472            if *resolved {
 6473                return Ok(());
 6474            }
 6475            anyhow::ensure!(
 6476                server_id == *completion_server_id,
 6477                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6478            );
 6479            **lsp_completion = resolved_completion;
 6480            *resolved = true;
 6481        }
 6482        Ok(())
 6483    }
 6484
 6485    async fn regenerate_completion_labels(
 6486        adapter: Arc<CachedLspAdapter>,
 6487        snapshot: &BufferSnapshot,
 6488        completions: Rc<RefCell<Box<[Completion]>>>,
 6489        completion_index: usize,
 6490    ) -> Result<()> {
 6491        let completion_item = completions.borrow()[completion_index]
 6492            .source
 6493            .lsp_completion(true)
 6494            .map(Cow::into_owned);
 6495        if let Some(lsp_documentation) = completion_item
 6496            .as_ref()
 6497            .and_then(|completion_item| completion_item.documentation.clone())
 6498        {
 6499            let mut completions = completions.borrow_mut();
 6500            let completion = &mut completions[completion_index];
 6501            completion.documentation = Some(lsp_documentation.into());
 6502        } else {
 6503            let mut completions = completions.borrow_mut();
 6504            let completion = &mut completions[completion_index];
 6505            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6506        }
 6507
 6508        let mut new_label = match completion_item {
 6509            Some(completion_item) => {
 6510                // Some language servers always return `detail` lazily via resolve, regardless of
 6511                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6512                // See: https://github.com/yioneko/vtsls/issues/213
 6513                let language = snapshot.language();
 6514                match language {
 6515                    Some(language) => {
 6516                        adapter
 6517                            .labels_for_completions(
 6518                                std::slice::from_ref(&completion_item),
 6519                                language,
 6520                            )
 6521                            .await?
 6522                    }
 6523                    None => Vec::new(),
 6524                }
 6525                .pop()
 6526                .flatten()
 6527                .unwrap_or_else(|| {
 6528                    CodeLabel::fallback_for_completion(
 6529                        &completion_item,
 6530                        language.map(|language| language.as_ref()),
 6531                    )
 6532                })
 6533            }
 6534            None => CodeLabel::plain(
 6535                completions.borrow()[completion_index].new_text.clone(),
 6536                None,
 6537            ),
 6538        };
 6539        ensure_uniform_list_compatible_label(&mut new_label);
 6540
 6541        let mut completions = completions.borrow_mut();
 6542        let completion = &mut completions[completion_index];
 6543        if completion.label.filter_text() == new_label.filter_text() {
 6544            completion.label = new_label;
 6545        } else {
 6546            log::error!(
 6547                "Resolved completion changed display label from {} to {}. \
 6548                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6549                completion.label.text(),
 6550                new_label.text(),
 6551                completion.label.filter_text(),
 6552                new_label.filter_text()
 6553            );
 6554        }
 6555
 6556        Ok(())
 6557    }
 6558
 6559    async fn resolve_completion_remote(
 6560        project_id: u64,
 6561        server_id: LanguageServerId,
 6562        buffer_id: BufferId,
 6563        completions: Rc<RefCell<Box<[Completion]>>>,
 6564        completion_index: usize,
 6565        client: AnyProtoClient,
 6566    ) -> Result<()> {
 6567        let lsp_completion = {
 6568            let completion = &completions.borrow()[completion_index];
 6569            match &completion.source {
 6570                CompletionSource::Lsp {
 6571                    lsp_completion,
 6572                    resolved,
 6573                    server_id: completion_server_id,
 6574                    ..
 6575                } => {
 6576                    anyhow::ensure!(
 6577                        server_id == *completion_server_id,
 6578                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6579                    );
 6580                    if *resolved {
 6581                        return Ok(());
 6582                    }
 6583                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6584                }
 6585                CompletionSource::Custom
 6586                | CompletionSource::Dap { .. }
 6587                | CompletionSource::BufferWord { .. } => {
 6588                    return Ok(());
 6589                }
 6590            }
 6591        };
 6592        let request = proto::ResolveCompletionDocumentation {
 6593            project_id,
 6594            language_server_id: server_id.0 as u64,
 6595            lsp_completion,
 6596            buffer_id: buffer_id.into(),
 6597        };
 6598
 6599        let response = client
 6600            .request(request)
 6601            .await
 6602            .context("completion documentation resolve proto request")?;
 6603        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6604
 6605        let documentation = if response.documentation.is_empty() {
 6606            CompletionDocumentation::Undocumented
 6607        } else if response.documentation_is_markdown {
 6608            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6609        } else if response.documentation.lines().count() <= 1 {
 6610            CompletionDocumentation::SingleLine(response.documentation.into())
 6611        } else {
 6612            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6613        };
 6614
 6615        let mut completions = completions.borrow_mut();
 6616        let completion = &mut completions[completion_index];
 6617        completion.documentation = Some(documentation);
 6618        if let CompletionSource::Lsp {
 6619            insert_range,
 6620            lsp_completion,
 6621            resolved,
 6622            server_id: completion_server_id,
 6623            lsp_defaults: _,
 6624        } = &mut completion.source
 6625        {
 6626            let completion_insert_range = response
 6627                .old_insert_start
 6628                .and_then(deserialize_anchor)
 6629                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6630            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6631
 6632            if *resolved {
 6633                return Ok(());
 6634            }
 6635            anyhow::ensure!(
 6636                server_id == *completion_server_id,
 6637                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6638            );
 6639            **lsp_completion = resolved_lsp_completion;
 6640            *resolved = true;
 6641        }
 6642
 6643        let replace_range = response
 6644            .old_replace_start
 6645            .and_then(deserialize_anchor)
 6646            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6647        if let Some((old_replace_start, old_replace_end)) = replace_range
 6648            && !response.new_text.is_empty()
 6649        {
 6650            completion.new_text = response.new_text;
 6651            completion.replace_range = old_replace_start..old_replace_end;
 6652        }
 6653
 6654        Ok(())
 6655    }
 6656
 6657    pub fn apply_additional_edits_for_completion(
 6658        &self,
 6659        buffer_handle: Entity<Buffer>,
 6660        completions: Rc<RefCell<Box<[Completion]>>>,
 6661        completion_index: usize,
 6662        push_to_history: bool,
 6663        all_commit_ranges: Vec<Range<language::Anchor>>,
 6664        cx: &mut Context<Self>,
 6665    ) -> Task<Result<Option<Transaction>>> {
 6666        if let Some((client, project_id)) = self.upstream_client() {
 6667            let buffer = buffer_handle.read(cx);
 6668            let buffer_id = buffer.remote_id();
 6669            cx.spawn(async move |_, cx| {
 6670                let request = {
 6671                    let completion = completions.borrow()[completion_index].clone();
 6672                    proto::ApplyCompletionAdditionalEdits {
 6673                        project_id,
 6674                        buffer_id: buffer_id.into(),
 6675                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6676                            replace_range: completion.replace_range,
 6677                            new_text: completion.new_text,
 6678                            source: completion.source,
 6679                        })),
 6680                        all_commit_ranges: all_commit_ranges
 6681                            .iter()
 6682                            .cloned()
 6683                            .map(language::proto::serialize_anchor_range)
 6684                            .collect(),
 6685                    }
 6686                };
 6687
 6688                let Some(transaction) = client.request(request).await?.transaction else {
 6689                    return Ok(None);
 6690                };
 6691
 6692                let transaction = language::proto::deserialize_transaction(transaction)?;
 6693                buffer_handle
 6694                    .update(cx, |buffer, _| {
 6695                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6696                    })
 6697                    .await?;
 6698                if push_to_history {
 6699                    buffer_handle.update(cx, |buffer, _| {
 6700                        buffer.push_transaction(transaction.clone(), Instant::now());
 6701                        buffer.finalize_last_transaction();
 6702                    });
 6703                }
 6704                Ok(Some(transaction))
 6705            })
 6706        } else {
 6707            let request_timeout = ProjectSettings::get_global(cx)
 6708                .global_lsp_settings
 6709                .get_request_timeout();
 6710
 6711            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6712                let completion = &completions.borrow()[completion_index];
 6713                let server_id = completion.source.server_id()?;
 6714                Some(
 6715                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6716                        .1
 6717                        .clone(),
 6718                )
 6719            }) else {
 6720                return Task::ready(Ok(None));
 6721            };
 6722
 6723            cx.spawn(async move |this, cx| {
 6724                Self::resolve_completion_local(
 6725                    server.clone(),
 6726                    completions.clone(),
 6727                    completion_index,
 6728                    request_timeout,
 6729                )
 6730                .await
 6731                .context("resolving completion")?;
 6732                let completion = completions.borrow()[completion_index].clone();
 6733                let additional_text_edits = completion
 6734                    .source
 6735                    .lsp_completion(true)
 6736                    .as_ref()
 6737                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6738                if let Some(edits) = additional_text_edits {
 6739                    let edits = this
 6740                        .update(cx, |this, cx| {
 6741                            this.as_local_mut().unwrap().edits_from_lsp(
 6742                                &buffer_handle,
 6743                                edits,
 6744                                server.server_id(),
 6745                                None,
 6746                                cx,
 6747                            )
 6748                        })?
 6749                        .await?;
 6750
 6751                    buffer_handle.update(cx, |buffer, cx| {
 6752                        buffer.finalize_last_transaction();
 6753                        buffer.start_transaction();
 6754
 6755                        for (range, text) in edits {
 6756                            let primary = &completion.replace_range;
 6757
 6758                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6759                            // and the primary completion is just an insertion (empty range), then this is likely
 6760                            // an auto-import scenario and should not be considered overlapping
 6761                            // https://github.com/zed-industries/zed/issues/26136
 6762                            let is_file_start_auto_import = {
 6763                                let snapshot = buffer.snapshot();
 6764                                let primary_start_point = primary.start.to_point(&snapshot);
 6765                                let range_start_point = range.start.to_point(&snapshot);
 6766
 6767                                let result = primary_start_point.row == 0
 6768                                    && primary_start_point.column == 0
 6769                                    && range_start_point.row == 0
 6770                                    && range_start_point.column == 0;
 6771
 6772                                result
 6773                            };
 6774
 6775                            let has_overlap = if is_file_start_auto_import {
 6776                                false
 6777                            } else {
 6778                                all_commit_ranges.iter().any(|commit_range| {
 6779                                    let start_within =
 6780                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6781                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6782                                    let end_within =
 6783                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6784                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6785                                    start_within || end_within
 6786                                })
 6787                            };
 6788
 6789                            //Skip additional edits which overlap with the primary completion edit
 6790                            //https://github.com/zed-industries/zed/pull/1871
 6791                            if !has_overlap {
 6792                                buffer.edit([(range, text)], None, cx);
 6793                            }
 6794                        }
 6795
 6796                        let transaction = if buffer.end_transaction(cx).is_some() {
 6797                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6798                            if !push_to_history {
 6799                                buffer.forget_transaction(transaction.id);
 6800                            }
 6801                            Some(transaction)
 6802                        } else {
 6803                            None
 6804                        };
 6805                        Ok(transaction)
 6806                    })
 6807                } else {
 6808                    Ok(None)
 6809                }
 6810            })
 6811        }
 6812    }
 6813
 6814    pub fn pull_diagnostics(
 6815        &mut self,
 6816        buffer: Entity<Buffer>,
 6817        cx: &mut Context<Self>,
 6818    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6819        let buffer_id = buffer.read(cx).remote_id();
 6820
 6821        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6822            let mut suitable_capabilities = None;
 6823            // Are we capable for proto request?
 6824            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6825                &buffer,
 6826                |capabilities| {
 6827                    if let Some(caps) = &capabilities.diagnostic_provider {
 6828                        suitable_capabilities = Some(caps.clone());
 6829                        true
 6830                    } else {
 6831                        false
 6832                    }
 6833                },
 6834                cx,
 6835            );
 6836            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6837            let Some(dynamic_caps) = suitable_capabilities else {
 6838                return Task::ready(Ok(None));
 6839            };
 6840            assert!(any_server_has_diagnostics_provider);
 6841
 6842            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6843            let request = GetDocumentDiagnostics {
 6844                previous_result_id: None,
 6845                identifier,
 6846                registration_id: None,
 6847            };
 6848            let request_timeout = ProjectSettings::get_global(cx)
 6849                .global_lsp_settings
 6850                .get_request_timeout();
 6851            let request_task = client.request_lsp(
 6852                upstream_project_id,
 6853                None,
 6854                request_timeout,
 6855                cx.background_executor().clone(),
 6856                request.to_proto(upstream_project_id, buffer.read(cx)),
 6857            );
 6858            cx.background_spawn(async move {
 6859                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6860                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6861                // Do not attempt to further process the dummy responses here.
 6862                let _response = request_task.await?;
 6863                Ok(None)
 6864            })
 6865        } else {
 6866            let servers = buffer.update(cx, |buffer, cx| {
 6867                self.running_language_servers_for_local_buffer(buffer, cx)
 6868                    .map(|(_, server)| server.clone())
 6869                    .collect::<Vec<_>>()
 6870            });
 6871
 6872            let pull_diagnostics = servers
 6873                .into_iter()
 6874                .flat_map(|server| {
 6875                    let result = maybe!({
 6876                        let local = self.as_local()?;
 6877                        let server_id = server.server_id();
 6878                        let providers_with_identifiers = local
 6879                            .language_server_dynamic_registrations
 6880                            .get(&server_id)
 6881                            .into_iter()
 6882                            .flat_map(|registrations| registrations.diagnostics.clone())
 6883                            .collect::<Vec<_>>();
 6884                        Some(
 6885                            providers_with_identifiers
 6886                                .into_iter()
 6887                                .map(|(registration_id, dynamic_caps)| {
 6888                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6889                                    let registration_id = registration_id.map(SharedString::from);
 6890                                    let result_id = self.result_id_for_buffer_pull(
 6891                                        server_id,
 6892                                        buffer_id,
 6893                                        &registration_id,
 6894                                        cx,
 6895                                    );
 6896                                    self.request_lsp(
 6897                                        buffer.clone(),
 6898                                        LanguageServerToQuery::Other(server_id),
 6899                                        GetDocumentDiagnostics {
 6900                                            previous_result_id: result_id,
 6901                                            registration_id,
 6902                                            identifier,
 6903                                        },
 6904                                        cx,
 6905                                    )
 6906                                })
 6907                                .collect::<Vec<_>>(),
 6908                        )
 6909                    });
 6910
 6911                    result.unwrap_or_default()
 6912                })
 6913                .collect::<Vec<_>>();
 6914
 6915            cx.background_spawn(async move {
 6916                let mut responses = Vec::new();
 6917                for diagnostics in join_all(pull_diagnostics).await {
 6918                    responses.extend(diagnostics?);
 6919                }
 6920                Ok(Some(responses))
 6921            })
 6922        }
 6923    }
 6924
 6925    pub fn applicable_inlay_chunks(
 6926        &mut self,
 6927        buffer: &Entity<Buffer>,
 6928        ranges: &[Range<text::Anchor>],
 6929        cx: &mut Context<Self>,
 6930    ) -> Vec<Range<BufferRow>> {
 6931        let buffer_snapshot = buffer.read(cx).snapshot();
 6932        let ranges = ranges
 6933            .iter()
 6934            .map(|range| range.to_point(&buffer_snapshot))
 6935            .collect::<Vec<_>>();
 6936
 6937        self.latest_lsp_data(buffer, cx)
 6938            .inlay_hints
 6939            .applicable_chunks(ranges.as_slice())
 6940            .map(|chunk| chunk.row_range())
 6941            .collect()
 6942    }
 6943
 6944    pub fn invalidate_inlay_hints<'a>(
 6945        &'a mut self,
 6946        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6947    ) {
 6948        for buffer_id in for_buffers {
 6949            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6950                lsp_data.inlay_hints.clear();
 6951            }
 6952        }
 6953    }
 6954
 6955    pub fn inlay_hints(
 6956        &mut self,
 6957        invalidate: InvalidationStrategy,
 6958        buffer: Entity<Buffer>,
 6959        ranges: Vec<Range<text::Anchor>>,
 6960        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6961        cx: &mut Context<Self>,
 6962    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6963        let next_hint_id = self.next_hint_id.clone();
 6964        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6965        let query_version = lsp_data.buffer_version.clone();
 6966        let mut lsp_refresh_requested = false;
 6967        let for_server = if let InvalidationStrategy::RefreshRequested {
 6968            server_id,
 6969            request_id,
 6970        } = invalidate
 6971        {
 6972            let invalidated = lsp_data
 6973                .inlay_hints
 6974                .invalidate_for_server_refresh(server_id, request_id);
 6975            lsp_refresh_requested = invalidated;
 6976            Some(server_id)
 6977        } else {
 6978            None
 6979        };
 6980        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6981        let known_chunks = known_chunks
 6982            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6983            .map(|(_, known_chunks)| known_chunks)
 6984            .unwrap_or_default();
 6985
 6986        let buffer_snapshot = buffer.read(cx).snapshot();
 6987        let ranges = ranges
 6988            .iter()
 6989            .map(|range| range.to_point(&buffer_snapshot))
 6990            .collect::<Vec<_>>();
 6991
 6992        let mut hint_fetch_tasks = Vec::new();
 6993        let mut cached_inlay_hints = None;
 6994        let mut ranges_to_query = None;
 6995        let applicable_chunks = existing_inlay_hints
 6996            .applicable_chunks(ranges.as_slice())
 6997            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6998            .collect::<Vec<_>>();
 6999        if applicable_chunks.is_empty() {
 7000            return HashMap::default();
 7001        }
 7002
 7003        for row_chunk in applicable_chunks {
 7004            match (
 7005                existing_inlay_hints
 7006                    .cached_hints(&row_chunk)
 7007                    .filter(|_| !lsp_refresh_requested)
 7008                    .cloned(),
 7009                existing_inlay_hints
 7010                    .fetched_hints(&row_chunk)
 7011                    .as_ref()
 7012                    .filter(|_| !lsp_refresh_requested)
 7013                    .cloned(),
 7014            ) {
 7015                (None, None) => {
 7016                    let chunk_range = row_chunk.anchor_range();
 7017                    ranges_to_query
 7018                        .get_or_insert_with(Vec::new)
 7019                        .push((row_chunk, chunk_range));
 7020                }
 7021                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7022                (Some(cached_hints), None) => {
 7023                    for (server_id, cached_hints) in cached_hints {
 7024                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7025                            cached_inlay_hints
 7026                                .get_or_insert_with(HashMap::default)
 7027                                .entry(row_chunk.row_range())
 7028                                .or_insert_with(HashMap::default)
 7029                                .entry(server_id)
 7030                                .or_insert_with(Vec::new)
 7031                                .extend(cached_hints);
 7032                        }
 7033                    }
 7034                }
 7035                (Some(cached_hints), Some(fetched_hints)) => {
 7036                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7037                    for (server_id, cached_hints) in cached_hints {
 7038                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7039                            cached_inlay_hints
 7040                                .get_or_insert_with(HashMap::default)
 7041                                .entry(row_chunk.row_range())
 7042                                .or_insert_with(HashMap::default)
 7043                                .entry(server_id)
 7044                                .or_insert_with(Vec::new)
 7045                                .extend(cached_hints);
 7046                        }
 7047                    }
 7048                }
 7049            }
 7050        }
 7051
 7052        if hint_fetch_tasks.is_empty()
 7053            && ranges_to_query
 7054                .as_ref()
 7055                .is_none_or(|ranges| ranges.is_empty())
 7056            && let Some(cached_inlay_hints) = cached_inlay_hints
 7057        {
 7058            cached_inlay_hints
 7059                .into_iter()
 7060                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7061                .collect()
 7062        } else {
 7063            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7064                // When a server refresh was requested, other servers' cached hints
 7065                // are unaffected by the refresh and must be included in the result.
 7066                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7067                // removes all visible hints but only adds back the requesting
 7068                // server's new hints, permanently losing other servers' hints.
 7069                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7070                    lsp_data
 7071                        .inlay_hints
 7072                        .cached_hints(&chunk)
 7073                        .cloned()
 7074                        .unwrap_or_default()
 7075                } else {
 7076                    HashMap::default()
 7077                };
 7078
 7079                let next_hint_id = next_hint_id.clone();
 7080                let buffer = buffer.clone();
 7081                let query_version = query_version.clone();
 7082                let new_inlay_hints = cx
 7083                    .spawn(async move |lsp_store, cx| {
 7084                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7085                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7086                        })?;
 7087                        new_fetch_task
 7088                            .await
 7089                            .and_then(|new_hints_by_server| {
 7090                                lsp_store.update(cx, |lsp_store, cx| {
 7091                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7092                                    let update_cache = lsp_data.buffer_version == query_version;
 7093                                    if new_hints_by_server.is_empty() {
 7094                                        if update_cache {
 7095                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7096                                        }
 7097                                        other_servers_cached
 7098                                    } else {
 7099                                        let mut result = other_servers_cached;
 7100                                        for (server_id, new_hints) in new_hints_by_server {
 7101                                            let new_hints = new_hints
 7102                                                .into_iter()
 7103                                                .map(|new_hint| {
 7104                                                    (
 7105                                                        InlayId::Hint(next_hint_id.fetch_add(
 7106                                                            1,
 7107                                                            atomic::Ordering::AcqRel,
 7108                                                        )),
 7109                                                        new_hint,
 7110                                                    )
 7111                                                })
 7112                                                .collect::<Vec<_>>();
 7113                                            if update_cache {
 7114                                                lsp_data.inlay_hints.insert_new_hints(
 7115                                                    chunk,
 7116                                                    server_id,
 7117                                                    new_hints.clone(),
 7118                                                );
 7119                                            }
 7120                                            result.insert(server_id, new_hints);
 7121                                        }
 7122                                        result
 7123                                    }
 7124                                })
 7125                            })
 7126                            .map_err(Arc::new)
 7127                    })
 7128                    .shared();
 7129
 7130                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7131                *fetch_task = Some(new_inlay_hints.clone());
 7132                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7133            }
 7134
 7135            cached_inlay_hints
 7136                .unwrap_or_default()
 7137                .into_iter()
 7138                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7139                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7140                    (
 7141                        chunk.row_range(),
 7142                        cx.spawn(async move |_, _| {
 7143                            hints_fetch.await.map_err(|e| {
 7144                                if e.error_code() != ErrorCode::Internal {
 7145                                    anyhow!(e.error_code())
 7146                                } else {
 7147                                    anyhow!("{e:#}")
 7148                                }
 7149                            })
 7150                        }),
 7151                    )
 7152                }))
 7153                .collect()
 7154        }
 7155    }
 7156
 7157    fn fetch_inlay_hints(
 7158        &mut self,
 7159        for_server: Option<LanguageServerId>,
 7160        buffer: &Entity<Buffer>,
 7161        range: Range<Anchor>,
 7162        cx: &mut Context<Self>,
 7163    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7164        let request = InlayHints {
 7165            range: range.clone(),
 7166        };
 7167        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7168            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7169                return Task::ready(Ok(HashMap::default()));
 7170            }
 7171            let request_timeout = ProjectSettings::get_global(cx)
 7172                .global_lsp_settings
 7173                .get_request_timeout();
 7174            let request_task = upstream_client.request_lsp(
 7175                project_id,
 7176                for_server.map(|id| id.to_proto()),
 7177                request_timeout,
 7178                cx.background_executor().clone(),
 7179                request.to_proto(project_id, buffer.read(cx)),
 7180            );
 7181            let buffer = buffer.clone();
 7182            cx.spawn(async move |weak_lsp_store, cx| {
 7183                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7184                    return Ok(HashMap::default());
 7185                };
 7186                let Some(responses) = request_task.await? else {
 7187                    return Ok(HashMap::default());
 7188                };
 7189
 7190                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7191                    let lsp_store = lsp_store.clone();
 7192                    let buffer = buffer.clone();
 7193                    let cx = cx.clone();
 7194                    let request = request.clone();
 7195                    async move {
 7196                        (
 7197                            LanguageServerId::from_proto(response.server_id),
 7198                            request
 7199                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7200                                .await,
 7201                        )
 7202                    }
 7203                }))
 7204                .await;
 7205
 7206                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7207                let mut has_errors = false;
 7208                let inlay_hints = inlay_hints
 7209                    .into_iter()
 7210                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7211                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7212                        Err(e) => {
 7213                            has_errors = true;
 7214                            log::error!("{e:#}");
 7215                            None
 7216                        }
 7217                    })
 7218                    .map(|(server_id, mut new_hints)| {
 7219                        new_hints.retain(|hint| {
 7220                            hint.position.is_valid(&buffer_snapshot)
 7221                                && range.start.is_valid(&buffer_snapshot)
 7222                                && range.end.is_valid(&buffer_snapshot)
 7223                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7224                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7225                        });
 7226                        (server_id, new_hints)
 7227                    })
 7228                    .collect::<HashMap<_, _>>();
 7229                anyhow::ensure!(
 7230                    !has_errors || !inlay_hints.is_empty(),
 7231                    "Failed to fetch inlay hints"
 7232                );
 7233                Ok(inlay_hints)
 7234            })
 7235        } else {
 7236            let inlay_hints_task = match for_server {
 7237                Some(server_id) => {
 7238                    let server_task = self.request_lsp(
 7239                        buffer.clone(),
 7240                        LanguageServerToQuery::Other(server_id),
 7241                        request,
 7242                        cx,
 7243                    );
 7244                    cx.background_spawn(async move {
 7245                        let mut responses = Vec::new();
 7246                        match server_task.await {
 7247                            Ok(response) => responses.push((server_id, response)),
 7248                            // rust-analyzer likes to error with this when its still loading up
 7249                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7250                            Err(e) => log::error!(
 7251                                "Error handling response for inlay hints request: {e:#}"
 7252                            ),
 7253                        }
 7254                        responses
 7255                    })
 7256                }
 7257                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7258            };
 7259            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7260            cx.background_spawn(async move {
 7261                Ok(inlay_hints_task
 7262                    .await
 7263                    .into_iter()
 7264                    .map(|(server_id, mut new_hints)| {
 7265                        new_hints.retain(|hint| {
 7266                            hint.position.is_valid(&buffer_snapshot)
 7267                                && range.start.is_valid(&buffer_snapshot)
 7268                                && range.end.is_valid(&buffer_snapshot)
 7269                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7270                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7271                        });
 7272                        (server_id, new_hints)
 7273                    })
 7274                    .collect())
 7275            })
 7276        }
 7277    }
 7278
 7279    fn diagnostic_registration_exists(
 7280        &self,
 7281        server_id: LanguageServerId,
 7282        registration_id: &Option<SharedString>,
 7283    ) -> bool {
 7284        let Some(local) = self.as_local() else {
 7285            return false;
 7286        };
 7287        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7288        else {
 7289            return false;
 7290        };
 7291        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7292        registrations.diagnostics.contains_key(&registration_key)
 7293    }
 7294
 7295    pub fn pull_diagnostics_for_buffer(
 7296        &mut self,
 7297        buffer: Entity<Buffer>,
 7298        cx: &mut Context<Self>,
 7299    ) -> Task<anyhow::Result<()>> {
 7300        let diagnostics = self.pull_diagnostics(buffer, cx);
 7301        cx.spawn(async move |lsp_store, cx| {
 7302            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7303                return Ok(());
 7304            };
 7305            lsp_store.update(cx, |lsp_store, cx| {
 7306                if lsp_store.as_local().is_none() {
 7307                    return;
 7308                }
 7309
 7310                let mut unchanged_buffers = HashMap::default();
 7311                let server_diagnostics_updates = diagnostics
 7312                    .into_iter()
 7313                    .filter_map(|diagnostics_set| match diagnostics_set {
 7314                        LspPullDiagnostics::Response {
 7315                            server_id,
 7316                            uri,
 7317                            diagnostics,
 7318                            registration_id,
 7319                        } => Some((server_id, uri, diagnostics, registration_id)),
 7320                        LspPullDiagnostics::Default => None,
 7321                    })
 7322                    .filter(|(server_id, _, _, registration_id)| {
 7323                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7324                    })
 7325                    .fold(
 7326                        HashMap::default(),
 7327                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7328                            let (result_id, diagnostics) = match diagnostics {
 7329                                PulledDiagnostics::Unchanged { result_id } => {
 7330                                    unchanged_buffers
 7331                                        .entry(new_registration_id.clone())
 7332                                        .or_insert_with(HashSet::default)
 7333                                        .insert(uri.clone());
 7334                                    (Some(result_id), Vec::new())
 7335                                }
 7336                                PulledDiagnostics::Changed {
 7337                                    result_id,
 7338                                    diagnostics,
 7339                                } => (result_id, diagnostics),
 7340                            };
 7341                            let disk_based_sources = Cow::Owned(
 7342                                lsp_store
 7343                                    .language_server_adapter_for_id(server_id)
 7344                                    .as_ref()
 7345                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7346                                    .unwrap_or(&[])
 7347                                    .to_vec(),
 7348                            );
 7349                            acc.entry(server_id)
 7350                                .or_insert_with(HashMap::default)
 7351                                .entry(new_registration_id.clone())
 7352                                .or_insert_with(Vec::new)
 7353                                .push(DocumentDiagnosticsUpdate {
 7354                                    server_id,
 7355                                    diagnostics: lsp::PublishDiagnosticsParams {
 7356                                        uri,
 7357                                        diagnostics,
 7358                                        version: None,
 7359                                    },
 7360                                    result_id: result_id.map(SharedString::new),
 7361                                    disk_based_sources,
 7362                                    registration_id: new_registration_id,
 7363                                });
 7364                            acc
 7365                        },
 7366                    );
 7367
 7368                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7369                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7370                        lsp_store
 7371                            .merge_lsp_diagnostics(
 7372                                DiagnosticSourceKind::Pulled,
 7373                                diagnostic_updates,
 7374                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7375                                    DiagnosticSourceKind::Pulled => {
 7376                                        old_diagnostic.registration_id != registration_id
 7377                                            || unchanged_buffers
 7378                                                .get(&old_diagnostic.registration_id)
 7379                                                .is_some_and(|unchanged_buffers| {
 7380                                                    unchanged_buffers.contains(&document_uri)
 7381                                                })
 7382                                    }
 7383                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7384                                        true
 7385                                    }
 7386                                },
 7387                                cx,
 7388                            )
 7389                            .log_err();
 7390                    }
 7391                }
 7392            })
 7393        })
 7394    }
 7395
 7396    pub fn signature_help<T: ToPointUtf16>(
 7397        &mut self,
 7398        buffer: &Entity<Buffer>,
 7399        position: T,
 7400        cx: &mut Context<Self>,
 7401    ) -> Task<Option<Vec<SignatureHelp>>> {
 7402        let position = position.to_point_utf16(buffer.read(cx));
 7403
 7404        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7405            let request = GetSignatureHelp { position };
 7406            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7407                return Task::ready(None);
 7408            }
 7409            let request_timeout = ProjectSettings::get_global(cx)
 7410                .global_lsp_settings
 7411                .get_request_timeout();
 7412            let request_task = client.request_lsp(
 7413                upstream_project_id,
 7414                None,
 7415                request_timeout,
 7416                cx.background_executor().clone(),
 7417                request.to_proto(upstream_project_id, buffer.read(cx)),
 7418            );
 7419            let buffer = buffer.clone();
 7420            cx.spawn(async move |weak_lsp_store, cx| {
 7421                let lsp_store = weak_lsp_store.upgrade()?;
 7422                let signatures = join_all(
 7423                    request_task
 7424                        .await
 7425                        .log_err()
 7426                        .flatten()
 7427                        .map(|response| response.payload)
 7428                        .unwrap_or_default()
 7429                        .into_iter()
 7430                        .map(|response| {
 7431                            let response = GetSignatureHelp { position }.response_from_proto(
 7432                                response.response,
 7433                                lsp_store.clone(),
 7434                                buffer.clone(),
 7435                                cx.clone(),
 7436                            );
 7437                            async move { response.await.log_err().flatten() }
 7438                        }),
 7439                )
 7440                .await
 7441                .into_iter()
 7442                .flatten()
 7443                .collect();
 7444                Some(signatures)
 7445            })
 7446        } else {
 7447            let all_actions_task = self.request_multiple_lsp_locally(
 7448                buffer,
 7449                Some(position),
 7450                GetSignatureHelp { position },
 7451                cx,
 7452            );
 7453            cx.background_spawn(async move {
 7454                Some(
 7455                    all_actions_task
 7456                        .await
 7457                        .into_iter()
 7458                        .flat_map(|(_, actions)| actions)
 7459                        .collect::<Vec<_>>(),
 7460                )
 7461            })
 7462        }
 7463    }
 7464
 7465    pub fn hover(
 7466        &mut self,
 7467        buffer: &Entity<Buffer>,
 7468        position: PointUtf16,
 7469        cx: &mut Context<Self>,
 7470    ) -> Task<Option<Vec<Hover>>> {
 7471        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7472            let request = GetHover { position };
 7473            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7474                return Task::ready(None);
 7475            }
 7476            let request_timeout = ProjectSettings::get_global(cx)
 7477                .global_lsp_settings
 7478                .get_request_timeout();
 7479            let request_task = client.request_lsp(
 7480                upstream_project_id,
 7481                None,
 7482                request_timeout,
 7483                cx.background_executor().clone(),
 7484                request.to_proto(upstream_project_id, buffer.read(cx)),
 7485            );
 7486            let buffer = buffer.clone();
 7487            cx.spawn(async move |weak_lsp_store, cx| {
 7488                let lsp_store = weak_lsp_store.upgrade()?;
 7489                let hovers = join_all(
 7490                    request_task
 7491                        .await
 7492                        .log_err()
 7493                        .flatten()
 7494                        .map(|response| response.payload)
 7495                        .unwrap_or_default()
 7496                        .into_iter()
 7497                        .map(|response| {
 7498                            let response = GetHover { position }.response_from_proto(
 7499                                response.response,
 7500                                lsp_store.clone(),
 7501                                buffer.clone(),
 7502                                cx.clone(),
 7503                            );
 7504                            async move {
 7505                                response
 7506                                    .await
 7507                                    .log_err()
 7508                                    .flatten()
 7509                                    .and_then(remove_empty_hover_blocks)
 7510                            }
 7511                        }),
 7512                )
 7513                .await
 7514                .into_iter()
 7515                .flatten()
 7516                .collect();
 7517                Some(hovers)
 7518            })
 7519        } else {
 7520            let all_actions_task = self.request_multiple_lsp_locally(
 7521                buffer,
 7522                Some(position),
 7523                GetHover { position },
 7524                cx,
 7525            );
 7526            cx.background_spawn(async move {
 7527                Some(
 7528                    all_actions_task
 7529                        .await
 7530                        .into_iter()
 7531                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7532                        .collect::<Vec<Hover>>(),
 7533                )
 7534            })
 7535        }
 7536    }
 7537
 7538    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7539        let language_registry = self.languages.clone();
 7540
 7541        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7542            let request = upstream_client.request(proto::GetProjectSymbols {
 7543                project_id: *project_id,
 7544                query: query.to_string(),
 7545            });
 7546            cx.foreground_executor().spawn(async move {
 7547                let response = request.await?;
 7548                let mut symbols = Vec::new();
 7549                let core_symbols = response
 7550                    .symbols
 7551                    .into_iter()
 7552                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7553                    .collect::<Vec<_>>();
 7554                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7555                    .await;
 7556                Ok(symbols)
 7557            })
 7558        } else if let Some(local) = self.as_local() {
 7559            struct WorkspaceSymbolsResult {
 7560                server_id: LanguageServerId,
 7561                lsp_adapter: Arc<CachedLspAdapter>,
 7562                worktree: WeakEntity<Worktree>,
 7563                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7564            }
 7565
 7566            let mut requests = Vec::new();
 7567            let mut requested_servers = BTreeSet::new();
 7568            let request_timeout = ProjectSettings::get_global(cx)
 7569                .global_lsp_settings
 7570                .get_request_timeout();
 7571
 7572            for (seed, state) in local.language_server_ids.iter() {
 7573                let Some(worktree_handle) = self
 7574                    .worktree_store
 7575                    .read(cx)
 7576                    .worktree_for_id(seed.worktree_id, cx)
 7577                else {
 7578                    continue;
 7579                };
 7580
 7581                let worktree = worktree_handle.read(cx);
 7582                if !worktree.is_visible() {
 7583                    continue;
 7584                }
 7585
 7586                if !requested_servers.insert(state.id) {
 7587                    continue;
 7588                }
 7589
 7590                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7591                    Some(LanguageServerState::Running {
 7592                        adapter, server, ..
 7593                    }) => (adapter.clone(), server),
 7594
 7595                    _ => continue,
 7596                };
 7597
 7598                let supports_workspace_symbol_request =
 7599                    match server.capabilities().workspace_symbol_provider {
 7600                        Some(OneOf::Left(supported)) => supported,
 7601                        Some(OneOf::Right(_)) => true,
 7602                        None => false,
 7603                    };
 7604
 7605                if !supports_workspace_symbol_request {
 7606                    continue;
 7607                }
 7608
 7609                let worktree_handle = worktree_handle.clone();
 7610                let server_id = server.server_id();
 7611                requests.push(
 7612                    server
 7613                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7614                            lsp::WorkspaceSymbolParams {
 7615                                query: query.to_string(),
 7616                                ..Default::default()
 7617                            },
 7618                            request_timeout,
 7619                        )
 7620                        .map(move |response| {
 7621                            let lsp_symbols = response
 7622                                .into_response()
 7623                                .context("workspace symbols request")
 7624                                .log_err()
 7625                                .flatten()
 7626                                .map(|symbol_response| match symbol_response {
 7627                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7628                                        flat_responses
 7629                                            .into_iter()
 7630                                            .map(|lsp_symbol| {
 7631                                                (
 7632                                                    lsp_symbol.name,
 7633                                                    lsp_symbol.kind,
 7634                                                    lsp_symbol.location,
 7635                                                    lsp_symbol.container_name,
 7636                                                )
 7637                                            })
 7638                                            .collect::<Vec<_>>()
 7639                                    }
 7640                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7641                                        nested_responses
 7642                                            .into_iter()
 7643                                            .filter_map(|lsp_symbol| {
 7644                                                let location = match lsp_symbol.location {
 7645                                                    OneOf::Left(location) => location,
 7646                                                    OneOf::Right(_) => {
 7647                                                        log::error!(
 7648                                                            "Unexpected: client capabilities \
 7649                                                            forbid symbol resolutions in \
 7650                                                            workspace.symbol.resolveSupport"
 7651                                                        );
 7652                                                        return None;
 7653                                                    }
 7654                                                };
 7655                                                Some((
 7656                                                    lsp_symbol.name,
 7657                                                    lsp_symbol.kind,
 7658                                                    location,
 7659                                                    lsp_symbol.container_name,
 7660                                                ))
 7661                                            })
 7662                                            .collect::<Vec<_>>()
 7663                                    }
 7664                                })
 7665                                .unwrap_or_default();
 7666
 7667                            WorkspaceSymbolsResult {
 7668                                server_id,
 7669                                lsp_adapter,
 7670                                worktree: worktree_handle.downgrade(),
 7671                                lsp_symbols,
 7672                            }
 7673                        }),
 7674                );
 7675            }
 7676
 7677            cx.spawn(async move |this, cx| {
 7678                let responses = futures::future::join_all(requests).await;
 7679                let this = match this.upgrade() {
 7680                    Some(this) => this,
 7681                    None => return Ok(Vec::new()),
 7682                };
 7683
 7684                let mut symbols = Vec::new();
 7685                for result in responses {
 7686                    let core_symbols = this.update(cx, |this, cx| {
 7687                        result
 7688                            .lsp_symbols
 7689                            .into_iter()
 7690                            .filter_map(
 7691                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7692                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7693                                    let source_worktree = result.worktree.upgrade()?;
 7694                                    let source_worktree_id = source_worktree.read(cx).id();
 7695
 7696                                    let path = if let Some((tree, rel_path)) =
 7697                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7698                                    {
 7699                                        let worktree_id = tree.read(cx).id();
 7700                                        SymbolLocation::InProject(ProjectPath {
 7701                                            worktree_id,
 7702                                            path: rel_path,
 7703                                        })
 7704                                    } else {
 7705                                        SymbolLocation::OutsideProject {
 7706                                            signature: this.symbol_signature(&abs_path),
 7707                                            abs_path: abs_path.into(),
 7708                                        }
 7709                                    };
 7710
 7711                                    Some(CoreSymbol {
 7712                                        source_language_server_id: result.server_id,
 7713                                        language_server_name: result.lsp_adapter.name.clone(),
 7714                                        source_worktree_id,
 7715                                        path,
 7716                                        kind: symbol_kind,
 7717                                        name: collapse_newlines(&symbol_name, ""),
 7718                                        range: range_from_lsp(symbol_location.range),
 7719                                        container_name: container_name
 7720                                            .map(|c| collapse_newlines(&c, "")),
 7721                                    })
 7722                                },
 7723                            )
 7724                            .collect::<Vec<_>>()
 7725                    });
 7726
 7727                    populate_labels_for_symbols(
 7728                        core_symbols,
 7729                        &language_registry,
 7730                        Some(result.lsp_adapter),
 7731                        &mut symbols,
 7732                    )
 7733                    .await;
 7734                }
 7735
 7736                Ok(symbols)
 7737            })
 7738        } else {
 7739            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7740        }
 7741    }
 7742
 7743    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7744        let mut summary = DiagnosticSummary::default();
 7745        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7746            summary.error_count += path_summary.error_count;
 7747            summary.warning_count += path_summary.warning_count;
 7748        }
 7749        summary
 7750    }
 7751
 7752    /// Returns the diagnostic summary for a specific project path.
 7753    pub fn diagnostic_summary_for_path(
 7754        &self,
 7755        project_path: &ProjectPath,
 7756        _: &App,
 7757    ) -> DiagnosticSummary {
 7758        if let Some(summaries) = self
 7759            .diagnostic_summaries
 7760            .get(&project_path.worktree_id)
 7761            .and_then(|map| map.get(&project_path.path))
 7762        {
 7763            let (error_count, warning_count) = summaries.iter().fold(
 7764                (0, 0),
 7765                |(error_count, warning_count), (_language_server_id, summary)| {
 7766                    (
 7767                        error_count + summary.error_count,
 7768                        warning_count + summary.warning_count,
 7769                    )
 7770                },
 7771            );
 7772
 7773            DiagnosticSummary {
 7774                error_count,
 7775                warning_count,
 7776            }
 7777        } else {
 7778            DiagnosticSummary::default()
 7779        }
 7780    }
 7781
 7782    pub fn diagnostic_summaries<'a>(
 7783        &'a self,
 7784        include_ignored: bool,
 7785        cx: &'a App,
 7786    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7787        self.worktree_store
 7788            .read(cx)
 7789            .visible_worktrees(cx)
 7790            .filter_map(|worktree| {
 7791                let worktree = worktree.read(cx);
 7792                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7793            })
 7794            .flat_map(move |(worktree, summaries)| {
 7795                let worktree_id = worktree.id();
 7796                summaries
 7797                    .iter()
 7798                    .filter(move |(path, _)| {
 7799                        include_ignored
 7800                            || worktree
 7801                                .entry_for_path(path.as_ref())
 7802                                .is_some_and(|entry| !entry.is_ignored)
 7803                    })
 7804                    .flat_map(move |(path, summaries)| {
 7805                        summaries.iter().map(move |(server_id, summary)| {
 7806                            (
 7807                                ProjectPath {
 7808                                    worktree_id,
 7809                                    path: path.clone(),
 7810                                },
 7811                                *server_id,
 7812                                *summary,
 7813                            )
 7814                        })
 7815                    })
 7816            })
 7817    }
 7818
 7819    pub fn on_buffer_edited(
 7820        &mut self,
 7821        buffer: Entity<Buffer>,
 7822        cx: &mut Context<Self>,
 7823    ) -> Option<()> {
 7824        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7825            Some(
 7826                self.as_local()?
 7827                    .language_servers_for_buffer(buffer, cx)
 7828                    .map(|i| i.1.clone())
 7829                    .collect(),
 7830            )
 7831        })?;
 7832
 7833        let buffer = buffer.read(cx);
 7834        let file = File::from_dyn(buffer.file())?;
 7835        let abs_path = file.as_local()?.abs_path(cx);
 7836        let uri = lsp::Uri::from_file_path(&abs_path)
 7837            .ok()
 7838            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7839            .log_err()?;
 7840        let next_snapshot = buffer.text_snapshot();
 7841        for language_server in language_servers {
 7842            let language_server = language_server.clone();
 7843
 7844            let buffer_snapshots = self
 7845                .as_local_mut()?
 7846                .buffer_snapshots
 7847                .get_mut(&buffer.remote_id())
 7848                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7849            let previous_snapshot = buffer_snapshots.last()?;
 7850
 7851            let build_incremental_change = || {
 7852                buffer
 7853                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7854                        previous_snapshot.snapshot.version(),
 7855                    )
 7856                    .map(|edit| {
 7857                        let edit_start = edit.new.start.0;
 7858                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7859                        let new_text = next_snapshot
 7860                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7861                            .collect();
 7862                        lsp::TextDocumentContentChangeEvent {
 7863                            range: Some(lsp::Range::new(
 7864                                point_to_lsp(edit_start),
 7865                                point_to_lsp(edit_end),
 7866                            )),
 7867                            range_length: None,
 7868                            text: new_text,
 7869                        }
 7870                    })
 7871                    .collect()
 7872            };
 7873
 7874            let document_sync_kind = language_server
 7875                .capabilities()
 7876                .text_document_sync
 7877                .as_ref()
 7878                .and_then(|sync| match sync {
 7879                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7880                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7881                });
 7882
 7883            let content_changes: Vec<_> = match document_sync_kind {
 7884                Some(lsp::TextDocumentSyncKind::FULL) => {
 7885                    vec![lsp::TextDocumentContentChangeEvent {
 7886                        range: None,
 7887                        range_length: None,
 7888                        text: next_snapshot.text(),
 7889                    }]
 7890                }
 7891                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7892                _ => {
 7893                    #[cfg(any(test, feature = "test-support"))]
 7894                    {
 7895                        build_incremental_change()
 7896                    }
 7897
 7898                    #[cfg(not(any(test, feature = "test-support")))]
 7899                    {
 7900                        continue;
 7901                    }
 7902                }
 7903            };
 7904
 7905            let next_version = previous_snapshot.version + 1;
 7906            buffer_snapshots.push(LspBufferSnapshot {
 7907                version: next_version,
 7908                snapshot: next_snapshot.clone(),
 7909            });
 7910
 7911            language_server
 7912                .notify::<lsp::notification::DidChangeTextDocument>(
 7913                    lsp::DidChangeTextDocumentParams {
 7914                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7915                            uri.clone(),
 7916                            next_version,
 7917                        ),
 7918                        content_changes,
 7919                    },
 7920                )
 7921                .ok();
 7922            self.pull_workspace_diagnostics(language_server.server_id());
 7923        }
 7924
 7925        None
 7926    }
 7927
 7928    pub fn on_buffer_saved(
 7929        &mut self,
 7930        buffer: Entity<Buffer>,
 7931        cx: &mut Context<Self>,
 7932    ) -> Option<()> {
 7933        let file = File::from_dyn(buffer.read(cx).file())?;
 7934        let worktree_id = file.worktree_id(cx);
 7935        let abs_path = file.as_local()?.abs_path(cx);
 7936        let text_document = lsp::TextDocumentIdentifier {
 7937            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7938        };
 7939        let local = self.as_local()?;
 7940
 7941        for server in local.language_servers_for_worktree(worktree_id) {
 7942            if let Some(include_text) = include_text(server.as_ref()) {
 7943                let text = if include_text {
 7944                    Some(buffer.read(cx).text())
 7945                } else {
 7946                    None
 7947                };
 7948                server
 7949                    .notify::<lsp::notification::DidSaveTextDocument>(
 7950                        lsp::DidSaveTextDocumentParams {
 7951                            text_document: text_document.clone(),
 7952                            text,
 7953                        },
 7954                    )
 7955                    .ok();
 7956            }
 7957        }
 7958
 7959        let language_servers = buffer.update(cx, |buffer, cx| {
 7960            local.language_server_ids_for_buffer(buffer, cx)
 7961        });
 7962        for language_server_id in language_servers {
 7963            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7964        }
 7965
 7966        None
 7967    }
 7968
 7969    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 7970        let buffer_id = buffer.read(cx).remote_id();
 7971        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 7972        self.buffer_reload_tasks.insert(buffer_id, task);
 7973    }
 7974
 7975    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7976        maybe!(async move {
 7977            let mut refreshed_servers = HashSet::default();
 7978            let servers = lsp_store
 7979                .update(cx, |lsp_store, cx| {
 7980                    let local = lsp_store.as_local()?;
 7981
 7982                    let servers = local
 7983                        .language_server_ids
 7984                        .iter()
 7985                        .filter_map(|(seed, state)| {
 7986                            let worktree = lsp_store
 7987                                .worktree_store
 7988                                .read(cx)
 7989                                .worktree_for_id(seed.worktree_id, cx);
 7990                            let delegate: Arc<dyn LspAdapterDelegate> =
 7991                                worktree.map(|worktree| {
 7992                                    LocalLspAdapterDelegate::new(
 7993                                        local.languages.clone(),
 7994                                        &local.environment,
 7995                                        cx.weak_entity(),
 7996                                        &worktree,
 7997                                        local.http_client.clone(),
 7998                                        local.fs.clone(),
 7999                                        cx,
 8000                                    )
 8001                                })?;
 8002                            let server_id = state.id;
 8003
 8004                            let states = local.language_servers.get(&server_id)?;
 8005
 8006                            match states {
 8007                                LanguageServerState::Starting { .. } => None,
 8008                                LanguageServerState::Running {
 8009                                    adapter, server, ..
 8010                                } => {
 8011                                    let adapter = adapter.clone();
 8012                                    let server = server.clone();
 8013                                    refreshed_servers.insert(server.name());
 8014                                    let toolchain = seed.toolchain.clone();
 8015                                    Some(cx.spawn(async move |_, cx| {
 8016                                        let settings =
 8017                                            LocalLspStore::workspace_configuration_for_adapter(
 8018                                                adapter.adapter.clone(),
 8019                                                &delegate,
 8020                                                toolchain,
 8021                                                None,
 8022                                                cx,
 8023                                            )
 8024                                            .await
 8025                                            .ok()?;
 8026                                        server
 8027                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8028                                                lsp::DidChangeConfigurationParams { settings },
 8029                                            )
 8030                                            .ok()?;
 8031                                        Some(())
 8032                                    }))
 8033                                }
 8034                            }
 8035                        })
 8036                        .collect::<Vec<_>>();
 8037
 8038                    Some(servers)
 8039                })
 8040                .ok()
 8041                .flatten()?;
 8042
 8043            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8044            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8045            // to stop and unregister its language server wrapper.
 8046            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8047            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8048            let _: Vec<Option<()>> = join_all(servers).await;
 8049
 8050            Some(())
 8051        })
 8052        .await;
 8053    }
 8054
 8055    fn maintain_workspace_config(
 8056        external_refresh_requests: watch::Receiver<()>,
 8057        cx: &mut Context<Self>,
 8058    ) -> Task<Result<()>> {
 8059        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8060        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8061
 8062        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8063            *settings_changed_tx.borrow_mut() = ();
 8064        });
 8065
 8066        let mut joint_future =
 8067            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8068        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8069        // - 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).
 8070        // - 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.
 8071        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8072        // - 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,
 8073        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8074        cx.spawn(async move |this, cx| {
 8075            while let Some(()) = joint_future.next().await {
 8076                this.update(cx, |this, cx| {
 8077                    this.refresh_server_tree(cx);
 8078                })
 8079                .ok();
 8080
 8081                Self::refresh_workspace_configurations(&this, cx).await;
 8082            }
 8083
 8084            drop(settings_observation);
 8085            anyhow::Ok(())
 8086        })
 8087    }
 8088
 8089    pub fn running_language_servers_for_local_buffer<'a>(
 8090        &'a self,
 8091        buffer: &Buffer,
 8092        cx: &mut App,
 8093    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8094        let local = self.as_local();
 8095        let language_server_ids = local
 8096            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8097            .unwrap_or_default();
 8098
 8099        language_server_ids
 8100            .into_iter()
 8101            .filter_map(
 8102                move |server_id| match local?.language_servers.get(&server_id)? {
 8103                    LanguageServerState::Running {
 8104                        adapter, server, ..
 8105                    } => Some((adapter, server)),
 8106                    _ => None,
 8107                },
 8108            )
 8109    }
 8110
 8111    pub fn language_servers_for_local_buffer(
 8112        &self,
 8113        buffer: &Buffer,
 8114        cx: &mut App,
 8115    ) -> Vec<LanguageServerId> {
 8116        let local = self.as_local();
 8117        local
 8118            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8119            .unwrap_or_default()
 8120    }
 8121
 8122    pub fn language_server_for_local_buffer<'a>(
 8123        &'a self,
 8124        buffer: &'a Buffer,
 8125        server_id: LanguageServerId,
 8126        cx: &'a mut App,
 8127    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8128        self.as_local()?
 8129            .language_servers_for_buffer(buffer, cx)
 8130            .find(|(_, s)| s.server_id() == server_id)
 8131    }
 8132
 8133    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8134        self.diagnostic_summaries.remove(&id_to_remove);
 8135        if let Some(local) = self.as_local_mut() {
 8136            let to_remove = local.remove_worktree(id_to_remove, cx);
 8137            for server in to_remove {
 8138                self.language_server_statuses.remove(&server);
 8139            }
 8140        }
 8141    }
 8142
 8143    fn invalidate_diagnostic_summaries_for_removed_entries(
 8144        &mut self,
 8145        worktree_id: WorktreeId,
 8146        changes: &UpdatedEntriesSet,
 8147        cx: &mut Context<Self>,
 8148    ) {
 8149        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8150            return;
 8151        };
 8152
 8153        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8154        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8155        let downstream = self.downstream_client.clone();
 8156
 8157        for (path, _, _) in changes
 8158            .iter()
 8159            .filter(|(_, _, change)| *change == PathChange::Removed)
 8160        {
 8161            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8162                for (server_id, _) in &summaries_by_server_id {
 8163                    cleared_server_ids.insert(*server_id);
 8164                    if let Some((client, project_id)) = &downstream {
 8165                        client
 8166                            .send(proto::UpdateDiagnosticSummary {
 8167                                project_id: *project_id,
 8168                                worktree_id: worktree_id.to_proto(),
 8169                                summary: Some(proto::DiagnosticSummary {
 8170                                    path: path.as_ref().to_proto(),
 8171                                    language_server_id: server_id.0 as u64,
 8172                                    error_count: 0,
 8173                                    warning_count: 0,
 8174                                }),
 8175                                more_summaries: Vec::new(),
 8176                            })
 8177                            .ok();
 8178                    }
 8179                }
 8180                cleared_paths.push(ProjectPath {
 8181                    worktree_id,
 8182                    path: path.clone(),
 8183                });
 8184            }
 8185        }
 8186
 8187        if !cleared_paths.is_empty() {
 8188            for server_id in cleared_server_ids {
 8189                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8190                    server_id,
 8191                    paths: cleared_paths.clone(),
 8192                });
 8193            }
 8194        }
 8195    }
 8196
 8197    pub fn shared(
 8198        &mut self,
 8199        project_id: u64,
 8200        downstream_client: AnyProtoClient,
 8201        _: &mut Context<Self>,
 8202    ) {
 8203        self.downstream_client = Some((downstream_client.clone(), project_id));
 8204
 8205        for (server_id, status) in &self.language_server_statuses {
 8206            if let Some(server) = self.language_server_for_id(*server_id) {
 8207                downstream_client
 8208                    .send(proto::StartLanguageServer {
 8209                        project_id,
 8210                        server: Some(proto::LanguageServer {
 8211                            id: server_id.to_proto(),
 8212                            name: status.name.to_string(),
 8213                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8214                        }),
 8215                        capabilities: serde_json::to_string(&server.capabilities())
 8216                            .expect("serializing server LSP capabilities"),
 8217                    })
 8218                    .log_err();
 8219            }
 8220        }
 8221    }
 8222
 8223    pub fn disconnected_from_host(&mut self) {
 8224        self.downstream_client.take();
 8225    }
 8226
 8227    pub fn disconnected_from_ssh_remote(&mut self) {
 8228        if let LspStoreMode::Remote(RemoteLspStore {
 8229            upstream_client, ..
 8230        }) = &mut self.mode
 8231        {
 8232            upstream_client.take();
 8233        }
 8234    }
 8235
 8236    pub(crate) fn set_language_server_statuses_from_proto(
 8237        &mut self,
 8238        project: WeakEntity<Project>,
 8239        language_servers: Vec<proto::LanguageServer>,
 8240        server_capabilities: Vec<String>,
 8241        cx: &mut Context<Self>,
 8242    ) {
 8243        let lsp_logs = cx
 8244            .try_global::<GlobalLogStore>()
 8245            .map(|lsp_store| lsp_store.0.clone());
 8246
 8247        self.language_server_statuses = language_servers
 8248            .into_iter()
 8249            .zip(server_capabilities)
 8250            .map(|(server, server_capabilities)| {
 8251                let server_id = LanguageServerId(server.id as usize);
 8252                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8253                    self.lsp_server_capabilities
 8254                        .insert(server_id, server_capabilities);
 8255                }
 8256
 8257                let name = LanguageServerName::from_proto(server.name);
 8258                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8259
 8260                if let Some(lsp_logs) = &lsp_logs {
 8261                    lsp_logs.update(cx, |lsp_logs, cx| {
 8262                        lsp_logs.add_language_server(
 8263                            // Only remote clients get their language servers set from proto
 8264                            LanguageServerKind::Remote {
 8265                                project: project.clone(),
 8266                            },
 8267                            server_id,
 8268                            Some(name.clone()),
 8269                            worktree,
 8270                            None,
 8271                            cx,
 8272                        );
 8273                    });
 8274                }
 8275
 8276                (
 8277                    server_id,
 8278                    LanguageServerStatus {
 8279                        name,
 8280                        server_version: None,
 8281                        server_readable_version: None,
 8282                        pending_work: Default::default(),
 8283                        has_pending_diagnostic_updates: false,
 8284                        progress_tokens: Default::default(),
 8285                        worktree,
 8286                        binary: None,
 8287                        configuration: None,
 8288                        workspace_folders: BTreeSet::new(),
 8289                        process_id: None,
 8290                    },
 8291                )
 8292            })
 8293            .collect();
 8294    }
 8295
 8296    #[cfg(feature = "test-support")]
 8297    pub fn update_diagnostic_entries(
 8298        &mut self,
 8299        server_id: LanguageServerId,
 8300        abs_path: PathBuf,
 8301        result_id: Option<SharedString>,
 8302        version: Option<i32>,
 8303        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8304        cx: &mut Context<Self>,
 8305    ) -> anyhow::Result<()> {
 8306        self.merge_diagnostic_entries(
 8307            vec![DocumentDiagnosticsUpdate {
 8308                diagnostics: DocumentDiagnostics {
 8309                    diagnostics,
 8310                    document_abs_path: abs_path,
 8311                    version,
 8312                },
 8313                result_id,
 8314                server_id,
 8315                disk_based_sources: Cow::Borrowed(&[]),
 8316                registration_id: None,
 8317            }],
 8318            |_, _, _| false,
 8319            cx,
 8320        )?;
 8321        Ok(())
 8322    }
 8323
 8324    pub fn merge_diagnostic_entries<'a>(
 8325        &mut self,
 8326        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8327        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8328        cx: &mut Context<Self>,
 8329    ) -> anyhow::Result<()> {
 8330        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8331        let mut updated_diagnostics_paths = HashMap::default();
 8332        for mut update in diagnostic_updates {
 8333            let abs_path = &update.diagnostics.document_abs_path;
 8334            let server_id = update.server_id;
 8335            let Some((worktree, relative_path)) =
 8336                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8337            else {
 8338                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8339                return Ok(());
 8340            };
 8341
 8342            let worktree_id = worktree.read(cx).id();
 8343            let project_path = ProjectPath {
 8344                worktree_id,
 8345                path: relative_path,
 8346            };
 8347
 8348            let document_uri = lsp::Uri::from_file_path(abs_path)
 8349                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8350            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8351                let snapshot = buffer_handle.read(cx).snapshot();
 8352                let buffer = buffer_handle.read(cx);
 8353                let reused_diagnostics = buffer
 8354                    .buffer_diagnostics(Some(server_id))
 8355                    .iter()
 8356                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8357                    .map(|v| {
 8358                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8359                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8360                        DiagnosticEntry {
 8361                            range: start..end,
 8362                            diagnostic: v.diagnostic.clone(),
 8363                        }
 8364                    })
 8365                    .collect::<Vec<_>>();
 8366
 8367                self.as_local_mut()
 8368                    .context("cannot merge diagnostics on a remote LspStore")?
 8369                    .update_buffer_diagnostics(
 8370                        &buffer_handle,
 8371                        server_id,
 8372                        Some(update.registration_id),
 8373                        update.result_id,
 8374                        update.diagnostics.version,
 8375                        update.diagnostics.diagnostics.clone(),
 8376                        reused_diagnostics.clone(),
 8377                        cx,
 8378                    )?;
 8379
 8380                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8381            } else if let Some(local) = self.as_local() {
 8382                let reused_diagnostics = local
 8383                    .diagnostics
 8384                    .get(&worktree_id)
 8385                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8386                    .and_then(|diagnostics_by_server_id| {
 8387                        diagnostics_by_server_id
 8388                            .binary_search_by_key(&server_id, |e| e.0)
 8389                            .ok()
 8390                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8391                    })
 8392                    .into_iter()
 8393                    .flatten()
 8394                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8395
 8396                update
 8397                    .diagnostics
 8398                    .diagnostics
 8399                    .extend(reused_diagnostics.cloned());
 8400            }
 8401
 8402            let updated = worktree.update(cx, |worktree, cx| {
 8403                self.update_worktree_diagnostics(
 8404                    worktree.id(),
 8405                    server_id,
 8406                    project_path.path.clone(),
 8407                    update.diagnostics.diagnostics,
 8408                    cx,
 8409                )
 8410            })?;
 8411            match updated {
 8412                ControlFlow::Continue(new_summary) => {
 8413                    if let Some((project_id, new_summary)) = new_summary {
 8414                        match &mut diagnostics_summary {
 8415                            Some(diagnostics_summary) => {
 8416                                diagnostics_summary
 8417                                    .more_summaries
 8418                                    .push(proto::DiagnosticSummary {
 8419                                        path: project_path.path.as_ref().to_proto(),
 8420                                        language_server_id: server_id.0 as u64,
 8421                                        error_count: new_summary.error_count,
 8422                                        warning_count: new_summary.warning_count,
 8423                                    })
 8424                            }
 8425                            None => {
 8426                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8427                                    project_id,
 8428                                    worktree_id: worktree_id.to_proto(),
 8429                                    summary: Some(proto::DiagnosticSummary {
 8430                                        path: project_path.path.as_ref().to_proto(),
 8431                                        language_server_id: server_id.0 as u64,
 8432                                        error_count: new_summary.error_count,
 8433                                        warning_count: new_summary.warning_count,
 8434                                    }),
 8435                                    more_summaries: Vec::new(),
 8436                                })
 8437                            }
 8438                        }
 8439                    }
 8440                    updated_diagnostics_paths
 8441                        .entry(server_id)
 8442                        .or_insert_with(Vec::new)
 8443                        .push(project_path);
 8444                }
 8445                ControlFlow::Break(()) => {}
 8446            }
 8447        }
 8448
 8449        if let Some((diagnostics_summary, (downstream_client, _))) =
 8450            diagnostics_summary.zip(self.downstream_client.as_ref())
 8451        {
 8452            downstream_client.send(diagnostics_summary).log_err();
 8453        }
 8454        for (server_id, paths) in updated_diagnostics_paths {
 8455            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8456        }
 8457        Ok(())
 8458    }
 8459
 8460    fn update_worktree_diagnostics(
 8461        &mut self,
 8462        worktree_id: WorktreeId,
 8463        server_id: LanguageServerId,
 8464        path_in_worktree: Arc<RelPath>,
 8465        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8466        _: &mut Context<Worktree>,
 8467    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8468        let local = match &mut self.mode {
 8469            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8470            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8471        };
 8472
 8473        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8474        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8475        let summaries_by_server_id = summaries_for_tree
 8476            .entry(path_in_worktree.clone())
 8477            .or_default();
 8478
 8479        let old_summary = summaries_by_server_id
 8480            .remove(&server_id)
 8481            .unwrap_or_default();
 8482
 8483        let new_summary = DiagnosticSummary::new(&diagnostics);
 8484        if diagnostics.is_empty() {
 8485            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8486            {
 8487                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8488                    diagnostics_by_server_id.remove(ix);
 8489                }
 8490                if diagnostics_by_server_id.is_empty() {
 8491                    diagnostics_for_tree.remove(&path_in_worktree);
 8492                }
 8493            }
 8494        } else {
 8495            summaries_by_server_id.insert(server_id, new_summary);
 8496            let diagnostics_by_server_id = diagnostics_for_tree
 8497                .entry(path_in_worktree.clone())
 8498                .or_default();
 8499            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8500                Ok(ix) => {
 8501                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8502                }
 8503                Err(ix) => {
 8504                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8505                }
 8506            }
 8507        }
 8508
 8509        if !old_summary.is_empty() || !new_summary.is_empty() {
 8510            if let Some((_, project_id)) = &self.downstream_client {
 8511                Ok(ControlFlow::Continue(Some((
 8512                    *project_id,
 8513                    proto::DiagnosticSummary {
 8514                        path: path_in_worktree.to_proto(),
 8515                        language_server_id: server_id.0 as u64,
 8516                        error_count: new_summary.error_count as u32,
 8517                        warning_count: new_summary.warning_count as u32,
 8518                    },
 8519                ))))
 8520            } else {
 8521                Ok(ControlFlow::Continue(None))
 8522            }
 8523        } else {
 8524            Ok(ControlFlow::Break(()))
 8525        }
 8526    }
 8527
 8528    pub fn open_buffer_for_symbol(
 8529        &mut self,
 8530        symbol: &Symbol,
 8531        cx: &mut Context<Self>,
 8532    ) -> Task<Result<Entity<Buffer>>> {
 8533        if let Some((client, project_id)) = self.upstream_client() {
 8534            let request = client.request(proto::OpenBufferForSymbol {
 8535                project_id,
 8536                symbol: Some(Self::serialize_symbol(symbol)),
 8537            });
 8538            cx.spawn(async move |this, cx| {
 8539                let response = request.await?;
 8540                let buffer_id = BufferId::new(response.buffer_id)?;
 8541                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8542                    .await
 8543            })
 8544        } else if let Some(local) = self.as_local() {
 8545            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8546                seed.worktree_id == symbol.source_worktree_id
 8547                    && state.id == symbol.source_language_server_id
 8548                    && symbol.language_server_name == seed.name
 8549            });
 8550            if !is_valid {
 8551                return Task::ready(Err(anyhow!(
 8552                    "language server for worktree and language not found"
 8553                )));
 8554            };
 8555
 8556            let symbol_abs_path = match &symbol.path {
 8557                SymbolLocation::InProject(project_path) => self
 8558                    .worktree_store
 8559                    .read(cx)
 8560                    .absolutize(&project_path, cx)
 8561                    .context("no such worktree"),
 8562                SymbolLocation::OutsideProject {
 8563                    abs_path,
 8564                    signature: _,
 8565                } => Ok(abs_path.to_path_buf()),
 8566            };
 8567            let symbol_abs_path = match symbol_abs_path {
 8568                Ok(abs_path) => abs_path,
 8569                Err(err) => return Task::ready(Err(err)),
 8570            };
 8571            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8572                uri
 8573            } else {
 8574                return Task::ready(Err(anyhow!("invalid symbol path")));
 8575            };
 8576
 8577            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8578        } else {
 8579            Task::ready(Err(anyhow!("no upstream client or local store")))
 8580        }
 8581    }
 8582
 8583    pub(crate) fn open_local_buffer_via_lsp(
 8584        &mut self,
 8585        abs_path: lsp::Uri,
 8586        language_server_id: LanguageServerId,
 8587        cx: &mut Context<Self>,
 8588    ) -> Task<Result<Entity<Buffer>>> {
 8589        let path_style = self.worktree_store.read(cx).path_style();
 8590        cx.spawn(async move |lsp_store, cx| {
 8591            // Escape percent-encoded string.
 8592            let current_scheme = abs_path.scheme().to_owned();
 8593            // Uri is immutable, so we can't modify the scheme
 8594
 8595            let abs_path = abs_path
 8596                .to_file_path_ext(path_style)
 8597                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8598            let p = abs_path.clone();
 8599            let yarn_worktree = lsp_store
 8600                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8601                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8602                        cx.spawn(async move |this, cx| {
 8603                            let t = this
 8604                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8605                                .ok()?;
 8606                            t.await
 8607                        })
 8608                    }),
 8609                    None => Task::ready(None),
 8610                })?
 8611                .await;
 8612            let (worktree_root_target, known_relative_path) =
 8613                if let Some((zip_root, relative_path)) = yarn_worktree {
 8614                    (zip_root, Some(relative_path))
 8615                } else {
 8616                    (Arc::<Path>::from(abs_path.as_path()), None)
 8617                };
 8618            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8619                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8620                    worktree_store.find_worktree(&worktree_root_target, cx)
 8621                })
 8622            })?;
 8623            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8624                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8625                (result.0, relative_path, None)
 8626            } else {
 8627                let worktree = lsp_store
 8628                    .update(cx, |lsp_store, cx| {
 8629                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8630                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8631                        })
 8632                    })?
 8633                    .await?;
 8634                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8635                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8636                    lsp_store
 8637                        .update(cx, |lsp_store, cx| {
 8638                            if let Some(local) = lsp_store.as_local_mut() {
 8639                                local.register_language_server_for_invisible_worktree(
 8640                                    &worktree,
 8641                                    language_server_id,
 8642                                    cx,
 8643                                )
 8644                            }
 8645                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8646                                Some(status) => status.worktree,
 8647                                None => None,
 8648                            }
 8649                        })
 8650                        .ok()
 8651                        .flatten()
 8652                        .zip(Some(worktree_root.clone()))
 8653                } else {
 8654                    None
 8655                };
 8656                let relative_path = if let Some(known_path) = known_relative_path {
 8657                    known_path
 8658                } else {
 8659                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8660                        .into_arc()
 8661                };
 8662                (worktree, relative_path, source_ws)
 8663            };
 8664            let project_path = ProjectPath {
 8665                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8666                path: relative_path,
 8667            };
 8668            let buffer = lsp_store
 8669                .update(cx, |lsp_store, cx| {
 8670                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8671                        buffer_store.open_buffer(project_path, cx)
 8672                    })
 8673                })?
 8674                .await?;
 8675            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8676            if let Some((source_ws, worktree_root)) = source_ws {
 8677                buffer.update(cx, |buffer, cx| {
 8678                    let settings = WorktreeSettings::get(
 8679                        Some(
 8680                            (&ProjectPath {
 8681                                worktree_id: source_ws,
 8682                                path: Arc::from(RelPath::empty()),
 8683                            })
 8684                                .into(),
 8685                        ),
 8686                        cx,
 8687                    );
 8688                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8689                    if is_read_only {
 8690                        buffer.set_capability(Capability::ReadOnly, cx);
 8691                    }
 8692                });
 8693            }
 8694            Ok(buffer)
 8695        })
 8696    }
 8697
 8698    fn local_lsp_servers_for_buffer(
 8699        &self,
 8700        buffer: &Entity<Buffer>,
 8701        cx: &mut Context<Self>,
 8702    ) -> Vec<LanguageServerId> {
 8703        let Some(local) = self.as_local() else {
 8704            return Vec::new();
 8705        };
 8706
 8707        let snapshot = buffer.read(cx).snapshot();
 8708
 8709        buffer.update(cx, |buffer, cx| {
 8710            local
 8711                .language_servers_for_buffer(buffer, cx)
 8712                .map(|(_, server)| server.server_id())
 8713                .filter(|server_id| {
 8714                    self.as_local().is_none_or(|local| {
 8715                        local
 8716                            .buffers_opened_in_servers
 8717                            .get(&snapshot.remote_id())
 8718                            .is_some_and(|servers| servers.contains(server_id))
 8719                    })
 8720                })
 8721                .collect()
 8722        })
 8723    }
 8724
 8725    fn request_multiple_lsp_locally<P, R>(
 8726        &mut self,
 8727        buffer: &Entity<Buffer>,
 8728        position: Option<P>,
 8729        request: R,
 8730        cx: &mut Context<Self>,
 8731    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8732    where
 8733        P: ToOffset,
 8734        R: LspCommand + Clone,
 8735        <R::LspRequest as lsp::request::Request>::Result: Send,
 8736        <R::LspRequest as lsp::request::Request>::Params: Send,
 8737    {
 8738        let Some(local) = self.as_local() else {
 8739            return Task::ready(Vec::new());
 8740        };
 8741
 8742        let snapshot = buffer.read(cx).snapshot();
 8743        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8744
 8745        let server_ids = buffer.update(cx, |buffer, cx| {
 8746            local
 8747                .language_servers_for_buffer(buffer, cx)
 8748                .filter(|(adapter, _)| {
 8749                    scope
 8750                        .as_ref()
 8751                        .map(|scope| scope.language_allowed(&adapter.name))
 8752                        .unwrap_or(true)
 8753                })
 8754                .map(|(_, server)| server.server_id())
 8755                .filter(|server_id| {
 8756                    self.as_local().is_none_or(|local| {
 8757                        local
 8758                            .buffers_opened_in_servers
 8759                            .get(&snapshot.remote_id())
 8760                            .is_some_and(|servers| servers.contains(server_id))
 8761                    })
 8762                })
 8763                .collect::<Vec<_>>()
 8764        });
 8765
 8766        let mut response_results = server_ids
 8767            .into_iter()
 8768            .map(|server_id| {
 8769                let task = self.request_lsp(
 8770                    buffer.clone(),
 8771                    LanguageServerToQuery::Other(server_id),
 8772                    request.clone(),
 8773                    cx,
 8774                );
 8775                async move { (server_id, task.await) }
 8776            })
 8777            .collect::<FuturesUnordered<_>>();
 8778
 8779        cx.background_spawn(async move {
 8780            let mut responses = Vec::with_capacity(response_results.len());
 8781            while let Some((server_id, response_result)) = response_results.next().await {
 8782                match response_result {
 8783                    Ok(response) => responses.push((server_id, response)),
 8784                    // rust-analyzer likes to error with this when its still loading up
 8785                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8786                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8787                }
 8788            }
 8789            responses
 8790        })
 8791    }
 8792
 8793    async fn handle_lsp_get_completions(
 8794        this: Entity<Self>,
 8795        envelope: TypedEnvelope<proto::GetCompletions>,
 8796        mut cx: AsyncApp,
 8797    ) -> Result<proto::GetCompletionsResponse> {
 8798        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8799
 8800        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8801        let buffer_handle = this.update(&mut cx, |this, cx| {
 8802            this.buffer_store.read(cx).get_existing(buffer_id)
 8803        })?;
 8804        let request = GetCompletions::from_proto(
 8805            envelope.payload,
 8806            this.clone(),
 8807            buffer_handle.clone(),
 8808            cx.clone(),
 8809        )
 8810        .await?;
 8811
 8812        let server_to_query = match request.server_id {
 8813            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8814            None => LanguageServerToQuery::FirstCapable,
 8815        };
 8816
 8817        let response = this
 8818            .update(&mut cx, |this, cx| {
 8819                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8820            })
 8821            .await?;
 8822        this.update(&mut cx, |this, cx| {
 8823            Ok(GetCompletions::response_to_proto(
 8824                response,
 8825                this,
 8826                sender_id,
 8827                &buffer_handle.read(cx).version(),
 8828                cx,
 8829            ))
 8830        })
 8831    }
 8832
 8833    async fn handle_lsp_command<T: LspCommand>(
 8834        this: Entity<Self>,
 8835        envelope: TypedEnvelope<T::ProtoRequest>,
 8836        mut cx: AsyncApp,
 8837    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8838    where
 8839        <T::LspRequest as lsp::request::Request>::Params: Send,
 8840        <T::LspRequest as lsp::request::Request>::Result: Send,
 8841    {
 8842        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8843        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8844        let buffer_handle = this.update(&mut cx, |this, cx| {
 8845            this.buffer_store.read(cx).get_existing(buffer_id)
 8846        })?;
 8847        let request = T::from_proto(
 8848            envelope.payload,
 8849            this.clone(),
 8850            buffer_handle.clone(),
 8851            cx.clone(),
 8852        )
 8853        .await?;
 8854        let response = this
 8855            .update(&mut cx, |this, cx| {
 8856                this.request_lsp(
 8857                    buffer_handle.clone(),
 8858                    LanguageServerToQuery::FirstCapable,
 8859                    request,
 8860                    cx,
 8861                )
 8862            })
 8863            .await?;
 8864        this.update(&mut cx, |this, cx| {
 8865            Ok(T::response_to_proto(
 8866                response,
 8867                this,
 8868                sender_id,
 8869                &buffer_handle.read(cx).version(),
 8870                cx,
 8871            ))
 8872        })
 8873    }
 8874
 8875    async fn handle_lsp_query(
 8876        lsp_store: Entity<Self>,
 8877        envelope: TypedEnvelope<proto::LspQuery>,
 8878        mut cx: AsyncApp,
 8879    ) -> Result<proto::Ack> {
 8880        use proto::lsp_query::Request;
 8881        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8882        let lsp_query = envelope.payload;
 8883        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8884        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8885        match lsp_query.request.context("invalid LSP query request")? {
 8886            Request::GetReferences(get_references) => {
 8887                let position = get_references.position.clone().and_then(deserialize_anchor);
 8888                Self::query_lsp_locally::<GetReferences>(
 8889                    lsp_store,
 8890                    server_id,
 8891                    sender_id,
 8892                    lsp_request_id,
 8893                    get_references,
 8894                    position,
 8895                    &mut cx,
 8896                )
 8897                .await?;
 8898            }
 8899            Request::GetDocumentColor(get_document_color) => {
 8900                Self::query_lsp_locally::<GetDocumentColor>(
 8901                    lsp_store,
 8902                    server_id,
 8903                    sender_id,
 8904                    lsp_request_id,
 8905                    get_document_color,
 8906                    None,
 8907                    &mut cx,
 8908                )
 8909                .await?;
 8910            }
 8911            Request::GetFoldingRanges(get_folding_ranges) => {
 8912                Self::query_lsp_locally::<GetFoldingRanges>(
 8913                    lsp_store,
 8914                    server_id,
 8915                    sender_id,
 8916                    lsp_request_id,
 8917                    get_folding_ranges,
 8918                    None,
 8919                    &mut cx,
 8920                )
 8921                .await?;
 8922            }
 8923            Request::GetDocumentSymbols(get_document_symbols) => {
 8924                Self::query_lsp_locally::<GetDocumentSymbols>(
 8925                    lsp_store,
 8926                    server_id,
 8927                    sender_id,
 8928                    lsp_request_id,
 8929                    get_document_symbols,
 8930                    None,
 8931                    &mut cx,
 8932                )
 8933                .await?;
 8934            }
 8935            Request::GetHover(get_hover) => {
 8936                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8937                Self::query_lsp_locally::<GetHover>(
 8938                    lsp_store,
 8939                    server_id,
 8940                    sender_id,
 8941                    lsp_request_id,
 8942                    get_hover,
 8943                    position,
 8944                    &mut cx,
 8945                )
 8946                .await?;
 8947            }
 8948            Request::GetCodeActions(get_code_actions) => {
 8949                Self::query_lsp_locally::<GetCodeActions>(
 8950                    lsp_store,
 8951                    server_id,
 8952                    sender_id,
 8953                    lsp_request_id,
 8954                    get_code_actions,
 8955                    None,
 8956                    &mut cx,
 8957                )
 8958                .await?;
 8959            }
 8960            Request::GetSignatureHelp(get_signature_help) => {
 8961                let position = get_signature_help
 8962                    .position
 8963                    .clone()
 8964                    .and_then(deserialize_anchor);
 8965                Self::query_lsp_locally::<GetSignatureHelp>(
 8966                    lsp_store,
 8967                    server_id,
 8968                    sender_id,
 8969                    lsp_request_id,
 8970                    get_signature_help,
 8971                    position,
 8972                    &mut cx,
 8973                )
 8974                .await?;
 8975            }
 8976            Request::GetCodeLens(get_code_lens) => {
 8977                Self::query_lsp_locally::<GetCodeLens>(
 8978                    lsp_store,
 8979                    server_id,
 8980                    sender_id,
 8981                    lsp_request_id,
 8982                    get_code_lens,
 8983                    None,
 8984                    &mut cx,
 8985                )
 8986                .await?;
 8987            }
 8988            Request::GetDefinition(get_definition) => {
 8989                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8990                Self::query_lsp_locally::<GetDefinitions>(
 8991                    lsp_store,
 8992                    server_id,
 8993                    sender_id,
 8994                    lsp_request_id,
 8995                    get_definition,
 8996                    position,
 8997                    &mut cx,
 8998                )
 8999                .await?;
 9000            }
 9001            Request::GetDeclaration(get_declaration) => {
 9002                let position = get_declaration
 9003                    .position
 9004                    .clone()
 9005                    .and_then(deserialize_anchor);
 9006                Self::query_lsp_locally::<GetDeclarations>(
 9007                    lsp_store,
 9008                    server_id,
 9009                    sender_id,
 9010                    lsp_request_id,
 9011                    get_declaration,
 9012                    position,
 9013                    &mut cx,
 9014                )
 9015                .await?;
 9016            }
 9017            Request::GetTypeDefinition(get_type_definition) => {
 9018                let position = get_type_definition
 9019                    .position
 9020                    .clone()
 9021                    .and_then(deserialize_anchor);
 9022                Self::query_lsp_locally::<GetTypeDefinitions>(
 9023                    lsp_store,
 9024                    server_id,
 9025                    sender_id,
 9026                    lsp_request_id,
 9027                    get_type_definition,
 9028                    position,
 9029                    &mut cx,
 9030                )
 9031                .await?;
 9032            }
 9033            Request::GetImplementation(get_implementation) => {
 9034                let position = get_implementation
 9035                    .position
 9036                    .clone()
 9037                    .and_then(deserialize_anchor);
 9038                Self::query_lsp_locally::<GetImplementations>(
 9039                    lsp_store,
 9040                    server_id,
 9041                    sender_id,
 9042                    lsp_request_id,
 9043                    get_implementation,
 9044                    position,
 9045                    &mut cx,
 9046                )
 9047                .await?;
 9048            }
 9049            Request::InlayHints(inlay_hints) => {
 9050                let query_start = inlay_hints
 9051                    .start
 9052                    .clone()
 9053                    .and_then(deserialize_anchor)
 9054                    .context("invalid inlay hints range start")?;
 9055                let query_end = inlay_hints
 9056                    .end
 9057                    .clone()
 9058                    .and_then(deserialize_anchor)
 9059                    .context("invalid inlay hints range end")?;
 9060                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9061                    &lsp_store,
 9062                    server_id,
 9063                    lsp_request_id,
 9064                    &inlay_hints,
 9065                    query_start..query_end,
 9066                    &mut cx,
 9067                )
 9068                .await
 9069                .context("preparing inlay hints request")?;
 9070                Self::query_lsp_locally::<InlayHints>(
 9071                    lsp_store,
 9072                    server_id,
 9073                    sender_id,
 9074                    lsp_request_id,
 9075                    inlay_hints,
 9076                    None,
 9077                    &mut cx,
 9078                )
 9079                .await
 9080                .context("querying for inlay hints")?
 9081            }
 9082            //////////////////////////////
 9083            // Below are LSP queries that need to fetch more data,
 9084            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9085            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9086                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9087                    &lsp_store,
 9088                    &get_document_diagnostics,
 9089                    &mut cx,
 9090                )
 9091                .await?;
 9092                lsp_store.update(&mut cx, |lsp_store, cx| {
 9093                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9094                    let key = LspKey {
 9095                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9096                        server_queried: server_id,
 9097                    };
 9098                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9099                    ) {
 9100                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9101                            lsp_requests.clear();
 9102                        };
 9103                    }
 9104
 9105                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9106                        lsp_request_id,
 9107                        cx.spawn(async move |lsp_store, cx| {
 9108                            let diagnostics_pull = lsp_store
 9109                                .update(cx, |lsp_store, cx| {
 9110                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9111                                })
 9112                                .ok();
 9113                            if let Some(diagnostics_pull) = diagnostics_pull {
 9114                                match diagnostics_pull.await {
 9115                                    Ok(()) => {}
 9116                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9117                                };
 9118                            }
 9119                        }),
 9120                    );
 9121                });
 9122            }
 9123            Request::SemanticTokens(semantic_tokens) => {
 9124                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9125                    &lsp_store,
 9126                    &semantic_tokens,
 9127                    &mut cx,
 9128                )
 9129                .await?;
 9130                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9131                lsp_store.update(&mut cx, |lsp_store, cx| {
 9132                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9133                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9134                        let key = LspKey {
 9135                            request_type: TypeId::of::<SemanticTokensFull>(),
 9136                            server_queried: server_id,
 9137                        };
 9138                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9139                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9140                                lsp_requests.clear();
 9141                            };
 9142                        }
 9143
 9144                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9145                            lsp_request_id,
 9146                            cx.spawn(async move |lsp_store, cx| {
 9147                                let tokens_fetch = lsp_store
 9148                                    .update(cx, |lsp_store, cx| {
 9149                                        lsp_store
 9150                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9151                                    })
 9152                                    .ok();
 9153                                if let Some(tokens_fetch) = tokens_fetch {
 9154                                    let new_tokens = tokens_fetch.await;
 9155                                    if let Some(new_tokens) = new_tokens {
 9156                                        lsp_store
 9157                                            .update(cx, |lsp_store, cx| {
 9158                                                let response = new_tokens
 9159                                                    .into_iter()
 9160                                                    .map(|(server_id, response)| {
 9161                                                        (
 9162                                                            server_id.to_proto(),
 9163                                                            SemanticTokensFull::response_to_proto(
 9164                                                                response,
 9165                                                                lsp_store,
 9166                                                                sender_id,
 9167                                                                &buffer_version,
 9168                                                                cx,
 9169                                                            ),
 9170                                                        )
 9171                                                    })
 9172                                                    .collect::<HashMap<_, _>>();
 9173                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9174                                                    project_id,
 9175                                                    lsp_request_id,
 9176                                                    response,
 9177                                                ) {
 9178                                                    Ok(()) => {}
 9179                                                    Err(e) => {
 9180                                                        log::error!(
 9181                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9182                                                        )
 9183                                                    }
 9184                                                }
 9185                                            })
 9186                                            .ok();
 9187                                    }
 9188                                }
 9189                            }),
 9190                        );
 9191                    }
 9192                });
 9193            }
 9194        }
 9195        Ok(proto::Ack {})
 9196    }
 9197
 9198    async fn handle_lsp_query_response(
 9199        lsp_store: Entity<Self>,
 9200        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9201        cx: AsyncApp,
 9202    ) -> Result<()> {
 9203        lsp_store.read_with(&cx, |lsp_store, _| {
 9204            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9205                upstream_client.handle_lsp_response(envelope.clone());
 9206            }
 9207        });
 9208        Ok(())
 9209    }
 9210
 9211    async fn handle_apply_code_action(
 9212        this: Entity<Self>,
 9213        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9214        mut cx: AsyncApp,
 9215    ) -> Result<proto::ApplyCodeActionResponse> {
 9216        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9217        let action =
 9218            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9219        let apply_code_action = this.update(&mut cx, |this, cx| {
 9220            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9221            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9222            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9223        })?;
 9224
 9225        let project_transaction = apply_code_action.await?;
 9226        let project_transaction = this.update(&mut cx, |this, cx| {
 9227            this.buffer_store.update(cx, |buffer_store, cx| {
 9228                buffer_store.serialize_project_transaction_for_peer(
 9229                    project_transaction,
 9230                    sender_id,
 9231                    cx,
 9232                )
 9233            })
 9234        });
 9235        Ok(proto::ApplyCodeActionResponse {
 9236            transaction: Some(project_transaction),
 9237        })
 9238    }
 9239
 9240    async fn handle_register_buffer_with_language_servers(
 9241        this: Entity<Self>,
 9242        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9243        mut cx: AsyncApp,
 9244    ) -> Result<proto::Ack> {
 9245        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9246        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9247        this.update(&mut cx, |this, cx| {
 9248            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9249                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9250                    project_id: upstream_project_id,
 9251                    buffer_id: buffer_id.to_proto(),
 9252                    only_servers: envelope.payload.only_servers,
 9253                });
 9254            }
 9255
 9256            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9257                anyhow::bail!("buffer is not open");
 9258            };
 9259
 9260            let handle = this.register_buffer_with_language_servers(
 9261                &buffer,
 9262                envelope
 9263                    .payload
 9264                    .only_servers
 9265                    .into_iter()
 9266                    .filter_map(|selector| {
 9267                        Some(match selector.selector? {
 9268                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9269                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9270                            }
 9271                            proto::language_server_selector::Selector::Name(name) => {
 9272                                LanguageServerSelector::Name(LanguageServerName(
 9273                                    SharedString::from(name),
 9274                                ))
 9275                            }
 9276                        })
 9277                    })
 9278                    .collect(),
 9279                false,
 9280                cx,
 9281            );
 9282            // Pull diagnostics for the buffer even if it was already registered.
 9283            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9284            // but it's unclear if we need it.
 9285            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9286                .detach();
 9287            this.buffer_store().update(cx, |buffer_store, _| {
 9288                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9289            });
 9290
 9291            Ok(())
 9292        })?;
 9293        Ok(proto::Ack {})
 9294    }
 9295
 9296    async fn handle_rename_project_entry(
 9297        this: Entity<Self>,
 9298        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9299        mut cx: AsyncApp,
 9300    ) -> Result<proto::ProjectEntryResponse> {
 9301        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9302        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9303        let new_path =
 9304            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9305
 9306        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9307            .update(&mut cx, |this, cx| {
 9308                let (worktree, entry) = this
 9309                    .worktree_store
 9310                    .read(cx)
 9311                    .worktree_and_entry_for_id(entry_id, cx)?;
 9312                let new_worktree = this
 9313                    .worktree_store
 9314                    .read(cx)
 9315                    .worktree_for_id(new_worktree_id, cx)?;
 9316                Some((
 9317                    this.worktree_store.clone(),
 9318                    worktree,
 9319                    new_worktree,
 9320                    entry.clone(),
 9321                ))
 9322            })
 9323            .context("worktree not found")?;
 9324        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9325            (worktree.absolutize(&old_entry.path), worktree.id())
 9326        });
 9327        let new_abs_path =
 9328            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9329
 9330        let _transaction = Self::will_rename_entry(
 9331            this.downgrade(),
 9332            old_worktree_id,
 9333            &old_abs_path,
 9334            &new_abs_path,
 9335            old_entry.is_dir(),
 9336            cx.clone(),
 9337        )
 9338        .await;
 9339        let response = WorktreeStore::handle_rename_project_entry(
 9340            worktree_store,
 9341            envelope.payload,
 9342            cx.clone(),
 9343        )
 9344        .await;
 9345        this.read_with(&cx, |this, _| {
 9346            this.did_rename_entry(
 9347                old_worktree_id,
 9348                &old_abs_path,
 9349                &new_abs_path,
 9350                old_entry.is_dir(),
 9351            );
 9352        });
 9353        response
 9354    }
 9355
 9356    async fn handle_update_diagnostic_summary(
 9357        this: Entity<Self>,
 9358        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9359        mut cx: AsyncApp,
 9360    ) -> Result<()> {
 9361        this.update(&mut cx, |lsp_store, cx| {
 9362            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9363            let mut updated_diagnostics_paths = HashMap::default();
 9364            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9365            for message_summary in envelope
 9366                .payload
 9367                .summary
 9368                .into_iter()
 9369                .chain(envelope.payload.more_summaries)
 9370            {
 9371                let project_path = ProjectPath {
 9372                    worktree_id,
 9373                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9374                };
 9375                let path = project_path.path.clone();
 9376                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9377                let summary = DiagnosticSummary {
 9378                    error_count: message_summary.error_count as usize,
 9379                    warning_count: message_summary.warning_count as usize,
 9380                };
 9381
 9382                if summary.is_empty() {
 9383                    if let Some(worktree_summaries) =
 9384                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9385                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9386                    {
 9387                        summaries.remove(&server_id);
 9388                        if summaries.is_empty() {
 9389                            worktree_summaries.remove(&path);
 9390                        }
 9391                    }
 9392                } else {
 9393                    lsp_store
 9394                        .diagnostic_summaries
 9395                        .entry(worktree_id)
 9396                        .or_default()
 9397                        .entry(path)
 9398                        .or_default()
 9399                        .insert(server_id, summary);
 9400                }
 9401
 9402                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9403                    match &mut diagnostics_summary {
 9404                        Some(diagnostics_summary) => {
 9405                            diagnostics_summary
 9406                                .more_summaries
 9407                                .push(proto::DiagnosticSummary {
 9408                                    path: project_path.path.as_ref().to_proto(),
 9409                                    language_server_id: server_id.0 as u64,
 9410                                    error_count: summary.error_count as u32,
 9411                                    warning_count: summary.warning_count as u32,
 9412                                })
 9413                        }
 9414                        None => {
 9415                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9416                                project_id: *project_id,
 9417                                worktree_id: worktree_id.to_proto(),
 9418                                summary: Some(proto::DiagnosticSummary {
 9419                                    path: project_path.path.as_ref().to_proto(),
 9420                                    language_server_id: server_id.0 as u64,
 9421                                    error_count: summary.error_count as u32,
 9422                                    warning_count: summary.warning_count as u32,
 9423                                }),
 9424                                more_summaries: Vec::new(),
 9425                            })
 9426                        }
 9427                    }
 9428                }
 9429                updated_diagnostics_paths
 9430                    .entry(server_id)
 9431                    .or_insert_with(Vec::new)
 9432                    .push(project_path);
 9433            }
 9434
 9435            if let Some((diagnostics_summary, (downstream_client, _))) =
 9436                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9437            {
 9438                downstream_client.send(diagnostics_summary).log_err();
 9439            }
 9440            for (server_id, paths) in updated_diagnostics_paths {
 9441                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9442            }
 9443            Ok(())
 9444        })
 9445    }
 9446
 9447    async fn handle_start_language_server(
 9448        lsp_store: Entity<Self>,
 9449        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9450        mut cx: AsyncApp,
 9451    ) -> Result<()> {
 9452        let server = envelope.payload.server.context("invalid server")?;
 9453        let server_capabilities =
 9454            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9455                .with_context(|| {
 9456                    format!(
 9457                        "incorrect server capabilities {}",
 9458                        envelope.payload.capabilities
 9459                    )
 9460                })?;
 9461        lsp_store.update(&mut cx, |lsp_store, cx| {
 9462            let server_id = LanguageServerId(server.id as usize);
 9463            let server_name = LanguageServerName::from_proto(server.name.clone());
 9464            lsp_store
 9465                .lsp_server_capabilities
 9466                .insert(server_id, server_capabilities);
 9467            lsp_store.language_server_statuses.insert(
 9468                server_id,
 9469                LanguageServerStatus {
 9470                    name: server_name.clone(),
 9471                    server_version: None,
 9472                    server_readable_version: None,
 9473                    pending_work: Default::default(),
 9474                    has_pending_diagnostic_updates: false,
 9475                    progress_tokens: Default::default(),
 9476                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9477                    binary: None,
 9478                    configuration: None,
 9479                    workspace_folders: BTreeSet::new(),
 9480                    process_id: None,
 9481                },
 9482            );
 9483            cx.emit(LspStoreEvent::LanguageServerAdded(
 9484                server_id,
 9485                server_name,
 9486                server.worktree_id.map(WorktreeId::from_proto),
 9487            ));
 9488            cx.notify();
 9489        });
 9490        Ok(())
 9491    }
 9492
 9493    async fn handle_update_language_server(
 9494        lsp_store: Entity<Self>,
 9495        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9496        mut cx: AsyncApp,
 9497    ) -> Result<()> {
 9498        lsp_store.update(&mut cx, |lsp_store, cx| {
 9499            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9500
 9501            match envelope.payload.variant.context("invalid variant")? {
 9502                proto::update_language_server::Variant::WorkStart(payload) => {
 9503                    lsp_store.on_lsp_work_start(
 9504                        language_server_id,
 9505                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9506                            .context("invalid progress token value")?,
 9507                        LanguageServerProgress {
 9508                            title: payload.title,
 9509                            is_disk_based_diagnostics_progress: false,
 9510                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9511                            message: payload.message,
 9512                            percentage: payload.percentage.map(|p| p as usize),
 9513                            last_update_at: cx.background_executor().now(),
 9514                        },
 9515                        cx,
 9516                    );
 9517                }
 9518                proto::update_language_server::Variant::WorkProgress(payload) => {
 9519                    lsp_store.on_lsp_work_progress(
 9520                        language_server_id,
 9521                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9522                            .context("invalid progress token value")?,
 9523                        LanguageServerProgress {
 9524                            title: None,
 9525                            is_disk_based_diagnostics_progress: false,
 9526                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9527                            message: payload.message,
 9528                            percentage: payload.percentage.map(|p| p as usize),
 9529                            last_update_at: cx.background_executor().now(),
 9530                        },
 9531                        cx,
 9532                    );
 9533                }
 9534
 9535                proto::update_language_server::Variant::WorkEnd(payload) => {
 9536                    lsp_store.on_lsp_work_end(
 9537                        language_server_id,
 9538                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9539                            .context("invalid progress token value")?,
 9540                        cx,
 9541                    );
 9542                }
 9543
 9544                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9545                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9546                }
 9547
 9548                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9549                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9550                }
 9551
 9552                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9553                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9554                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9555                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9556                        language_server_id,
 9557                        name: envelope
 9558                            .payload
 9559                            .server_name
 9560                            .map(SharedString::new)
 9561                            .map(LanguageServerName),
 9562                        message: non_lsp,
 9563                    });
 9564                }
 9565            }
 9566
 9567            Ok(())
 9568        })
 9569    }
 9570
 9571    async fn handle_language_server_log(
 9572        this: Entity<Self>,
 9573        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9574        mut cx: AsyncApp,
 9575    ) -> Result<()> {
 9576        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9577        let log_type = envelope
 9578            .payload
 9579            .log_type
 9580            .map(LanguageServerLogType::from_proto)
 9581            .context("invalid language server log type")?;
 9582
 9583        let message = envelope.payload.message;
 9584
 9585        this.update(&mut cx, |_, cx| {
 9586            cx.emit(LspStoreEvent::LanguageServerLog(
 9587                language_server_id,
 9588                log_type,
 9589                message,
 9590            ));
 9591        });
 9592        Ok(())
 9593    }
 9594
 9595    async fn handle_lsp_ext_cancel_flycheck(
 9596        lsp_store: Entity<Self>,
 9597        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9598        cx: AsyncApp,
 9599    ) -> Result<proto::Ack> {
 9600        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9601        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9602            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9603                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9604            } else {
 9605                None
 9606            }
 9607        });
 9608        if let Some(task) = task {
 9609            task.context("handling lsp ext cancel flycheck")?;
 9610        }
 9611
 9612        Ok(proto::Ack {})
 9613    }
 9614
 9615    async fn handle_lsp_ext_run_flycheck(
 9616        lsp_store: Entity<Self>,
 9617        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9618        mut cx: AsyncApp,
 9619    ) -> Result<proto::Ack> {
 9620        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9621        lsp_store.update(&mut cx, |lsp_store, cx| {
 9622            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9623                let text_document = if envelope.payload.current_file_only {
 9624                    let buffer_id = envelope
 9625                        .payload
 9626                        .buffer_id
 9627                        .map(|id| BufferId::new(id))
 9628                        .transpose()?;
 9629                    buffer_id
 9630                        .and_then(|buffer_id| {
 9631                            lsp_store
 9632                                .buffer_store()
 9633                                .read(cx)
 9634                                .get(buffer_id)
 9635                                .and_then(|buffer| {
 9636                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9637                                })
 9638                                .map(|path| make_text_document_identifier(&path))
 9639                        })
 9640                        .transpose()?
 9641                } else {
 9642                    None
 9643                };
 9644                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9645                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9646                )?;
 9647            }
 9648            anyhow::Ok(())
 9649        })?;
 9650
 9651        Ok(proto::Ack {})
 9652    }
 9653
 9654    async fn handle_lsp_ext_clear_flycheck(
 9655        lsp_store: Entity<Self>,
 9656        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9657        cx: AsyncApp,
 9658    ) -> Result<proto::Ack> {
 9659        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9660        lsp_store.read_with(&cx, |lsp_store, _| {
 9661            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9662                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9663            } else {
 9664                None
 9665            }
 9666        });
 9667
 9668        Ok(proto::Ack {})
 9669    }
 9670
 9671    pub fn disk_based_diagnostics_started(
 9672        &mut self,
 9673        language_server_id: LanguageServerId,
 9674        cx: &mut Context<Self>,
 9675    ) {
 9676        if let Some(language_server_status) =
 9677            self.language_server_statuses.get_mut(&language_server_id)
 9678        {
 9679            language_server_status.has_pending_diagnostic_updates = true;
 9680        }
 9681
 9682        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9683        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9684            language_server_id,
 9685            name: self
 9686                .language_server_adapter_for_id(language_server_id)
 9687                .map(|adapter| adapter.name()),
 9688            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9689                Default::default(),
 9690            ),
 9691        })
 9692    }
 9693
 9694    pub fn disk_based_diagnostics_finished(
 9695        &mut self,
 9696        language_server_id: LanguageServerId,
 9697        cx: &mut Context<Self>,
 9698    ) {
 9699        if let Some(language_server_status) =
 9700            self.language_server_statuses.get_mut(&language_server_id)
 9701        {
 9702            language_server_status.has_pending_diagnostic_updates = false;
 9703        }
 9704
 9705        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9706        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9707            language_server_id,
 9708            name: self
 9709                .language_server_adapter_for_id(language_server_id)
 9710                .map(|adapter| adapter.name()),
 9711            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9712                Default::default(),
 9713            ),
 9714        })
 9715    }
 9716
 9717    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9718    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9719    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9720    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9721    // the language server might take some time to publish diagnostics.
 9722    fn simulate_disk_based_diagnostics_events_if_needed(
 9723        &mut self,
 9724        language_server_id: LanguageServerId,
 9725        cx: &mut Context<Self>,
 9726    ) {
 9727        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9728
 9729        let Some(LanguageServerState::Running {
 9730            simulate_disk_based_diagnostics_completion,
 9731            adapter,
 9732            ..
 9733        }) = self
 9734            .as_local_mut()
 9735            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9736        else {
 9737            return;
 9738        };
 9739
 9740        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9741            return;
 9742        }
 9743
 9744        let prev_task =
 9745            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9746                cx.background_executor()
 9747                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9748                    .await;
 9749
 9750                this.update(cx, |this, cx| {
 9751                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9752
 9753                    if let Some(LanguageServerState::Running {
 9754                        simulate_disk_based_diagnostics_completion,
 9755                        ..
 9756                    }) = this.as_local_mut().and_then(|local_store| {
 9757                        local_store.language_servers.get_mut(&language_server_id)
 9758                    }) {
 9759                        *simulate_disk_based_diagnostics_completion = None;
 9760                    }
 9761                })
 9762                .ok();
 9763            }));
 9764
 9765        if prev_task.is_none() {
 9766            self.disk_based_diagnostics_started(language_server_id, cx);
 9767        }
 9768    }
 9769
 9770    pub fn language_server_statuses(
 9771        &self,
 9772    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9773        self.language_server_statuses
 9774            .iter()
 9775            .map(|(key, value)| (*key, value))
 9776    }
 9777
 9778    pub(super) fn did_rename_entry(
 9779        &self,
 9780        worktree_id: WorktreeId,
 9781        old_path: &Path,
 9782        new_path: &Path,
 9783        is_dir: bool,
 9784    ) {
 9785        maybe!({
 9786            let local_store = self.as_local()?;
 9787
 9788            let old_uri = lsp::Uri::from_file_path(old_path)
 9789                .ok()
 9790                .map(|uri| uri.to_string())?;
 9791            let new_uri = lsp::Uri::from_file_path(new_path)
 9792                .ok()
 9793                .map(|uri| uri.to_string())?;
 9794
 9795            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9796                let Some(filter) = local_store
 9797                    .language_server_paths_watched_for_rename
 9798                    .get(&language_server.server_id())
 9799                else {
 9800                    continue;
 9801                };
 9802
 9803                if filter.should_send_did_rename(&old_uri, is_dir) {
 9804                    language_server
 9805                        .notify::<DidRenameFiles>(RenameFilesParams {
 9806                            files: vec![FileRename {
 9807                                old_uri: old_uri.clone(),
 9808                                new_uri: new_uri.clone(),
 9809                            }],
 9810                        })
 9811                        .ok();
 9812                }
 9813            }
 9814            Some(())
 9815        });
 9816    }
 9817
 9818    pub(super) fn will_rename_entry(
 9819        this: WeakEntity<Self>,
 9820        worktree_id: WorktreeId,
 9821        old_path: &Path,
 9822        new_path: &Path,
 9823        is_dir: bool,
 9824        cx: AsyncApp,
 9825    ) -> Task<ProjectTransaction> {
 9826        let old_uri = lsp::Uri::from_file_path(old_path)
 9827            .ok()
 9828            .map(|uri| uri.to_string());
 9829        let new_uri = lsp::Uri::from_file_path(new_path)
 9830            .ok()
 9831            .map(|uri| uri.to_string());
 9832        cx.spawn(async move |cx| {
 9833            let mut tasks = vec![];
 9834            this.update(cx, |this, cx| {
 9835                let local_store = this.as_local()?;
 9836                let old_uri = old_uri?;
 9837                let new_uri = new_uri?;
 9838                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9839                    let Some(filter) = local_store
 9840                        .language_server_paths_watched_for_rename
 9841                        .get(&language_server.server_id())
 9842                    else {
 9843                        continue;
 9844                    };
 9845
 9846                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9847                        continue;
 9848                    }
 9849                    let request_timeout = ProjectSettings::get_global(cx)
 9850                        .global_lsp_settings
 9851                        .get_request_timeout();
 9852
 9853                    let apply_edit = cx.spawn({
 9854                        let old_uri = old_uri.clone();
 9855                        let new_uri = new_uri.clone();
 9856                        let language_server = language_server.clone();
 9857                        async move |this, cx| {
 9858                            let edit = language_server
 9859                                .request::<WillRenameFiles>(
 9860                                    RenameFilesParams {
 9861                                        files: vec![FileRename { old_uri, new_uri }],
 9862                                    },
 9863                                    request_timeout,
 9864                                )
 9865                                .await
 9866                                .into_response()
 9867                                .context("will rename files")
 9868                                .log_err()
 9869                                .flatten()?;
 9870
 9871                            LocalLspStore::deserialize_workspace_edit(
 9872                                this.upgrade()?,
 9873                                edit,
 9874                                false,
 9875                                language_server.clone(),
 9876                                cx,
 9877                            )
 9878                            .await
 9879                            .ok()
 9880                        }
 9881                    });
 9882                    tasks.push(apply_edit);
 9883                }
 9884                Some(())
 9885            })
 9886            .ok()
 9887            .flatten();
 9888            let mut merged_transaction = ProjectTransaction::default();
 9889            for task in tasks {
 9890                // Await on tasks sequentially so that the order of application of edits is deterministic
 9891                // (at least with regards to the order of registration of language servers)
 9892                if let Some(transaction) = task.await {
 9893                    for (buffer, buffer_transaction) in transaction.0 {
 9894                        merged_transaction.0.insert(buffer, buffer_transaction);
 9895                    }
 9896                }
 9897            }
 9898            merged_transaction
 9899        })
 9900    }
 9901
 9902    fn lsp_notify_abs_paths_changed(
 9903        &mut self,
 9904        server_id: LanguageServerId,
 9905        changes: Vec<PathEvent>,
 9906    ) {
 9907        maybe!({
 9908            let server = self.language_server_for_id(server_id)?;
 9909            let changes = changes
 9910                .into_iter()
 9911                .filter_map(|event| {
 9912                    let typ = match event.kind? {
 9913                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9914                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9915                        PathEventKind::Changed | PathEventKind::Rescan => {
 9916                            lsp::FileChangeType::CHANGED
 9917                        }
 9918                    };
 9919                    Some(lsp::FileEvent {
 9920                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9921                        typ,
 9922                    })
 9923                })
 9924                .collect::<Vec<_>>();
 9925            if !changes.is_empty() {
 9926                server
 9927                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9928                        lsp::DidChangeWatchedFilesParams { changes },
 9929                    )
 9930                    .ok();
 9931            }
 9932            Some(())
 9933        });
 9934    }
 9935
 9936    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9937        self.as_local()?.language_server_for_id(id)
 9938    }
 9939
 9940    fn on_lsp_progress(
 9941        &mut self,
 9942        progress_params: lsp::ProgressParams,
 9943        language_server_id: LanguageServerId,
 9944        disk_based_diagnostics_progress_token: Option<String>,
 9945        cx: &mut Context<Self>,
 9946    ) {
 9947        match progress_params.value {
 9948            lsp::ProgressParamsValue::WorkDone(progress) => {
 9949                self.handle_work_done_progress(
 9950                    progress,
 9951                    language_server_id,
 9952                    disk_based_diagnostics_progress_token,
 9953                    ProgressToken::from_lsp(progress_params.token),
 9954                    cx,
 9955                );
 9956            }
 9957            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9958                let registration_id = match progress_params.token {
 9959                    lsp::NumberOrString::Number(_) => None,
 9960                    lsp::NumberOrString::String(token) => token
 9961                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9962                        .map(|(_, id)| id.to_owned()),
 9963                };
 9964                if let Some(LanguageServerState::Running {
 9965                    workspace_diagnostics_refresh_tasks,
 9966                    ..
 9967                }) = self
 9968                    .as_local_mut()
 9969                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9970                    && let Some(workspace_diagnostics) =
 9971                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9972                {
 9973                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9974                    self.apply_workspace_diagnostic_report(
 9975                        language_server_id,
 9976                        report,
 9977                        registration_id.map(SharedString::from),
 9978                        cx,
 9979                    )
 9980                }
 9981            }
 9982        }
 9983    }
 9984
 9985    fn handle_work_done_progress(
 9986        &mut self,
 9987        progress: lsp::WorkDoneProgress,
 9988        language_server_id: LanguageServerId,
 9989        disk_based_diagnostics_progress_token: Option<String>,
 9990        token: ProgressToken,
 9991        cx: &mut Context<Self>,
 9992    ) {
 9993        let language_server_status =
 9994            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9995                status
 9996            } else {
 9997                return;
 9998            };
 9999
10000        if !language_server_status.progress_tokens.contains(&token) {
10001            return;
10002        }
10003
10004        let is_disk_based_diagnostics_progress =
10005            if let (Some(disk_based_token), ProgressToken::String(token)) =
10006                (&disk_based_diagnostics_progress_token, &token)
10007            {
10008                token.starts_with(disk_based_token)
10009            } else {
10010                false
10011            };
10012
10013        match progress {
10014            lsp::WorkDoneProgress::Begin(report) => {
10015                if is_disk_based_diagnostics_progress {
10016                    self.disk_based_diagnostics_started(language_server_id, cx);
10017                }
10018                self.on_lsp_work_start(
10019                    language_server_id,
10020                    token.clone(),
10021                    LanguageServerProgress {
10022                        title: Some(report.title),
10023                        is_disk_based_diagnostics_progress,
10024                        is_cancellable: report.cancellable.unwrap_or(false),
10025                        message: report.message.clone(),
10026                        percentage: report.percentage.map(|p| p as usize),
10027                        last_update_at: cx.background_executor().now(),
10028                    },
10029                    cx,
10030                );
10031            }
10032            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10033                language_server_id,
10034                token,
10035                LanguageServerProgress {
10036                    title: None,
10037                    is_disk_based_diagnostics_progress,
10038                    is_cancellable: report.cancellable.unwrap_or(false),
10039                    message: report.message,
10040                    percentage: report.percentage.map(|p| p as usize),
10041                    last_update_at: cx.background_executor().now(),
10042                },
10043                cx,
10044            ),
10045            lsp::WorkDoneProgress::End(_) => {
10046                language_server_status.progress_tokens.remove(&token);
10047                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10048                if is_disk_based_diagnostics_progress {
10049                    self.disk_based_diagnostics_finished(language_server_id, cx);
10050                }
10051            }
10052        }
10053    }
10054
10055    fn on_lsp_work_start(
10056        &mut self,
10057        language_server_id: LanguageServerId,
10058        token: ProgressToken,
10059        progress: LanguageServerProgress,
10060        cx: &mut Context<Self>,
10061    ) {
10062        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10063            status.pending_work.insert(token.clone(), progress.clone());
10064            cx.notify();
10065        }
10066        cx.emit(LspStoreEvent::LanguageServerUpdate {
10067            language_server_id,
10068            name: self
10069                .language_server_adapter_for_id(language_server_id)
10070                .map(|adapter| adapter.name()),
10071            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10072                token: Some(token.to_proto()),
10073                title: progress.title,
10074                message: progress.message,
10075                percentage: progress.percentage.map(|p| p as u32),
10076                is_cancellable: Some(progress.is_cancellable),
10077            }),
10078        })
10079    }
10080
10081    fn on_lsp_work_progress(
10082        &mut self,
10083        language_server_id: LanguageServerId,
10084        token: ProgressToken,
10085        progress: LanguageServerProgress,
10086        cx: &mut Context<Self>,
10087    ) {
10088        let mut did_update = false;
10089        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10090            match status.pending_work.entry(token.clone()) {
10091                btree_map::Entry::Vacant(entry) => {
10092                    entry.insert(progress.clone());
10093                    did_update = true;
10094                }
10095                btree_map::Entry::Occupied(mut entry) => {
10096                    let entry = entry.get_mut();
10097                    if (progress.last_update_at - entry.last_update_at)
10098                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10099                    {
10100                        entry.last_update_at = progress.last_update_at;
10101                        if progress.message.is_some() {
10102                            entry.message = progress.message.clone();
10103                        }
10104                        if progress.percentage.is_some() {
10105                            entry.percentage = progress.percentage;
10106                        }
10107                        if progress.is_cancellable != entry.is_cancellable {
10108                            entry.is_cancellable = progress.is_cancellable;
10109                        }
10110                        did_update = true;
10111                    }
10112                }
10113            }
10114        }
10115
10116        if did_update {
10117            cx.emit(LspStoreEvent::LanguageServerUpdate {
10118                language_server_id,
10119                name: self
10120                    .language_server_adapter_for_id(language_server_id)
10121                    .map(|adapter| adapter.name()),
10122                message: proto::update_language_server::Variant::WorkProgress(
10123                    proto::LspWorkProgress {
10124                        token: Some(token.to_proto()),
10125                        message: progress.message,
10126                        percentage: progress.percentage.map(|p| p as u32),
10127                        is_cancellable: Some(progress.is_cancellable),
10128                    },
10129                ),
10130            })
10131        }
10132    }
10133
10134    fn on_lsp_work_end(
10135        &mut self,
10136        language_server_id: LanguageServerId,
10137        token: ProgressToken,
10138        cx: &mut Context<Self>,
10139    ) {
10140        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10141            if let Some(work) = status.pending_work.remove(&token)
10142                && !work.is_disk_based_diagnostics_progress
10143            {
10144                cx.emit(LspStoreEvent::RefreshInlayHints {
10145                    server_id: language_server_id,
10146                    request_id: None,
10147                });
10148            }
10149            cx.notify();
10150        }
10151
10152        cx.emit(LspStoreEvent::LanguageServerUpdate {
10153            language_server_id,
10154            name: self
10155                .language_server_adapter_for_id(language_server_id)
10156                .map(|adapter| adapter.name()),
10157            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10158                token: Some(token.to_proto()),
10159            }),
10160        })
10161    }
10162
10163    pub async fn handle_resolve_completion_documentation(
10164        this: Entity<Self>,
10165        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10166        mut cx: AsyncApp,
10167    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10168        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10169
10170        let completion = this
10171            .read_with(&cx, |this, cx| {
10172                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10173                let server = this
10174                    .language_server_for_id(id)
10175                    .with_context(|| format!("No language server {id}"))?;
10176
10177                let request_timeout = ProjectSettings::get_global(cx)
10178                    .global_lsp_settings
10179                    .get_request_timeout();
10180
10181                anyhow::Ok(cx.background_spawn(async move {
10182                    let can_resolve = server
10183                        .capabilities()
10184                        .completion_provider
10185                        .as_ref()
10186                        .and_then(|options| options.resolve_provider)
10187                        .unwrap_or(false);
10188                    if can_resolve {
10189                        server
10190                            .request::<lsp::request::ResolveCompletionItem>(
10191                                lsp_completion,
10192                                request_timeout,
10193                            )
10194                            .await
10195                            .into_response()
10196                            .context("resolve completion item")
10197                    } else {
10198                        anyhow::Ok(lsp_completion)
10199                    }
10200                }))
10201            })?
10202            .await?;
10203
10204        let mut documentation_is_markdown = false;
10205        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10206        let documentation = match completion.documentation {
10207            Some(lsp::Documentation::String(text)) => text,
10208
10209            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10210                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10211                value
10212            }
10213
10214            _ => String::new(),
10215        };
10216
10217        // If we have a new buffer_id, that means we're talking to a new client
10218        // and want to check for new text_edits in the completion too.
10219        let mut old_replace_start = None;
10220        let mut old_replace_end = None;
10221        let mut old_insert_start = None;
10222        let mut old_insert_end = None;
10223        let mut new_text = String::default();
10224        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10225            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10226                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10227                anyhow::Ok(buffer.read(cx).snapshot())
10228            })?;
10229
10230            if let Some(text_edit) = completion.text_edit.as_ref() {
10231                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10232
10233                if let Some(mut edit) = edit {
10234                    LineEnding::normalize(&mut edit.new_text);
10235
10236                    new_text = edit.new_text;
10237                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10238                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10239                    if let Some(insert_range) = edit.insert_range {
10240                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10241                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10242                    }
10243                }
10244            }
10245        }
10246
10247        Ok(proto::ResolveCompletionDocumentationResponse {
10248            documentation,
10249            documentation_is_markdown,
10250            old_replace_start,
10251            old_replace_end,
10252            new_text,
10253            lsp_completion,
10254            old_insert_start,
10255            old_insert_end,
10256        })
10257    }
10258
10259    async fn handle_on_type_formatting(
10260        this: Entity<Self>,
10261        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10262        mut cx: AsyncApp,
10263    ) -> Result<proto::OnTypeFormattingResponse> {
10264        let on_type_formatting = this.update(&mut cx, |this, cx| {
10265            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10266            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10267            let position = envelope
10268                .payload
10269                .position
10270                .and_then(deserialize_anchor)
10271                .context("invalid position")?;
10272            anyhow::Ok(this.apply_on_type_formatting(
10273                buffer,
10274                position,
10275                envelope.payload.trigger.clone(),
10276                cx,
10277            ))
10278        })?;
10279
10280        let transaction = on_type_formatting
10281            .await?
10282            .as_ref()
10283            .map(language::proto::serialize_transaction);
10284        Ok(proto::OnTypeFormattingResponse { transaction })
10285    }
10286
10287    async fn handle_pull_workspace_diagnostics(
10288        lsp_store: Entity<Self>,
10289        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10290        mut cx: AsyncApp,
10291    ) -> Result<proto::Ack> {
10292        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10293        lsp_store.update(&mut cx, |lsp_store, _| {
10294            lsp_store.pull_workspace_diagnostics(server_id);
10295        });
10296        Ok(proto::Ack {})
10297    }
10298
10299    async fn handle_open_buffer_for_symbol(
10300        this: Entity<Self>,
10301        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10302        mut cx: AsyncApp,
10303    ) -> Result<proto::OpenBufferForSymbolResponse> {
10304        let peer_id = envelope.original_sender_id().unwrap_or_default();
10305        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10306        let symbol = Self::deserialize_symbol(symbol)?;
10307        this.read_with(&cx, |this, _| {
10308            if let SymbolLocation::OutsideProject {
10309                abs_path,
10310                signature,
10311            } = &symbol.path
10312            {
10313                let new_signature = this.symbol_signature(&abs_path);
10314                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10315            }
10316            Ok(())
10317        })?;
10318        let buffer = this
10319            .update(&mut cx, |this, cx| {
10320                this.open_buffer_for_symbol(
10321                    &Symbol {
10322                        language_server_name: symbol.language_server_name,
10323                        source_worktree_id: symbol.source_worktree_id,
10324                        source_language_server_id: symbol.source_language_server_id,
10325                        path: symbol.path,
10326                        name: symbol.name,
10327                        kind: symbol.kind,
10328                        range: symbol.range,
10329                        label: CodeLabel::default(),
10330                        container_name: symbol.container_name,
10331                    },
10332                    cx,
10333                )
10334            })
10335            .await?;
10336
10337        this.update(&mut cx, |this, cx| {
10338            let is_private = buffer
10339                .read(cx)
10340                .file()
10341                .map(|f| f.is_private())
10342                .unwrap_or_default();
10343            if is_private {
10344                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10345            } else {
10346                this.buffer_store
10347                    .update(cx, |buffer_store, cx| {
10348                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10349                    })
10350                    .detach_and_log_err(cx);
10351                let buffer_id = buffer.read(cx).remote_id().to_proto();
10352                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10353            }
10354        })
10355    }
10356
10357    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10358        let mut hasher = Sha256::new();
10359        hasher.update(abs_path.to_string_lossy().as_bytes());
10360        hasher.update(self.nonce.to_be_bytes());
10361        hasher.finalize().as_slice().try_into().unwrap()
10362    }
10363
10364    pub async fn handle_get_project_symbols(
10365        this: Entity<Self>,
10366        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10367        mut cx: AsyncApp,
10368    ) -> Result<proto::GetProjectSymbolsResponse> {
10369        let symbols = this
10370            .update(&mut cx, |this, cx| {
10371                this.symbols(&envelope.payload.query, cx)
10372            })
10373            .await?;
10374
10375        Ok(proto::GetProjectSymbolsResponse {
10376            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10377        })
10378    }
10379
10380    pub async fn handle_restart_language_servers(
10381        this: Entity<Self>,
10382        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10383        mut cx: AsyncApp,
10384    ) -> Result<proto::Ack> {
10385        this.update(&mut cx, |lsp_store, cx| {
10386            let buffers =
10387                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10388            lsp_store.restart_language_servers_for_buffers(
10389                buffers,
10390                envelope
10391                    .payload
10392                    .only_servers
10393                    .into_iter()
10394                    .filter_map(|selector| {
10395                        Some(match selector.selector? {
10396                            proto::language_server_selector::Selector::ServerId(server_id) => {
10397                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10398                            }
10399                            proto::language_server_selector::Selector::Name(name) => {
10400                                LanguageServerSelector::Name(LanguageServerName(
10401                                    SharedString::from(name),
10402                                ))
10403                            }
10404                        })
10405                    })
10406                    .collect(),
10407                cx,
10408            );
10409        });
10410
10411        Ok(proto::Ack {})
10412    }
10413
10414    pub async fn handle_stop_language_servers(
10415        lsp_store: Entity<Self>,
10416        envelope: TypedEnvelope<proto::StopLanguageServers>,
10417        mut cx: AsyncApp,
10418    ) -> Result<proto::Ack> {
10419        lsp_store.update(&mut cx, |lsp_store, cx| {
10420            if envelope.payload.all
10421                && envelope.payload.also_servers.is_empty()
10422                && envelope.payload.buffer_ids.is_empty()
10423            {
10424                lsp_store.stop_all_language_servers(cx);
10425            } else {
10426                let buffers =
10427                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10428                lsp_store
10429                    .stop_language_servers_for_buffers(
10430                        buffers,
10431                        envelope
10432                            .payload
10433                            .also_servers
10434                            .into_iter()
10435                            .filter_map(|selector| {
10436                                Some(match selector.selector? {
10437                                    proto::language_server_selector::Selector::ServerId(
10438                                        server_id,
10439                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10440                                        server_id,
10441                                    )),
10442                                    proto::language_server_selector::Selector::Name(name) => {
10443                                        LanguageServerSelector::Name(LanguageServerName(
10444                                            SharedString::from(name),
10445                                        ))
10446                                    }
10447                                })
10448                            })
10449                            .collect(),
10450                        cx,
10451                    )
10452                    .detach_and_log_err(cx);
10453            }
10454        });
10455
10456        Ok(proto::Ack {})
10457    }
10458
10459    pub async fn handle_cancel_language_server_work(
10460        lsp_store: Entity<Self>,
10461        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10462        mut cx: AsyncApp,
10463    ) -> Result<proto::Ack> {
10464        lsp_store.update(&mut cx, |lsp_store, cx| {
10465            if let Some(work) = envelope.payload.work {
10466                match work {
10467                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10468                        let buffers =
10469                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10470                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10471                    }
10472                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10473                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10474                        let token = work
10475                            .token
10476                            .map(|token| {
10477                                ProgressToken::from_proto(token)
10478                                    .context("invalid work progress token")
10479                            })
10480                            .transpose()?;
10481                        lsp_store.cancel_language_server_work(server_id, token, cx);
10482                    }
10483                }
10484            }
10485            anyhow::Ok(())
10486        })?;
10487
10488        Ok(proto::Ack {})
10489    }
10490
10491    fn buffer_ids_to_buffers(
10492        &mut self,
10493        buffer_ids: impl Iterator<Item = u64>,
10494        cx: &mut Context<Self>,
10495    ) -> Vec<Entity<Buffer>> {
10496        buffer_ids
10497            .into_iter()
10498            .flat_map(|buffer_id| {
10499                self.buffer_store
10500                    .read(cx)
10501                    .get(BufferId::new(buffer_id).log_err()?)
10502            })
10503            .collect::<Vec<_>>()
10504    }
10505
10506    async fn handle_apply_additional_edits_for_completion(
10507        this: Entity<Self>,
10508        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10509        mut cx: AsyncApp,
10510    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10511        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10512            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10513            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10514            let completion = Self::deserialize_completion(
10515                envelope.payload.completion.context("invalid completion")?,
10516            )?;
10517            let all_commit_ranges = envelope
10518                .payload
10519                .all_commit_ranges
10520                .into_iter()
10521                .map(language::proto::deserialize_anchor_range)
10522                .collect::<Result<Vec<_>, _>>()?;
10523            anyhow::Ok((buffer, completion, all_commit_ranges))
10524        })?;
10525
10526        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10527            this.apply_additional_edits_for_completion(
10528                buffer,
10529                Rc::new(RefCell::new(Box::new([Completion {
10530                    replace_range: completion.replace_range,
10531                    new_text: completion.new_text,
10532                    source: completion.source,
10533                    documentation: None,
10534                    label: CodeLabel::default(),
10535                    match_start: None,
10536                    snippet_deduplication_key: None,
10537                    insert_text_mode: None,
10538                    icon_path: None,
10539                    confirm: None,
10540                }]))),
10541                0,
10542                false,
10543                all_commit_ranges,
10544                cx,
10545            )
10546        });
10547
10548        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10549            transaction: apply_additional_edits
10550                .await?
10551                .as_ref()
10552                .map(language::proto::serialize_transaction),
10553        })
10554    }
10555
10556    pub fn last_formatting_failure(&self) -> Option<&str> {
10557        self.last_formatting_failure.as_deref()
10558    }
10559
10560    pub fn reset_last_formatting_failure(&mut self) {
10561        self.last_formatting_failure = None;
10562    }
10563
10564    pub fn environment_for_buffer(
10565        &self,
10566        buffer: &Entity<Buffer>,
10567        cx: &mut Context<Self>,
10568    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10569        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10570            environment.update(cx, |env, cx| {
10571                env.buffer_environment(buffer, &self.worktree_store, cx)
10572            })
10573        } else {
10574            Task::ready(None).shared()
10575        }
10576    }
10577
10578    pub fn format(
10579        &mut self,
10580        buffers: HashSet<Entity<Buffer>>,
10581        target: LspFormatTarget,
10582        push_to_history: bool,
10583        trigger: FormatTrigger,
10584        cx: &mut Context<Self>,
10585    ) -> Task<anyhow::Result<ProjectTransaction>> {
10586        let logger = zlog::scoped!("format");
10587        if self.as_local().is_some() {
10588            zlog::trace!(logger => "Formatting locally");
10589            let logger = zlog::scoped!(logger => "local");
10590            let buffers = buffers
10591                .into_iter()
10592                .map(|buffer_handle| {
10593                    let buffer = buffer_handle.read(cx);
10594                    let buffer_abs_path = File::from_dyn(buffer.file())
10595                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10596
10597                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10598                })
10599                .collect::<Vec<_>>();
10600
10601            cx.spawn(async move |lsp_store, cx| {
10602                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10603
10604                for (handle, abs_path, id) in buffers {
10605                    let env = lsp_store
10606                        .update(cx, |lsp_store, cx| {
10607                            lsp_store.environment_for_buffer(&handle, cx)
10608                        })?
10609                        .await;
10610
10611                    let ranges = match &target {
10612                        LspFormatTarget::Buffers => None,
10613                        LspFormatTarget::Ranges(ranges) => {
10614                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10615                        }
10616                    };
10617
10618                    formattable_buffers.push(FormattableBuffer {
10619                        handle,
10620                        abs_path,
10621                        env,
10622                        ranges,
10623                    });
10624                }
10625                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10626
10627                let format_timer = zlog::time!(logger => "Formatting buffers");
10628                let result = LocalLspStore::format_locally(
10629                    lsp_store.clone(),
10630                    formattable_buffers,
10631                    push_to_history,
10632                    trigger,
10633                    logger,
10634                    cx,
10635                )
10636                .await;
10637                format_timer.end();
10638
10639                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10640
10641                lsp_store.update(cx, |lsp_store, _| {
10642                    lsp_store.update_last_formatting_failure(&result);
10643                })?;
10644
10645                result
10646            })
10647        } else if let Some((client, project_id)) = self.upstream_client() {
10648            zlog::trace!(logger => "Formatting remotely");
10649            let logger = zlog::scoped!(logger => "remote");
10650
10651            let buffer_ranges = match &target {
10652                LspFormatTarget::Buffers => Vec::new(),
10653                LspFormatTarget::Ranges(ranges) => ranges
10654                    .iter()
10655                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10656                        buffer_id: buffer_id.to_proto(),
10657                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10658                    })
10659                    .collect(),
10660            };
10661
10662            let buffer_store = self.buffer_store();
10663            cx.spawn(async move |lsp_store, cx| {
10664                zlog::trace!(logger => "Sending remote format request");
10665                let request_timer = zlog::time!(logger => "remote format request");
10666                let result = client
10667                    .request(proto::FormatBuffers {
10668                        project_id,
10669                        trigger: trigger as i32,
10670                        buffer_ids: buffers
10671                            .iter()
10672                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10673                            .collect(),
10674                        buffer_ranges,
10675                    })
10676                    .await
10677                    .and_then(|result| result.transaction.context("missing transaction"));
10678                request_timer.end();
10679
10680                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10681
10682                lsp_store.update(cx, |lsp_store, _| {
10683                    lsp_store.update_last_formatting_failure(&result);
10684                })?;
10685
10686                let transaction_response = result?;
10687                let _timer = zlog::time!(logger => "deserializing project transaction");
10688                buffer_store
10689                    .update(cx, |buffer_store, cx| {
10690                        buffer_store.deserialize_project_transaction(
10691                            transaction_response,
10692                            push_to_history,
10693                            cx,
10694                        )
10695                    })
10696                    .await
10697            })
10698        } else {
10699            zlog::trace!(logger => "Not formatting");
10700            Task::ready(Ok(ProjectTransaction::default()))
10701        }
10702    }
10703
10704    async fn handle_format_buffers(
10705        this: Entity<Self>,
10706        envelope: TypedEnvelope<proto::FormatBuffers>,
10707        mut cx: AsyncApp,
10708    ) -> Result<proto::FormatBuffersResponse> {
10709        let sender_id = envelope.original_sender_id().unwrap_or_default();
10710        let format = this.update(&mut cx, |this, cx| {
10711            let mut buffers = HashSet::default();
10712            for buffer_id in &envelope.payload.buffer_ids {
10713                let buffer_id = BufferId::new(*buffer_id)?;
10714                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10715            }
10716
10717            let target = if envelope.payload.buffer_ranges.is_empty() {
10718                LspFormatTarget::Buffers
10719            } else {
10720                let mut ranges_map = BTreeMap::new();
10721                for buffer_range in &envelope.payload.buffer_ranges {
10722                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10723                    let ranges: Result<Vec<_>> = buffer_range
10724                        .ranges
10725                        .iter()
10726                        .map(|range| {
10727                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10728                        })
10729                        .collect();
10730                    ranges_map.insert(buffer_id, ranges?);
10731                }
10732                LspFormatTarget::Ranges(ranges_map)
10733            };
10734
10735            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10736            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10737        })?;
10738
10739        let project_transaction = format.await?;
10740        let project_transaction = this.update(&mut cx, |this, cx| {
10741            this.buffer_store.update(cx, |buffer_store, cx| {
10742                buffer_store.serialize_project_transaction_for_peer(
10743                    project_transaction,
10744                    sender_id,
10745                    cx,
10746                )
10747            })
10748        });
10749        Ok(proto::FormatBuffersResponse {
10750            transaction: Some(project_transaction),
10751        })
10752    }
10753
10754    async fn handle_apply_code_action_kind(
10755        this: Entity<Self>,
10756        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10757        mut cx: AsyncApp,
10758    ) -> Result<proto::ApplyCodeActionKindResponse> {
10759        let sender_id = envelope.original_sender_id().unwrap_or_default();
10760        let format = this.update(&mut cx, |this, cx| {
10761            let mut buffers = HashSet::default();
10762            for buffer_id in &envelope.payload.buffer_ids {
10763                let buffer_id = BufferId::new(*buffer_id)?;
10764                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10765            }
10766            let kind = match envelope.payload.kind.as_str() {
10767                "" => CodeActionKind::EMPTY,
10768                "quickfix" => CodeActionKind::QUICKFIX,
10769                "refactor" => CodeActionKind::REFACTOR,
10770                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10771                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10772                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10773                "source" => CodeActionKind::SOURCE,
10774                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10775                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10776                _ => anyhow::bail!(
10777                    "Invalid code action kind {}",
10778                    envelope.payload.kind.as_str()
10779                ),
10780            };
10781            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10782        })?;
10783
10784        let project_transaction = format.await?;
10785        let project_transaction = this.update(&mut cx, |this, cx| {
10786            this.buffer_store.update(cx, |buffer_store, cx| {
10787                buffer_store.serialize_project_transaction_for_peer(
10788                    project_transaction,
10789                    sender_id,
10790                    cx,
10791                )
10792            })
10793        });
10794        Ok(proto::ApplyCodeActionKindResponse {
10795            transaction: Some(project_transaction),
10796        })
10797    }
10798
10799    async fn shutdown_language_server(
10800        server_state: Option<LanguageServerState>,
10801        name: LanguageServerName,
10802        cx: &mut AsyncApp,
10803    ) {
10804        let server = match server_state {
10805            Some(LanguageServerState::Starting { startup, .. }) => {
10806                let mut timer = cx
10807                    .background_executor()
10808                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10809                    .fuse();
10810
10811                select! {
10812                    server = startup.fuse() => server,
10813                    () = timer => {
10814                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10815                        None
10816                    },
10817                }
10818            }
10819
10820            Some(LanguageServerState::Running { server, .. }) => Some(server),
10821
10822            None => None,
10823        };
10824
10825        let Some(server) = server else { return };
10826        if let Some(shutdown) = server.shutdown() {
10827            shutdown.await;
10828        }
10829    }
10830
10831    // Returns a list of all of the worktrees which no longer have a language server and the root path
10832    // for the stopped server
10833    fn stop_local_language_server(
10834        &mut self,
10835        server_id: LanguageServerId,
10836        cx: &mut Context<Self>,
10837    ) -> Task<()> {
10838        let local = match &mut self.mode {
10839            LspStoreMode::Local(local) => local,
10840            _ => {
10841                return Task::ready(());
10842            }
10843        };
10844
10845        // Remove this server ID from all entries in the given worktree.
10846        local
10847            .language_server_ids
10848            .retain(|_, state| state.id != server_id);
10849        self.buffer_store.update(cx, |buffer_store, cx| {
10850            for buffer in buffer_store.buffers() {
10851                buffer.update(cx, |buffer, cx| {
10852                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10853                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10854                });
10855            }
10856        });
10857
10858        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10859        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10860            summaries.retain(|path, summaries_by_server_id| {
10861                if summaries_by_server_id.remove(&server_id).is_some() {
10862                    if let Some((client, project_id)) = self.downstream_client.clone() {
10863                        client
10864                            .send(proto::UpdateDiagnosticSummary {
10865                                project_id,
10866                                worktree_id: worktree_id.to_proto(),
10867                                summary: Some(proto::DiagnosticSummary {
10868                                    path: path.as_ref().to_proto(),
10869                                    language_server_id: server_id.0 as u64,
10870                                    error_count: 0,
10871                                    warning_count: 0,
10872                                }),
10873                                more_summaries: Vec::new(),
10874                            })
10875                            .log_err();
10876                    }
10877                    cleared_paths.push(ProjectPath {
10878                        worktree_id: *worktree_id,
10879                        path: path.clone(),
10880                    });
10881                    !summaries_by_server_id.is_empty()
10882                } else {
10883                    true
10884                }
10885            });
10886        }
10887        if !cleared_paths.is_empty() {
10888            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10889                server_id,
10890                paths: cleared_paths,
10891            });
10892        }
10893
10894        let local = self.as_local_mut().unwrap();
10895        for diagnostics in local.diagnostics.values_mut() {
10896            diagnostics.retain(|_, diagnostics_by_server_id| {
10897                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10898                    diagnostics_by_server_id.remove(ix);
10899                    !diagnostics_by_server_id.is_empty()
10900                } else {
10901                    true
10902                }
10903            });
10904        }
10905        local.language_server_watched_paths.remove(&server_id);
10906
10907        let server_state = local.language_servers.remove(&server_id);
10908        self.cleanup_lsp_data(server_id);
10909        let name = self
10910            .language_server_statuses
10911            .remove(&server_id)
10912            .map(|status| status.name)
10913            .or_else(|| {
10914                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10915                    Some(adapter.name())
10916                } else {
10917                    None
10918                }
10919            });
10920
10921        if let Some(name) = name {
10922            log::info!("stopping language server {name}");
10923            self.languages
10924                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10925            cx.notify();
10926
10927            return cx.spawn(async move |lsp_store, cx| {
10928                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10929                lsp_store
10930                    .update(cx, |lsp_store, cx| {
10931                        lsp_store
10932                            .languages
10933                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10934                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10935                        cx.notify();
10936                    })
10937                    .ok();
10938            });
10939        }
10940
10941        if server_state.is_some() {
10942            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10943        }
10944        Task::ready(())
10945    }
10946
10947    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10948        self.shutdown_all_language_servers(cx).detach();
10949    }
10950
10951    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10952        if let Some((client, project_id)) = self.upstream_client() {
10953            let request = client.request(proto::StopLanguageServers {
10954                project_id,
10955                buffer_ids: Vec::new(),
10956                also_servers: Vec::new(),
10957                all: true,
10958            });
10959            cx.background_spawn(async move {
10960                request.await.ok();
10961            })
10962        } else {
10963            let Some(local) = self.as_local_mut() else {
10964                return Task::ready(());
10965            };
10966            let language_servers_to_stop = local
10967                .language_server_ids
10968                .values()
10969                .map(|state| state.id)
10970                .collect();
10971            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10972            let tasks = language_servers_to_stop
10973                .into_iter()
10974                .map(|server| self.stop_local_language_server(server, cx))
10975                .collect::<Vec<_>>();
10976            cx.background_spawn(async move {
10977                futures::future::join_all(tasks).await;
10978            })
10979        }
10980    }
10981
10982    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10983        let buffers = self.buffer_store.read(cx).buffers().collect();
10984        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10985    }
10986
10987    pub fn restart_language_servers_for_buffers(
10988        &mut self,
10989        buffers: Vec<Entity<Buffer>>,
10990        only_restart_servers: HashSet<LanguageServerSelector>,
10991        cx: &mut Context<Self>,
10992    ) {
10993        if let Some((client, project_id)) = self.upstream_client() {
10994            let request = client.request(proto::RestartLanguageServers {
10995                project_id,
10996                buffer_ids: buffers
10997                    .into_iter()
10998                    .map(|b| b.read(cx).remote_id().to_proto())
10999                    .collect(),
11000                only_servers: only_restart_servers
11001                    .into_iter()
11002                    .map(|selector| {
11003                        let selector = match selector {
11004                            LanguageServerSelector::Id(language_server_id) => {
11005                                proto::language_server_selector::Selector::ServerId(
11006                                    language_server_id.to_proto(),
11007                                )
11008                            }
11009                            LanguageServerSelector::Name(language_server_name) => {
11010                                proto::language_server_selector::Selector::Name(
11011                                    language_server_name.to_string(),
11012                                )
11013                            }
11014                        };
11015                        proto::LanguageServerSelector {
11016                            selector: Some(selector),
11017                        }
11018                    })
11019                    .collect(),
11020                all: false,
11021            });
11022            cx.background_spawn(request).detach_and_log_err(cx);
11023        } else {
11024            let stop_task = if only_restart_servers.is_empty() {
11025                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11026            } else {
11027                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11028            };
11029            cx.spawn(async move |lsp_store, cx| {
11030                stop_task.await;
11031                lsp_store.update(cx, |lsp_store, cx| {
11032                    for buffer in buffers {
11033                        lsp_store.register_buffer_with_language_servers(
11034                            &buffer,
11035                            only_restart_servers.clone(),
11036                            true,
11037                            cx,
11038                        );
11039                    }
11040                })
11041            })
11042            .detach();
11043        }
11044    }
11045
11046    pub fn stop_language_servers_for_buffers(
11047        &mut self,
11048        buffers: Vec<Entity<Buffer>>,
11049        also_stop_servers: HashSet<LanguageServerSelector>,
11050        cx: &mut Context<Self>,
11051    ) -> Task<Result<()>> {
11052        if let Some((client, project_id)) = self.upstream_client() {
11053            let request = client.request(proto::StopLanguageServers {
11054                project_id,
11055                buffer_ids: buffers
11056                    .into_iter()
11057                    .map(|b| b.read(cx).remote_id().to_proto())
11058                    .collect(),
11059                also_servers: also_stop_servers
11060                    .into_iter()
11061                    .map(|selector| {
11062                        let selector = match selector {
11063                            LanguageServerSelector::Id(language_server_id) => {
11064                                proto::language_server_selector::Selector::ServerId(
11065                                    language_server_id.to_proto(),
11066                                )
11067                            }
11068                            LanguageServerSelector::Name(language_server_name) => {
11069                                proto::language_server_selector::Selector::Name(
11070                                    language_server_name.to_string(),
11071                                )
11072                            }
11073                        };
11074                        proto::LanguageServerSelector {
11075                            selector: Some(selector),
11076                        }
11077                    })
11078                    .collect(),
11079                all: false,
11080            });
11081            cx.background_spawn(async move {
11082                let _ = request.await?;
11083                Ok(())
11084            })
11085        } else {
11086            let task =
11087                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11088            cx.background_spawn(async move {
11089                task.await;
11090                Ok(())
11091            })
11092        }
11093    }
11094
11095    fn stop_local_language_servers_for_buffers(
11096        &mut self,
11097        buffers: &[Entity<Buffer>],
11098        also_stop_servers: HashSet<LanguageServerSelector>,
11099        cx: &mut Context<Self>,
11100    ) -> Task<()> {
11101        let Some(local) = self.as_local_mut() else {
11102            return Task::ready(());
11103        };
11104        let mut language_server_names_to_stop = BTreeSet::default();
11105        let mut language_servers_to_stop = also_stop_servers
11106            .into_iter()
11107            .flat_map(|selector| match selector {
11108                LanguageServerSelector::Id(id) => Some(id),
11109                LanguageServerSelector::Name(name) => {
11110                    language_server_names_to_stop.insert(name);
11111                    None
11112                }
11113            })
11114            .collect::<BTreeSet<_>>();
11115
11116        let mut covered_worktrees = HashSet::default();
11117        for buffer in buffers {
11118            buffer.update(cx, |buffer, cx| {
11119                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11120                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11121                    && covered_worktrees.insert(worktree_id)
11122                {
11123                    language_server_names_to_stop.retain(|name| {
11124                        let old_ids_count = language_servers_to_stop.len();
11125                        let all_language_servers_with_this_name = local
11126                            .language_server_ids
11127                            .iter()
11128                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11129                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11130                        old_ids_count == language_servers_to_stop.len()
11131                    });
11132                }
11133            });
11134        }
11135        for name in language_server_names_to_stop {
11136            language_servers_to_stop.extend(
11137                local
11138                    .language_server_ids
11139                    .iter()
11140                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11141            );
11142        }
11143
11144        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11145        let tasks = language_servers_to_stop
11146            .into_iter()
11147            .map(|server| self.stop_local_language_server(server, cx))
11148            .collect::<Vec<_>>();
11149
11150        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11151    }
11152
11153    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11154        let (worktree, relative_path) =
11155            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11156
11157        let project_path = ProjectPath {
11158            worktree_id: worktree.read(cx).id(),
11159            path: relative_path,
11160        };
11161
11162        Some(
11163            self.buffer_store()
11164                .read(cx)
11165                .get_by_path(&project_path)?
11166                .read(cx),
11167        )
11168    }
11169
11170    #[cfg(any(test, feature = "test-support"))]
11171    pub fn update_diagnostics(
11172        &mut self,
11173        server_id: LanguageServerId,
11174        diagnostics: lsp::PublishDiagnosticsParams,
11175        result_id: Option<SharedString>,
11176        source_kind: DiagnosticSourceKind,
11177        disk_based_sources: &[String],
11178        cx: &mut Context<Self>,
11179    ) -> Result<()> {
11180        self.merge_lsp_diagnostics(
11181            source_kind,
11182            vec![DocumentDiagnosticsUpdate {
11183                diagnostics,
11184                result_id,
11185                server_id,
11186                disk_based_sources: Cow::Borrowed(disk_based_sources),
11187                registration_id: None,
11188            }],
11189            |_, _, _| false,
11190            cx,
11191        )
11192    }
11193
11194    pub fn merge_lsp_diagnostics(
11195        &mut self,
11196        source_kind: DiagnosticSourceKind,
11197        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11198        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11199        cx: &mut Context<Self>,
11200    ) -> Result<()> {
11201        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11202        let updates = lsp_diagnostics
11203            .into_iter()
11204            .filter_map(|update| {
11205                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11206                Some(DocumentDiagnosticsUpdate {
11207                    diagnostics: self.lsp_to_document_diagnostics(
11208                        abs_path,
11209                        source_kind,
11210                        update.server_id,
11211                        update.diagnostics,
11212                        &update.disk_based_sources,
11213                        update.registration_id.clone(),
11214                    ),
11215                    result_id: update.result_id,
11216                    server_id: update.server_id,
11217                    disk_based_sources: update.disk_based_sources,
11218                    registration_id: update.registration_id,
11219                })
11220            })
11221            .collect();
11222        self.merge_diagnostic_entries(updates, merge, cx)?;
11223        Ok(())
11224    }
11225
11226    fn lsp_to_document_diagnostics(
11227        &mut self,
11228        document_abs_path: PathBuf,
11229        source_kind: DiagnosticSourceKind,
11230        server_id: LanguageServerId,
11231        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11232        disk_based_sources: &[String],
11233        registration_id: Option<SharedString>,
11234    ) -> DocumentDiagnostics {
11235        let mut diagnostics = Vec::default();
11236        let mut primary_diagnostic_group_ids = HashMap::default();
11237        let mut sources_by_group_id = HashMap::default();
11238        let mut supporting_diagnostics = HashMap::default();
11239
11240        let adapter = self.language_server_adapter_for_id(server_id);
11241
11242        // Ensure that primary diagnostics are always the most severe
11243        lsp_diagnostics
11244            .diagnostics
11245            .sort_by_key(|item| item.severity);
11246
11247        for diagnostic in &lsp_diagnostics.diagnostics {
11248            let source = diagnostic.source.as_ref();
11249            let range = range_from_lsp(diagnostic.range);
11250            let is_supporting = diagnostic
11251                .related_information
11252                .as_ref()
11253                .is_some_and(|infos| {
11254                    infos.iter().any(|info| {
11255                        primary_diagnostic_group_ids.contains_key(&(
11256                            source,
11257                            diagnostic.code.clone(),
11258                            range_from_lsp(info.location.range),
11259                        ))
11260                    })
11261                });
11262
11263            let is_unnecessary = diagnostic
11264                .tags
11265                .as_ref()
11266                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11267
11268            let underline = self
11269                .language_server_adapter_for_id(server_id)
11270                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11271
11272            if is_supporting {
11273                supporting_diagnostics.insert(
11274                    (source, diagnostic.code.clone(), range),
11275                    (diagnostic.severity, is_unnecessary),
11276                );
11277            } else {
11278                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11279                let is_disk_based =
11280                    source.is_some_and(|source| disk_based_sources.contains(source));
11281
11282                sources_by_group_id.insert(group_id, source);
11283                primary_diagnostic_group_ids
11284                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11285
11286                diagnostics.push(DiagnosticEntry {
11287                    range,
11288                    diagnostic: Diagnostic {
11289                        source: diagnostic.source.clone(),
11290                        source_kind,
11291                        code: diagnostic.code.clone(),
11292                        code_description: diagnostic
11293                            .code_description
11294                            .as_ref()
11295                            .and_then(|d| d.href.clone()),
11296                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11297                        markdown: adapter.as_ref().and_then(|adapter| {
11298                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11299                        }),
11300                        message: diagnostic.message.trim().to_string(),
11301                        group_id,
11302                        is_primary: true,
11303                        is_disk_based,
11304                        is_unnecessary,
11305                        underline,
11306                        data: diagnostic.data.clone(),
11307                        registration_id: registration_id.clone(),
11308                    },
11309                });
11310                if let Some(infos) = &diagnostic.related_information {
11311                    for info in infos {
11312                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11313                            let range = range_from_lsp(info.location.range);
11314                            diagnostics.push(DiagnosticEntry {
11315                                range,
11316                                diagnostic: Diagnostic {
11317                                    source: diagnostic.source.clone(),
11318                                    source_kind,
11319                                    code: diagnostic.code.clone(),
11320                                    code_description: diagnostic
11321                                        .code_description
11322                                        .as_ref()
11323                                        .and_then(|d| d.href.clone()),
11324                                    severity: DiagnosticSeverity::INFORMATION,
11325                                    markdown: adapter.as_ref().and_then(|adapter| {
11326                                        adapter.diagnostic_message_to_markdown(&info.message)
11327                                    }),
11328                                    message: info.message.trim().to_string(),
11329                                    group_id,
11330                                    is_primary: false,
11331                                    is_disk_based,
11332                                    is_unnecessary: false,
11333                                    underline,
11334                                    data: diagnostic.data.clone(),
11335                                    registration_id: registration_id.clone(),
11336                                },
11337                            });
11338                        }
11339                    }
11340                }
11341            }
11342        }
11343
11344        for entry in &mut diagnostics {
11345            let diagnostic = &mut entry.diagnostic;
11346            if !diagnostic.is_primary {
11347                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11348                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11349                    source,
11350                    diagnostic.code.clone(),
11351                    entry.range.clone(),
11352                )) {
11353                    if let Some(severity) = severity {
11354                        diagnostic.severity = severity;
11355                    }
11356                    diagnostic.is_unnecessary = is_unnecessary;
11357                }
11358            }
11359        }
11360
11361        DocumentDiagnostics {
11362            diagnostics,
11363            document_abs_path,
11364            version: lsp_diagnostics.version,
11365        }
11366    }
11367
11368    fn insert_newly_running_language_server(
11369        &mut self,
11370        adapter: Arc<CachedLspAdapter>,
11371        language_server: Arc<LanguageServer>,
11372        server_id: LanguageServerId,
11373        key: LanguageServerSeed,
11374        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11375        cx: &mut Context<Self>,
11376    ) {
11377        let Some(local) = self.as_local_mut() else {
11378            return;
11379        };
11380        // If the language server for this key doesn't match the server id, don't store the
11381        // server. Which will cause it to be dropped, killing the process
11382        if local
11383            .language_server_ids
11384            .get(&key)
11385            .map(|state| state.id != server_id)
11386            .unwrap_or(false)
11387        {
11388            return;
11389        }
11390
11391        // Update language_servers collection with Running variant of LanguageServerState
11392        // indicating that the server is up and running and ready
11393        let workspace_folders = workspace_folders.lock().clone();
11394        language_server.set_workspace_folders(workspace_folders);
11395
11396        let workspace_diagnostics_refresh_tasks = language_server
11397            .capabilities()
11398            .diagnostic_provider
11399            .and_then(|provider| {
11400                local
11401                    .language_server_dynamic_registrations
11402                    .entry(server_id)
11403                    .or_default()
11404                    .diagnostics
11405                    .entry(None)
11406                    .or_insert(provider.clone());
11407                let workspace_refresher =
11408                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11409
11410                Some((None, workspace_refresher))
11411            })
11412            .into_iter()
11413            .collect();
11414        local.language_servers.insert(
11415            server_id,
11416            LanguageServerState::Running {
11417                workspace_diagnostics_refresh_tasks,
11418                adapter: adapter.clone(),
11419                server: language_server.clone(),
11420                simulate_disk_based_diagnostics_completion: None,
11421            },
11422        );
11423        local
11424            .languages
11425            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11426        if let Some(file_ops_caps) = language_server
11427            .capabilities()
11428            .workspace
11429            .as_ref()
11430            .and_then(|ws| ws.file_operations.as_ref())
11431        {
11432            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11433            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11434            if did_rename_caps.or(will_rename_caps).is_some() {
11435                let watcher = RenamePathsWatchedForServer::default()
11436                    .with_did_rename_patterns(did_rename_caps)
11437                    .with_will_rename_patterns(will_rename_caps);
11438                local
11439                    .language_server_paths_watched_for_rename
11440                    .insert(server_id, watcher);
11441            }
11442        }
11443
11444        self.language_server_statuses.insert(
11445            server_id,
11446            LanguageServerStatus {
11447                name: language_server.name(),
11448                server_version: language_server.version(),
11449                server_readable_version: language_server.readable_version(),
11450                pending_work: Default::default(),
11451                has_pending_diagnostic_updates: false,
11452                progress_tokens: Default::default(),
11453                worktree: Some(key.worktree_id),
11454                binary: Some(language_server.binary().clone()),
11455                configuration: Some(language_server.configuration().clone()),
11456                workspace_folders: language_server.workspace_folders(),
11457                process_id: language_server.process_id(),
11458            },
11459        );
11460
11461        cx.emit(LspStoreEvent::LanguageServerAdded(
11462            server_id,
11463            language_server.name(),
11464            Some(key.worktree_id),
11465        ));
11466
11467        let server_capabilities = language_server.capabilities();
11468        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11469            downstream_client
11470                .send(proto::StartLanguageServer {
11471                    project_id: *project_id,
11472                    server: Some(proto::LanguageServer {
11473                        id: server_id.to_proto(),
11474                        name: language_server.name().to_string(),
11475                        worktree_id: Some(key.worktree_id.to_proto()),
11476                    }),
11477                    capabilities: serde_json::to_string(&server_capabilities)
11478                        .expect("serializing server LSP capabilities"),
11479                })
11480                .log_err();
11481        }
11482        self.lsp_server_capabilities
11483            .insert(server_id, server_capabilities);
11484
11485        // Tell the language server about every open buffer in the worktree that matches the language.
11486        // Also check for buffers in worktrees that reused this server
11487        let mut worktrees_using_server = vec![key.worktree_id];
11488        if let Some(local) = self.as_local() {
11489            // Find all worktrees that have this server in their language server tree
11490            for (worktree_id, servers) in &local.lsp_tree.instances {
11491                if *worktree_id != key.worktree_id {
11492                    for server_map in servers.roots.values() {
11493                        if server_map
11494                            .values()
11495                            .any(|(node, _)| node.id() == Some(server_id))
11496                        {
11497                            worktrees_using_server.push(*worktree_id);
11498                        }
11499                    }
11500                }
11501            }
11502        }
11503
11504        let mut buffer_paths_registered = Vec::new();
11505        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11506            let mut lsp_adapters = HashMap::default();
11507            for buffer_handle in buffer_store.buffers() {
11508                let buffer = buffer_handle.read(cx);
11509                let file = match File::from_dyn(buffer.file()) {
11510                    Some(file) => file,
11511                    None => continue,
11512                };
11513                let language = match buffer.language() {
11514                    Some(language) => language,
11515                    None => continue,
11516                };
11517
11518                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11519                    || !lsp_adapters
11520                        .entry(language.name())
11521                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11522                        .iter()
11523                        .any(|a| a.name == key.name)
11524                {
11525                    continue;
11526                }
11527                // didOpen
11528                let file = match file.as_local() {
11529                    Some(file) => file,
11530                    None => continue,
11531                };
11532
11533                let local = self.as_local_mut().unwrap();
11534
11535                let buffer_id = buffer.remote_id();
11536                if local.registered_buffers.contains_key(&buffer_id) {
11537                    let abs_path = file.abs_path(cx);
11538                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11539                        Ok(uri) => uri,
11540                        Err(()) => {
11541                            log::error!("failed to convert path to URI: {:?}", abs_path);
11542                            continue;
11543                        }
11544                    };
11545
11546                    let versions = local
11547                        .buffer_snapshots
11548                        .entry(buffer_id)
11549                        .or_default()
11550                        .entry(server_id)
11551                        .and_modify(|_| {
11552                            assert!(
11553                            false,
11554                            "There should not be an existing snapshot for a newly inserted buffer"
11555                        )
11556                        })
11557                        .or_insert_with(|| {
11558                            vec![LspBufferSnapshot {
11559                                version: 0,
11560                                snapshot: buffer.text_snapshot(),
11561                            }]
11562                        });
11563
11564                    let snapshot = versions.last().unwrap();
11565                    let version = snapshot.version;
11566                    let initial_snapshot = &snapshot.snapshot;
11567                    language_server.register_buffer(
11568                        uri,
11569                        adapter.language_id(&language.name()),
11570                        version,
11571                        initial_snapshot.text(),
11572                    );
11573                    buffer_paths_registered.push((buffer_id, abs_path));
11574                    local
11575                        .buffers_opened_in_servers
11576                        .entry(buffer_id)
11577                        .or_default()
11578                        .insert(server_id);
11579                }
11580                buffer_handle.update(cx, |buffer, cx| {
11581                    buffer.set_completion_triggers(
11582                        server_id,
11583                        language_server
11584                            .capabilities()
11585                            .completion_provider
11586                            .as_ref()
11587                            .and_then(|provider| {
11588                                provider
11589                                    .trigger_characters
11590                                    .as_ref()
11591                                    .map(|characters| characters.iter().cloned().collect())
11592                            })
11593                            .unwrap_or_default(),
11594                        cx,
11595                    )
11596                });
11597            }
11598        });
11599
11600        for (buffer_id, abs_path) in buffer_paths_registered {
11601            cx.emit(LspStoreEvent::LanguageServerUpdate {
11602                language_server_id: server_id,
11603                name: Some(adapter.name()),
11604                message: proto::update_language_server::Variant::RegisteredForBuffer(
11605                    proto::RegisteredForBuffer {
11606                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11607                        buffer_id: buffer_id.to_proto(),
11608                    },
11609                ),
11610            });
11611        }
11612
11613        cx.notify();
11614    }
11615
11616    pub fn language_servers_running_disk_based_diagnostics(
11617        &self,
11618    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11619        self.language_server_statuses
11620            .iter()
11621            .filter_map(|(id, status)| {
11622                if status.has_pending_diagnostic_updates {
11623                    Some(*id)
11624                } else {
11625                    None
11626                }
11627            })
11628    }
11629
11630    pub(crate) fn cancel_language_server_work_for_buffers(
11631        &mut self,
11632        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11633        cx: &mut Context<Self>,
11634    ) {
11635        if let Some((client, project_id)) = self.upstream_client() {
11636            let request = client.request(proto::CancelLanguageServerWork {
11637                project_id,
11638                work: Some(proto::cancel_language_server_work::Work::Buffers(
11639                    proto::cancel_language_server_work::Buffers {
11640                        buffer_ids: buffers
11641                            .into_iter()
11642                            .map(|b| b.read(cx).remote_id().to_proto())
11643                            .collect(),
11644                    },
11645                )),
11646            });
11647            cx.background_spawn(request).detach_and_log_err(cx);
11648        } else if let Some(local) = self.as_local() {
11649            let servers = buffers
11650                .into_iter()
11651                .flat_map(|buffer| {
11652                    buffer.update(cx, |buffer, cx| {
11653                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11654                    })
11655                })
11656                .collect::<HashSet<_>>();
11657            for server_id in servers {
11658                self.cancel_language_server_work(server_id, None, cx);
11659            }
11660        }
11661    }
11662
11663    pub(crate) fn cancel_language_server_work(
11664        &mut self,
11665        server_id: LanguageServerId,
11666        token_to_cancel: Option<ProgressToken>,
11667        cx: &mut Context<Self>,
11668    ) {
11669        if let Some(local) = self.as_local() {
11670            let status = self.language_server_statuses.get(&server_id);
11671            let server = local.language_servers.get(&server_id);
11672            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11673            {
11674                for (token, progress) in &status.pending_work {
11675                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11676                        && token != token_to_cancel
11677                    {
11678                        continue;
11679                    }
11680                    if progress.is_cancellable {
11681                        server
11682                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11683                                WorkDoneProgressCancelParams {
11684                                    token: token.to_lsp(),
11685                                },
11686                            )
11687                            .ok();
11688                    }
11689                }
11690            }
11691        } else if let Some((client, project_id)) = self.upstream_client() {
11692            let request = client.request(proto::CancelLanguageServerWork {
11693                project_id,
11694                work: Some(
11695                    proto::cancel_language_server_work::Work::LanguageServerWork(
11696                        proto::cancel_language_server_work::LanguageServerWork {
11697                            language_server_id: server_id.to_proto(),
11698                            token: token_to_cancel.map(|token| token.to_proto()),
11699                        },
11700                    ),
11701                ),
11702            });
11703            cx.background_spawn(request).detach_and_log_err(cx);
11704        }
11705    }
11706
11707    fn register_supplementary_language_server(
11708        &mut self,
11709        id: LanguageServerId,
11710        name: LanguageServerName,
11711        server: Arc<LanguageServer>,
11712        cx: &mut Context<Self>,
11713    ) {
11714        if let Some(local) = self.as_local_mut() {
11715            local
11716                .supplementary_language_servers
11717                .insert(id, (name.clone(), server));
11718            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11719        }
11720    }
11721
11722    fn unregister_supplementary_language_server(
11723        &mut self,
11724        id: LanguageServerId,
11725        cx: &mut Context<Self>,
11726    ) {
11727        if let Some(local) = self.as_local_mut() {
11728            local.supplementary_language_servers.remove(&id);
11729            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11730        }
11731    }
11732
11733    pub(crate) fn supplementary_language_servers(
11734        &self,
11735    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11736        self.as_local().into_iter().flat_map(|local| {
11737            local
11738                .supplementary_language_servers
11739                .iter()
11740                .map(|(id, (name, _))| (*id, name.clone()))
11741        })
11742    }
11743
11744    pub fn language_server_adapter_for_id(
11745        &self,
11746        id: LanguageServerId,
11747    ) -> Option<Arc<CachedLspAdapter>> {
11748        self.as_local()
11749            .and_then(|local| local.language_servers.get(&id))
11750            .and_then(|language_server_state| match language_server_state {
11751                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11752                _ => None,
11753            })
11754    }
11755
11756    pub(super) fn update_local_worktree_language_servers(
11757        &mut self,
11758        worktree_handle: &Entity<Worktree>,
11759        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11760        cx: &mut Context<Self>,
11761    ) {
11762        if changes.is_empty() {
11763            return;
11764        }
11765
11766        let Some(local) = self.as_local() else { return };
11767
11768        local.prettier_store.update(cx, |prettier_store, cx| {
11769            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11770        });
11771
11772        let worktree_id = worktree_handle.read(cx).id();
11773        let mut language_server_ids = local
11774            .language_server_ids
11775            .iter()
11776            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11777            .collect::<Vec<_>>();
11778        language_server_ids.sort();
11779        language_server_ids.dedup();
11780
11781        // let abs_path = worktree_handle.read(cx).abs_path();
11782        for server_id in &language_server_ids {
11783            if let Some(LanguageServerState::Running { server, .. }) =
11784                local.language_servers.get(server_id)
11785                && let Some(watched_paths) = local
11786                    .language_server_watched_paths
11787                    .get(server_id)
11788                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11789            {
11790                let params = lsp::DidChangeWatchedFilesParams {
11791                    changes: changes
11792                        .iter()
11793                        .filter_map(|(path, _, change)| {
11794                            if !watched_paths.is_match(path.as_std_path()) {
11795                                return None;
11796                            }
11797                            let typ = match change {
11798                                PathChange::Loaded => return None,
11799                                PathChange::Added => lsp::FileChangeType::CREATED,
11800                                PathChange::Removed => lsp::FileChangeType::DELETED,
11801                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11802                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11803                            };
11804                            let uri = lsp::Uri::from_file_path(
11805                                worktree_handle.read(cx).absolutize(&path),
11806                            )
11807                            .ok()?;
11808                            Some(lsp::FileEvent { uri, typ })
11809                        })
11810                        .collect(),
11811                };
11812                if !params.changes.is_empty() {
11813                    server
11814                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11815                        .ok();
11816                }
11817            }
11818        }
11819        for (path, _, _) in changes {
11820            if let Some(file_name) = path.file_name()
11821                && local.watched_manifest_filenames.contains(file_name)
11822            {
11823                self.request_workspace_config_refresh();
11824                break;
11825            }
11826        }
11827    }
11828
11829    pub fn wait_for_remote_buffer(
11830        &mut self,
11831        id: BufferId,
11832        cx: &mut Context<Self>,
11833    ) -> Task<Result<Entity<Buffer>>> {
11834        self.buffer_store.update(cx, |buffer_store, cx| {
11835            buffer_store.wait_for_remote_buffer(id, cx)
11836        })
11837    }
11838
11839    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11840        let mut result = proto::Symbol {
11841            language_server_name: symbol.language_server_name.0.to_string(),
11842            source_worktree_id: symbol.source_worktree_id.to_proto(),
11843            language_server_id: symbol.source_language_server_id.to_proto(),
11844            name: symbol.name.clone(),
11845            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11846            start: Some(proto::PointUtf16 {
11847                row: symbol.range.start.0.row,
11848                column: symbol.range.start.0.column,
11849            }),
11850            end: Some(proto::PointUtf16 {
11851                row: symbol.range.end.0.row,
11852                column: symbol.range.end.0.column,
11853            }),
11854            worktree_id: Default::default(),
11855            path: Default::default(),
11856            signature: Default::default(),
11857            container_name: symbol.container_name.clone(),
11858        };
11859        match &symbol.path {
11860            SymbolLocation::InProject(path) => {
11861                result.worktree_id = path.worktree_id.to_proto();
11862                result.path = path.path.to_proto();
11863            }
11864            SymbolLocation::OutsideProject {
11865                abs_path,
11866                signature,
11867            } => {
11868                result.path = abs_path.to_string_lossy().into_owned();
11869                result.signature = signature.to_vec();
11870            }
11871        }
11872        result
11873    }
11874
11875    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11876        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11877        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11878        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11879
11880        let path = if serialized_symbol.signature.is_empty() {
11881            SymbolLocation::InProject(ProjectPath {
11882                worktree_id,
11883                path: RelPath::from_proto(&serialized_symbol.path)
11884                    .context("invalid symbol path")?,
11885            })
11886        } else {
11887            SymbolLocation::OutsideProject {
11888                abs_path: Path::new(&serialized_symbol.path).into(),
11889                signature: serialized_symbol
11890                    .signature
11891                    .try_into()
11892                    .map_err(|_| anyhow!("invalid signature"))?,
11893            }
11894        };
11895
11896        let start = serialized_symbol.start.context("invalid start")?;
11897        let end = serialized_symbol.end.context("invalid end")?;
11898        Ok(CoreSymbol {
11899            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11900            source_worktree_id,
11901            source_language_server_id: LanguageServerId::from_proto(
11902                serialized_symbol.language_server_id,
11903            ),
11904            path,
11905            name: serialized_symbol.name,
11906            range: Unclipped(PointUtf16::new(start.row, start.column))
11907                ..Unclipped(PointUtf16::new(end.row, end.column)),
11908            kind,
11909            container_name: serialized_symbol.container_name,
11910        })
11911    }
11912
11913    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11914        let mut serialized_completion = proto::Completion {
11915            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11916            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11917            new_text: completion.new_text.clone(),
11918            ..proto::Completion::default()
11919        };
11920        match &completion.source {
11921            CompletionSource::Lsp {
11922                insert_range,
11923                server_id,
11924                lsp_completion,
11925                lsp_defaults,
11926                resolved,
11927            } => {
11928                let (old_insert_start, old_insert_end) = insert_range
11929                    .as_ref()
11930                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11931                    .unzip();
11932
11933                serialized_completion.old_insert_start = old_insert_start;
11934                serialized_completion.old_insert_end = old_insert_end;
11935                serialized_completion.source = proto::completion::Source::Lsp as i32;
11936                serialized_completion.server_id = server_id.0 as u64;
11937                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11938                serialized_completion.lsp_defaults = lsp_defaults
11939                    .as_deref()
11940                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11941                serialized_completion.resolved = *resolved;
11942            }
11943            CompletionSource::BufferWord {
11944                word_range,
11945                resolved,
11946            } => {
11947                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11948                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11949                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11950                serialized_completion.resolved = *resolved;
11951            }
11952            CompletionSource::Custom => {
11953                serialized_completion.source = proto::completion::Source::Custom as i32;
11954                serialized_completion.resolved = true;
11955            }
11956            CompletionSource::Dap { sort_text } => {
11957                serialized_completion.source = proto::completion::Source::Dap as i32;
11958                serialized_completion.sort_text = Some(sort_text.clone());
11959            }
11960        }
11961
11962        serialized_completion
11963    }
11964
11965    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11966        let old_replace_start = completion
11967            .old_replace_start
11968            .and_then(deserialize_anchor)
11969            .context("invalid old start")?;
11970        let old_replace_end = completion
11971            .old_replace_end
11972            .and_then(deserialize_anchor)
11973            .context("invalid old end")?;
11974        let insert_range = {
11975            match completion.old_insert_start.zip(completion.old_insert_end) {
11976                Some((start, end)) => {
11977                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11978                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11979                    Some(start..end)
11980                }
11981                None => None,
11982            }
11983        };
11984        Ok(CoreCompletion {
11985            replace_range: old_replace_start..old_replace_end,
11986            new_text: completion.new_text,
11987            source: match proto::completion::Source::from_i32(completion.source) {
11988                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11989                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11990                    insert_range,
11991                    server_id: LanguageServerId::from_proto(completion.server_id),
11992                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11993                    lsp_defaults: completion
11994                        .lsp_defaults
11995                        .as_deref()
11996                        .map(serde_json::from_slice)
11997                        .transpose()?,
11998                    resolved: completion.resolved,
11999                },
12000                Some(proto::completion::Source::BufferWord) => {
12001                    let word_range = completion
12002                        .buffer_word_start
12003                        .and_then(deserialize_anchor)
12004                        .context("invalid buffer word start")?
12005                        ..completion
12006                            .buffer_word_end
12007                            .and_then(deserialize_anchor)
12008                            .context("invalid buffer word end")?;
12009                    CompletionSource::BufferWord {
12010                        word_range,
12011                        resolved: completion.resolved,
12012                    }
12013                }
12014                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12015                    sort_text: completion
12016                        .sort_text
12017                        .context("expected sort text to exist")?,
12018                },
12019                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12020            },
12021        })
12022    }
12023
12024    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12025        let (kind, lsp_action) = match &action.lsp_action {
12026            LspAction::Action(code_action) => (
12027                proto::code_action::Kind::Action as i32,
12028                serde_json::to_vec(code_action).unwrap(),
12029            ),
12030            LspAction::Command(command) => (
12031                proto::code_action::Kind::Command as i32,
12032                serde_json::to_vec(command).unwrap(),
12033            ),
12034            LspAction::CodeLens(code_lens) => (
12035                proto::code_action::Kind::CodeLens as i32,
12036                serde_json::to_vec(code_lens).unwrap(),
12037            ),
12038        };
12039
12040        proto::CodeAction {
12041            server_id: action.server_id.0 as u64,
12042            start: Some(serialize_anchor(&action.range.start)),
12043            end: Some(serialize_anchor(&action.range.end)),
12044            lsp_action,
12045            kind,
12046            resolved: action.resolved,
12047        }
12048    }
12049
12050    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12051        let start = action
12052            .start
12053            .and_then(deserialize_anchor)
12054            .context("invalid start")?;
12055        let end = action
12056            .end
12057            .and_then(deserialize_anchor)
12058            .context("invalid end")?;
12059        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12060            Some(proto::code_action::Kind::Action) => {
12061                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12062            }
12063            Some(proto::code_action::Kind::Command) => {
12064                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12065            }
12066            Some(proto::code_action::Kind::CodeLens) => {
12067                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12068            }
12069            None => anyhow::bail!("Unknown action kind {}", action.kind),
12070        };
12071        Ok(CodeAction {
12072            server_id: LanguageServerId(action.server_id as usize),
12073            range: start..end,
12074            resolved: action.resolved,
12075            lsp_action,
12076        })
12077    }
12078
12079    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12080        match &formatting_result {
12081            Ok(_) => self.last_formatting_failure = None,
12082            Err(error) => {
12083                let error_string = format!("{error:#}");
12084                log::error!("Formatting failed: {error_string}");
12085                self.last_formatting_failure
12086                    .replace(error_string.lines().join(" "));
12087            }
12088        }
12089    }
12090
12091    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12092        self.lsp_server_capabilities.remove(&for_server);
12093        self.semantic_token_config.remove_server_data(for_server);
12094        for lsp_data in self.lsp_data.values_mut() {
12095            lsp_data.remove_server_data(for_server);
12096        }
12097        if let Some(local) = self.as_local_mut() {
12098            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12099            local
12100                .workspace_pull_diagnostics_result_ids
12101                .remove(&for_server);
12102            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12103                buffer_servers.remove(&for_server);
12104            }
12105        }
12106    }
12107
12108    pub fn result_id_for_buffer_pull(
12109        &self,
12110        server_id: LanguageServerId,
12111        buffer_id: BufferId,
12112        registration_id: &Option<SharedString>,
12113        cx: &App,
12114    ) -> Option<SharedString> {
12115        let abs_path = self
12116            .buffer_store
12117            .read(cx)
12118            .get(buffer_id)
12119            .and_then(|b| File::from_dyn(b.read(cx).file()))
12120            .map(|f| f.abs_path(cx))?;
12121        self.as_local()?
12122            .buffer_pull_diagnostics_result_ids
12123            .get(&server_id)?
12124            .get(registration_id)?
12125            .get(&abs_path)?
12126            .clone()
12127    }
12128
12129    /// Gets all result_ids for a workspace diagnostics pull request.
12130    /// 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.
12131    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12132    pub fn result_ids_for_workspace_refresh(
12133        &self,
12134        server_id: LanguageServerId,
12135        registration_id: &Option<SharedString>,
12136    ) -> HashMap<PathBuf, SharedString> {
12137        let Some(local) = self.as_local() else {
12138            return HashMap::default();
12139        };
12140        local
12141            .workspace_pull_diagnostics_result_ids
12142            .get(&server_id)
12143            .into_iter()
12144            .filter_map(|diagnostics| diagnostics.get(registration_id))
12145            .flatten()
12146            .filter_map(|(abs_path, result_id)| {
12147                let result_id = local
12148                    .buffer_pull_diagnostics_result_ids
12149                    .get(&server_id)
12150                    .and_then(|buffer_ids_result_ids| {
12151                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12152                    })
12153                    .cloned()
12154                    .flatten()
12155                    .or_else(|| result_id.clone())?;
12156                Some((abs_path.clone(), result_id))
12157            })
12158            .collect()
12159    }
12160
12161    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12162        if let Some(LanguageServerState::Running {
12163            workspace_diagnostics_refresh_tasks,
12164            ..
12165        }) = self
12166            .as_local_mut()
12167            .and_then(|local| local.language_servers.get_mut(&server_id))
12168        {
12169            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12170                diagnostics.refresh_tx.try_send(()).ok();
12171            }
12172        }
12173    }
12174
12175    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12176    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12177    /// which requires refreshing both workspace and document diagnostics.
12178    pub fn pull_document_diagnostics_for_server(
12179        &mut self,
12180        server_id: LanguageServerId,
12181        source_buffer_id: Option<BufferId>,
12182        cx: &mut Context<Self>,
12183    ) -> Shared<Task<()>> {
12184        let Some(local) = self.as_local_mut() else {
12185            return Task::ready(()).shared();
12186        };
12187        let mut buffers_to_refresh = HashSet::default();
12188        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12189            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12190                buffers_to_refresh.insert(*buffer_id);
12191            }
12192        }
12193
12194        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12195    }
12196
12197    pub fn pull_document_diagnostics_for_buffer_edit(
12198        &mut self,
12199        buffer_id: BufferId,
12200        cx: &mut Context<Self>,
12201    ) {
12202        let Some(local) = self.as_local_mut() else {
12203            return;
12204        };
12205        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12206        else {
12207            return;
12208        };
12209        for server_id in languages_servers {
12210            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12211        }
12212    }
12213
12214    fn apply_workspace_diagnostic_report(
12215        &mut self,
12216        server_id: LanguageServerId,
12217        report: lsp::WorkspaceDiagnosticReportResult,
12218        registration_id: Option<SharedString>,
12219        cx: &mut Context<Self>,
12220    ) {
12221        let mut workspace_diagnostics =
12222            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12223                report,
12224                server_id,
12225                registration_id,
12226            );
12227        workspace_diagnostics.retain(|d| match &d.diagnostics {
12228            LspPullDiagnostics::Response {
12229                server_id,
12230                registration_id,
12231                ..
12232            } => self.diagnostic_registration_exists(*server_id, registration_id),
12233            LspPullDiagnostics::Default => false,
12234        });
12235        let mut unchanged_buffers = HashMap::default();
12236        let workspace_diagnostics_updates = workspace_diagnostics
12237            .into_iter()
12238            .filter_map(
12239                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12240                    LspPullDiagnostics::Response {
12241                        server_id,
12242                        uri,
12243                        diagnostics,
12244                        registration_id,
12245                    } => Some((
12246                        server_id,
12247                        uri,
12248                        diagnostics,
12249                        workspace_diagnostics.version,
12250                        registration_id,
12251                    )),
12252                    LspPullDiagnostics::Default => None,
12253                },
12254            )
12255            .fold(
12256                HashMap::default(),
12257                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12258                    let (result_id, diagnostics) = match diagnostics {
12259                        PulledDiagnostics::Unchanged { result_id } => {
12260                            unchanged_buffers
12261                                .entry(new_registration_id.clone())
12262                                .or_insert_with(HashSet::default)
12263                                .insert(uri.clone());
12264                            (Some(result_id), Vec::new())
12265                        }
12266                        PulledDiagnostics::Changed {
12267                            result_id,
12268                            diagnostics,
12269                        } => (result_id, diagnostics),
12270                    };
12271                    let disk_based_sources = Cow::Owned(
12272                        self.language_server_adapter_for_id(server_id)
12273                            .as_ref()
12274                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12275                            .unwrap_or(&[])
12276                            .to_vec(),
12277                    );
12278
12279                    let Some(abs_path) = uri.to_file_path().ok() else {
12280                        return acc;
12281                    };
12282                    let Some((worktree, relative_path)) =
12283                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12284                    else {
12285                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12286                        return acc;
12287                    };
12288                    let worktree_id = worktree.read(cx).id();
12289                    let project_path = ProjectPath {
12290                        worktree_id,
12291                        path: relative_path,
12292                    };
12293                    if let Some(local_lsp_store) = self.as_local_mut() {
12294                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12295                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12296                    }
12297                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12298                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12299                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12300                        acc.entry(server_id)
12301                            .or_insert_with(HashMap::default)
12302                            .entry(new_registration_id.clone())
12303                            .or_insert_with(Vec::new)
12304                            .push(DocumentDiagnosticsUpdate {
12305                                server_id,
12306                                diagnostics: lsp::PublishDiagnosticsParams {
12307                                    uri,
12308                                    diagnostics,
12309                                    version,
12310                                },
12311                                result_id: result_id.map(SharedString::new),
12312                                disk_based_sources,
12313                                registration_id: new_registration_id,
12314                            });
12315                    }
12316                    acc
12317                },
12318            );
12319
12320        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12321            for (registration_id, diagnostic_updates) in diagnostic_updates {
12322                self.merge_lsp_diagnostics(
12323                    DiagnosticSourceKind::Pulled,
12324                    diagnostic_updates,
12325                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12326                        DiagnosticSourceKind::Pulled => {
12327                            old_diagnostic.registration_id != registration_id
12328                                || unchanged_buffers
12329                                    .get(&old_diagnostic.registration_id)
12330                                    .is_some_and(|unchanged_buffers| {
12331                                        unchanged_buffers.contains(&document_uri)
12332                                    })
12333                        }
12334                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12335                    },
12336                    cx,
12337                )
12338                .log_err();
12339            }
12340        }
12341    }
12342
12343    fn register_server_capabilities(
12344        &mut self,
12345        server_id: LanguageServerId,
12346        params: lsp::RegistrationParams,
12347        cx: &mut Context<Self>,
12348    ) -> anyhow::Result<()> {
12349        let server = self
12350            .language_server_for_id(server_id)
12351            .with_context(|| format!("no server {server_id} found"))?;
12352        for reg in params.registrations {
12353            match reg.method.as_str() {
12354                "workspace/didChangeWatchedFiles" => {
12355                    if let Some(options) = reg.register_options {
12356                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12357                            let caps = serde_json::from_value(options)?;
12358                            local_lsp_store
12359                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12360                            true
12361                        } else {
12362                            false
12363                        };
12364                        if notify {
12365                            notify_server_capabilities_updated(&server, cx);
12366                        }
12367                    }
12368                }
12369                "workspace/didChangeConfiguration" => {
12370                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12371                }
12372                "workspace/didChangeWorkspaceFolders" => {
12373                    // In this case register options is an empty object, we can ignore it
12374                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12375                        supported: Some(true),
12376                        change_notifications: Some(OneOf::Right(reg.id)),
12377                    };
12378                    server.update_capabilities(|capabilities| {
12379                        capabilities
12380                            .workspace
12381                            .get_or_insert_default()
12382                            .workspace_folders = Some(caps);
12383                    });
12384                    notify_server_capabilities_updated(&server, cx);
12385                }
12386                "workspace/symbol" => {
12387                    let options = parse_register_capabilities(reg)?;
12388                    server.update_capabilities(|capabilities| {
12389                        capabilities.workspace_symbol_provider = Some(options);
12390                    });
12391                    notify_server_capabilities_updated(&server, cx);
12392                }
12393                "workspace/fileOperations" => {
12394                    if let Some(options) = reg.register_options {
12395                        let caps = serde_json::from_value(options)?;
12396                        server.update_capabilities(|capabilities| {
12397                            capabilities
12398                                .workspace
12399                                .get_or_insert_default()
12400                                .file_operations = Some(caps);
12401                        });
12402                        notify_server_capabilities_updated(&server, cx);
12403                    }
12404                }
12405                "workspace/executeCommand" => {
12406                    if let Some(options) = reg.register_options {
12407                        let options = serde_json::from_value(options)?;
12408                        server.update_capabilities(|capabilities| {
12409                            capabilities.execute_command_provider = Some(options);
12410                        });
12411                        notify_server_capabilities_updated(&server, cx);
12412                    }
12413                }
12414                "textDocument/rangeFormatting" => {
12415                    let options = parse_register_capabilities(reg)?;
12416                    server.update_capabilities(|capabilities| {
12417                        capabilities.document_range_formatting_provider = Some(options);
12418                    });
12419                    notify_server_capabilities_updated(&server, cx);
12420                }
12421                "textDocument/onTypeFormatting" => {
12422                    if let Some(options) = reg
12423                        .register_options
12424                        .map(serde_json::from_value)
12425                        .transpose()?
12426                    {
12427                        server.update_capabilities(|capabilities| {
12428                            capabilities.document_on_type_formatting_provider = Some(options);
12429                        });
12430                        notify_server_capabilities_updated(&server, cx);
12431                    }
12432                }
12433                "textDocument/formatting" => {
12434                    let options = parse_register_capabilities(reg)?;
12435                    server.update_capabilities(|capabilities| {
12436                        capabilities.document_formatting_provider = Some(options);
12437                    });
12438                    notify_server_capabilities_updated(&server, cx);
12439                }
12440                "textDocument/rename" => {
12441                    let options = parse_register_capabilities(reg)?;
12442                    server.update_capabilities(|capabilities| {
12443                        capabilities.rename_provider = Some(options);
12444                    });
12445                    notify_server_capabilities_updated(&server, cx);
12446                }
12447                "textDocument/inlayHint" => {
12448                    let options = parse_register_capabilities(reg)?;
12449                    server.update_capabilities(|capabilities| {
12450                        capabilities.inlay_hint_provider = Some(options);
12451                    });
12452                    notify_server_capabilities_updated(&server, cx);
12453                }
12454                "textDocument/documentSymbol" => {
12455                    let options = parse_register_capabilities(reg)?;
12456                    server.update_capabilities(|capabilities| {
12457                        capabilities.document_symbol_provider = Some(options);
12458                    });
12459                    notify_server_capabilities_updated(&server, cx);
12460                }
12461                "textDocument/codeAction" => {
12462                    let options = parse_register_capabilities(reg)?;
12463                    let provider = match options {
12464                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12465                        OneOf::Right(caps) => caps,
12466                    };
12467                    server.update_capabilities(|capabilities| {
12468                        capabilities.code_action_provider = Some(provider);
12469                    });
12470                    notify_server_capabilities_updated(&server, cx);
12471                }
12472                "textDocument/definition" => {
12473                    let options = parse_register_capabilities(reg)?;
12474                    server.update_capabilities(|capabilities| {
12475                        capabilities.definition_provider = Some(options);
12476                    });
12477                    notify_server_capabilities_updated(&server, cx);
12478                }
12479                "textDocument/completion" => {
12480                    if let Some(caps) = reg
12481                        .register_options
12482                        .map(serde_json::from_value::<CompletionOptions>)
12483                        .transpose()?
12484                    {
12485                        server.update_capabilities(|capabilities| {
12486                            capabilities.completion_provider = Some(caps.clone());
12487                        });
12488
12489                        if let Some(local) = self.as_local() {
12490                            let mut buffers_with_language_server = Vec::new();
12491                            for handle in self.buffer_store.read(cx).buffers() {
12492                                let buffer_id = handle.read(cx).remote_id();
12493                                if local
12494                                    .buffers_opened_in_servers
12495                                    .get(&buffer_id)
12496                                    .filter(|s| s.contains(&server_id))
12497                                    .is_some()
12498                                {
12499                                    buffers_with_language_server.push(handle);
12500                                }
12501                            }
12502                            let triggers = caps
12503                                .trigger_characters
12504                                .unwrap_or_default()
12505                                .into_iter()
12506                                .collect::<BTreeSet<_>>();
12507                            for handle in buffers_with_language_server {
12508                                let triggers = triggers.clone();
12509                                let _ = handle.update(cx, move |buffer, cx| {
12510                                    buffer.set_completion_triggers(server_id, triggers, cx);
12511                                });
12512                            }
12513                        }
12514                        notify_server_capabilities_updated(&server, cx);
12515                    }
12516                }
12517                "textDocument/hover" => {
12518                    let options = parse_register_capabilities(reg)?;
12519                    let provider = match options {
12520                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12521                        OneOf::Right(caps) => caps,
12522                    };
12523                    server.update_capabilities(|capabilities| {
12524                        capabilities.hover_provider = Some(provider);
12525                    });
12526                    notify_server_capabilities_updated(&server, cx);
12527                }
12528                "textDocument/signatureHelp" => {
12529                    if let Some(caps) = reg
12530                        .register_options
12531                        .map(serde_json::from_value)
12532                        .transpose()?
12533                    {
12534                        server.update_capabilities(|capabilities| {
12535                            capabilities.signature_help_provider = Some(caps);
12536                        });
12537                        notify_server_capabilities_updated(&server, cx);
12538                    }
12539                }
12540                "textDocument/didChange" => {
12541                    if let Some(sync_kind) = reg
12542                        .register_options
12543                        .and_then(|opts| opts.get("syncKind").cloned())
12544                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12545                        .transpose()?
12546                    {
12547                        server.update_capabilities(|capabilities| {
12548                            let mut sync_options =
12549                                Self::take_text_document_sync_options(capabilities);
12550                            sync_options.change = Some(sync_kind);
12551                            capabilities.text_document_sync =
12552                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12553                        });
12554                        notify_server_capabilities_updated(&server, cx);
12555                    }
12556                }
12557                "textDocument/didSave" => {
12558                    if let Some(include_text) = reg
12559                        .register_options
12560                        .map(|opts| {
12561                            let transpose = opts
12562                                .get("includeText")
12563                                .cloned()
12564                                .map(serde_json::from_value::<Option<bool>>)
12565                                .transpose();
12566                            match transpose {
12567                                Ok(value) => Ok(value.flatten()),
12568                                Err(e) => Err(e),
12569                            }
12570                        })
12571                        .transpose()?
12572                    {
12573                        server.update_capabilities(|capabilities| {
12574                            let mut sync_options =
12575                                Self::take_text_document_sync_options(capabilities);
12576                            sync_options.save =
12577                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12578                                    include_text,
12579                                }));
12580                            capabilities.text_document_sync =
12581                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12582                        });
12583                        notify_server_capabilities_updated(&server, cx);
12584                    }
12585                }
12586                "textDocument/codeLens" => {
12587                    if let Some(caps) = reg
12588                        .register_options
12589                        .map(serde_json::from_value)
12590                        .transpose()?
12591                    {
12592                        server.update_capabilities(|capabilities| {
12593                            capabilities.code_lens_provider = Some(caps);
12594                        });
12595                        notify_server_capabilities_updated(&server, cx);
12596                    }
12597                }
12598                "textDocument/diagnostic" => {
12599                    if let Some(caps) = reg
12600                        .register_options
12601                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12602                        .transpose()?
12603                    {
12604                        let local = self
12605                            .as_local_mut()
12606                            .context("Expected LSP Store to be local")?;
12607                        let state = local
12608                            .language_servers
12609                            .get_mut(&server_id)
12610                            .context("Could not obtain Language Servers state")?;
12611                        local
12612                            .language_server_dynamic_registrations
12613                            .entry(server_id)
12614                            .or_default()
12615                            .diagnostics
12616                            .insert(Some(reg.id.clone()), caps.clone());
12617
12618                        let supports_workspace_diagnostics =
12619                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12620                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12621                                    diagnostic_options.workspace_diagnostics
12622                                }
12623                                DiagnosticServerCapabilities::RegistrationOptions(
12624                                    diagnostic_registration_options,
12625                                ) => {
12626                                    diagnostic_registration_options
12627                                        .diagnostic_options
12628                                        .workspace_diagnostics
12629                                }
12630                            };
12631
12632                        if supports_workspace_diagnostics(&caps) {
12633                            if let LanguageServerState::Running {
12634                                workspace_diagnostics_refresh_tasks,
12635                                ..
12636                            } = state
12637                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12638                                    Some(reg.id.clone()),
12639                                    caps.clone(),
12640                                    server.clone(),
12641                                    cx,
12642                                )
12643                            {
12644                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12645                            }
12646                        }
12647
12648                        server.update_capabilities(|capabilities| {
12649                            capabilities.diagnostic_provider = Some(caps);
12650                        });
12651
12652                        notify_server_capabilities_updated(&server, cx);
12653
12654                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12655                    }
12656                }
12657                "textDocument/documentColor" => {
12658                    let options = parse_register_capabilities(reg)?;
12659                    let provider = match options {
12660                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12661                        OneOf::Right(caps) => caps,
12662                    };
12663                    server.update_capabilities(|capabilities| {
12664                        capabilities.color_provider = Some(provider);
12665                    });
12666                    notify_server_capabilities_updated(&server, cx);
12667                }
12668                "textDocument/foldingRange" => {
12669                    let options = parse_register_capabilities(reg)?;
12670                    let provider = match options {
12671                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12672                        OneOf::Right(caps) => caps,
12673                    };
12674                    server.update_capabilities(|capabilities| {
12675                        capabilities.folding_range_provider = Some(provider);
12676                    });
12677                    notify_server_capabilities_updated(&server, cx);
12678                }
12679                _ => log::warn!("unhandled capability registration: {reg:?}"),
12680            }
12681        }
12682
12683        Ok(())
12684    }
12685
12686    fn unregister_server_capabilities(
12687        &mut self,
12688        server_id: LanguageServerId,
12689        params: lsp::UnregistrationParams,
12690        cx: &mut Context<Self>,
12691    ) -> anyhow::Result<()> {
12692        let server = self
12693            .language_server_for_id(server_id)
12694            .with_context(|| format!("no server {server_id} found"))?;
12695        for unreg in params.unregisterations.iter() {
12696            match unreg.method.as_str() {
12697                "workspace/didChangeWatchedFiles" => {
12698                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12699                        local_lsp_store
12700                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12701                        true
12702                    } else {
12703                        false
12704                    };
12705                    if notify {
12706                        notify_server_capabilities_updated(&server, cx);
12707                    }
12708                }
12709                "workspace/didChangeConfiguration" => {
12710                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12711                }
12712                "workspace/didChangeWorkspaceFolders" => {
12713                    server.update_capabilities(|capabilities| {
12714                        capabilities
12715                            .workspace
12716                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12717                                workspace_folders: None,
12718                                file_operations: None,
12719                            })
12720                            .workspace_folders = None;
12721                    });
12722                    notify_server_capabilities_updated(&server, cx);
12723                }
12724                "workspace/symbol" => {
12725                    server.update_capabilities(|capabilities| {
12726                        capabilities.workspace_symbol_provider = None
12727                    });
12728                    notify_server_capabilities_updated(&server, cx);
12729                }
12730                "workspace/fileOperations" => {
12731                    server.update_capabilities(|capabilities| {
12732                        capabilities
12733                            .workspace
12734                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12735                                workspace_folders: None,
12736                                file_operations: None,
12737                            })
12738                            .file_operations = None;
12739                    });
12740                    notify_server_capabilities_updated(&server, cx);
12741                }
12742                "workspace/executeCommand" => {
12743                    server.update_capabilities(|capabilities| {
12744                        capabilities.execute_command_provider = None;
12745                    });
12746                    notify_server_capabilities_updated(&server, cx);
12747                }
12748                "textDocument/rangeFormatting" => {
12749                    server.update_capabilities(|capabilities| {
12750                        capabilities.document_range_formatting_provider = None
12751                    });
12752                    notify_server_capabilities_updated(&server, cx);
12753                }
12754                "textDocument/onTypeFormatting" => {
12755                    server.update_capabilities(|capabilities| {
12756                        capabilities.document_on_type_formatting_provider = None;
12757                    });
12758                    notify_server_capabilities_updated(&server, cx);
12759                }
12760                "textDocument/formatting" => {
12761                    server.update_capabilities(|capabilities| {
12762                        capabilities.document_formatting_provider = None;
12763                    });
12764                    notify_server_capabilities_updated(&server, cx);
12765                }
12766                "textDocument/rename" => {
12767                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12768                    notify_server_capabilities_updated(&server, cx);
12769                }
12770                "textDocument/codeAction" => {
12771                    server.update_capabilities(|capabilities| {
12772                        capabilities.code_action_provider = None;
12773                    });
12774                    notify_server_capabilities_updated(&server, cx);
12775                }
12776                "textDocument/definition" => {
12777                    server.update_capabilities(|capabilities| {
12778                        capabilities.definition_provider = None;
12779                    });
12780                    notify_server_capabilities_updated(&server, cx);
12781                }
12782                "textDocument/completion" => {
12783                    server.update_capabilities(|capabilities| {
12784                        capabilities.completion_provider = None;
12785                    });
12786                    notify_server_capabilities_updated(&server, cx);
12787                }
12788                "textDocument/hover" => {
12789                    server.update_capabilities(|capabilities| {
12790                        capabilities.hover_provider = None;
12791                    });
12792                    notify_server_capabilities_updated(&server, cx);
12793                }
12794                "textDocument/signatureHelp" => {
12795                    server.update_capabilities(|capabilities| {
12796                        capabilities.signature_help_provider = None;
12797                    });
12798                    notify_server_capabilities_updated(&server, cx);
12799                }
12800                "textDocument/didChange" => {
12801                    server.update_capabilities(|capabilities| {
12802                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12803                        sync_options.change = None;
12804                        capabilities.text_document_sync =
12805                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12806                    });
12807                    notify_server_capabilities_updated(&server, cx);
12808                }
12809                "textDocument/didSave" => {
12810                    server.update_capabilities(|capabilities| {
12811                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12812                        sync_options.save = None;
12813                        capabilities.text_document_sync =
12814                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12815                    });
12816                    notify_server_capabilities_updated(&server, cx);
12817                }
12818                "textDocument/codeLens" => {
12819                    server.update_capabilities(|capabilities| {
12820                        capabilities.code_lens_provider = None;
12821                    });
12822                    notify_server_capabilities_updated(&server, cx);
12823                }
12824                "textDocument/diagnostic" => {
12825                    let local = self
12826                        .as_local_mut()
12827                        .context("Expected LSP Store to be local")?;
12828
12829                    let state = local
12830                        .language_servers
12831                        .get_mut(&server_id)
12832                        .context("Could not obtain Language Servers state")?;
12833                    let registrations = local
12834                        .language_server_dynamic_registrations
12835                        .get_mut(&server_id)
12836                        .with_context(|| {
12837                            format!("Expected dynamic registration to exist for server {server_id}")
12838                        })?;
12839                    registrations.diagnostics
12840                        .remove(&Some(unreg.id.clone()))
12841                        .with_context(|| format!(
12842                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12843                            unreg.id)
12844                        )?;
12845                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12846
12847                    if let LanguageServerState::Running {
12848                        workspace_diagnostics_refresh_tasks,
12849                        ..
12850                    } = state
12851                    {
12852                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12853                    }
12854
12855                    self.clear_unregistered_diagnostics(
12856                        server_id,
12857                        SharedString::from(unreg.id.clone()),
12858                        cx,
12859                    )?;
12860
12861                    if removed_last_diagnostic_provider {
12862                        server.update_capabilities(|capabilities| {
12863                            debug_assert!(capabilities.diagnostic_provider.is_some());
12864                            capabilities.diagnostic_provider = None;
12865                        });
12866                    }
12867
12868                    notify_server_capabilities_updated(&server, cx);
12869                }
12870                "textDocument/documentColor" => {
12871                    server.update_capabilities(|capabilities| {
12872                        capabilities.color_provider = None;
12873                    });
12874                    notify_server_capabilities_updated(&server, cx);
12875                }
12876                "textDocument/foldingRange" => {
12877                    server.update_capabilities(|capabilities| {
12878                        capabilities.folding_range_provider = None;
12879                    });
12880                    notify_server_capabilities_updated(&server, cx);
12881                }
12882                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12883            }
12884        }
12885
12886        Ok(())
12887    }
12888
12889    fn clear_unregistered_diagnostics(
12890        &mut self,
12891        server_id: LanguageServerId,
12892        cleared_registration_id: SharedString,
12893        cx: &mut Context<Self>,
12894    ) -> anyhow::Result<()> {
12895        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12896
12897        self.buffer_store.update(cx, |buffer_store, cx| {
12898            for buffer_handle in buffer_store.buffers() {
12899                let buffer = buffer_handle.read(cx);
12900                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12901                let Some(abs_path) = abs_path else {
12902                    continue;
12903                };
12904                affected_abs_paths.insert(abs_path);
12905            }
12906        });
12907
12908        let local = self.as_local().context("Expected LSP Store to be local")?;
12909        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12910            let Some(worktree) = self
12911                .worktree_store
12912                .read(cx)
12913                .worktree_for_id(*worktree_id, cx)
12914            else {
12915                continue;
12916            };
12917
12918            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12919                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12920                    let has_matching_registration =
12921                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12922                            entry.diagnostic.registration_id.as_ref()
12923                                == Some(&cleared_registration_id)
12924                        });
12925                    if has_matching_registration {
12926                        let abs_path = worktree.read(cx).absolutize(rel_path);
12927                        affected_abs_paths.insert(abs_path);
12928                    }
12929                }
12930            }
12931        }
12932
12933        if affected_abs_paths.is_empty() {
12934            return Ok(());
12935        }
12936
12937        // Send a fake diagnostic update which clears the state for the registration ID
12938        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12939            affected_abs_paths
12940                .into_iter()
12941                .map(|abs_path| DocumentDiagnosticsUpdate {
12942                    diagnostics: DocumentDiagnostics {
12943                        diagnostics: Vec::new(),
12944                        document_abs_path: abs_path,
12945                        version: None,
12946                    },
12947                    result_id: None,
12948                    registration_id: Some(cleared_registration_id.clone()),
12949                    server_id,
12950                    disk_based_sources: Cow::Borrowed(&[]),
12951                })
12952                .collect();
12953
12954        let merge_registration_id = cleared_registration_id.clone();
12955        self.merge_diagnostic_entries(
12956            clears,
12957            move |_, diagnostic, _| {
12958                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12959                    diagnostic.registration_id != Some(merge_registration_id.clone())
12960                } else {
12961                    true
12962                }
12963            },
12964            cx,
12965        )?;
12966
12967        Ok(())
12968    }
12969
12970    async fn deduplicate_range_based_lsp_requests<T>(
12971        lsp_store: &Entity<Self>,
12972        server_id: Option<LanguageServerId>,
12973        lsp_request_id: LspRequestId,
12974        proto_request: &T::ProtoRequest,
12975        range: Range<Anchor>,
12976        cx: &mut AsyncApp,
12977    ) -> Result<()>
12978    where
12979        T: LspCommand,
12980        T::ProtoRequest: proto::LspRequestMessage,
12981    {
12982        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12983        let version = deserialize_version(proto_request.buffer_version());
12984        let buffer = lsp_store.update(cx, |this, cx| {
12985            this.buffer_store.read(cx).get_existing(buffer_id)
12986        })?;
12987        buffer
12988            .update(cx, |buffer, _| buffer.wait_for_version(version))
12989            .await?;
12990        lsp_store.update(cx, |lsp_store, cx| {
12991            let buffer_snapshot = buffer.read(cx).snapshot();
12992            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12993            let chunks_queried_for = lsp_data
12994                .inlay_hints
12995                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12996                .collect::<Vec<_>>();
12997            match chunks_queried_for.as_slice() {
12998                &[chunk] => {
12999                    let key = LspKey {
13000                        request_type: TypeId::of::<T>(),
13001                        server_queried: server_id,
13002                    };
13003                    let previous_request = lsp_data
13004                        .chunk_lsp_requests
13005                        .entry(key)
13006                        .or_default()
13007                        .insert(chunk, lsp_request_id);
13008                    if let Some((previous_request, running_requests)) =
13009                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13010                    {
13011                        running_requests.remove(&previous_request);
13012                    }
13013                }
13014                _ambiguous_chunks => {
13015                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13016                    // there, a buffer version-based check will be performed and outdated requests discarded.
13017                }
13018            }
13019            anyhow::Ok(())
13020        })?;
13021
13022        Ok(())
13023    }
13024
13025    async fn query_lsp_locally<T>(
13026        lsp_store: Entity<Self>,
13027        for_server_id: Option<LanguageServerId>,
13028        sender_id: proto::PeerId,
13029        lsp_request_id: LspRequestId,
13030        proto_request: T::ProtoRequest,
13031        position: Option<Anchor>,
13032        cx: &mut AsyncApp,
13033    ) -> Result<()>
13034    where
13035        T: LspCommand + Clone,
13036        T::ProtoRequest: proto::LspRequestMessage,
13037        <T::ProtoRequest as proto::RequestMessage>::Response:
13038            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13039    {
13040        let (buffer_version, buffer) =
13041            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13042        let request =
13043            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13044        let key = LspKey {
13045            request_type: TypeId::of::<T>(),
13046            server_queried: for_server_id,
13047        };
13048        lsp_store.update(cx, |lsp_store, cx| {
13049            let request_task = match for_server_id {
13050                Some(server_id) => {
13051                    let server_task = lsp_store.request_lsp(
13052                        buffer.clone(),
13053                        LanguageServerToQuery::Other(server_id),
13054                        request.clone(),
13055                        cx,
13056                    );
13057                    cx.background_spawn(async move {
13058                        let mut responses = Vec::new();
13059                        match server_task.await {
13060                            Ok(response) => responses.push((server_id, response)),
13061                            // rust-analyzer likes to error with this when its still loading up
13062                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13063                            Err(e) => log::error!(
13064                                "Error handling response for request {request:?}: {e:#}"
13065                            ),
13066                        }
13067                        responses
13068                    })
13069                }
13070                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13071            };
13072            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13073            if T::ProtoRequest::stop_previous_requests() {
13074                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13075                    lsp_requests.clear();
13076                }
13077            }
13078            lsp_data.lsp_requests.entry(key).or_default().insert(
13079                lsp_request_id,
13080                cx.spawn(async move |lsp_store, cx| {
13081                    let response = request_task.await;
13082                    lsp_store
13083                        .update(cx, |lsp_store, cx| {
13084                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13085                            {
13086                                let response = response
13087                                    .into_iter()
13088                                    .map(|(server_id, response)| {
13089                                        (
13090                                            server_id.to_proto(),
13091                                            T::response_to_proto(
13092                                                response,
13093                                                lsp_store,
13094                                                sender_id,
13095                                                &buffer_version,
13096                                                cx,
13097                                            )
13098                                            .into(),
13099                                        )
13100                                    })
13101                                    .collect::<HashMap<_, _>>();
13102                                match client.send_lsp_response::<T::ProtoRequest>(
13103                                    project_id,
13104                                    lsp_request_id,
13105                                    response,
13106                                ) {
13107                                    Ok(()) => {}
13108                                    Err(e) => {
13109                                        log::error!("Failed to send LSP response: {e:#}",)
13110                                    }
13111                                }
13112                            }
13113                        })
13114                        .ok();
13115                }),
13116            );
13117        });
13118        Ok(())
13119    }
13120
13121    async fn wait_for_buffer_version<T>(
13122        lsp_store: &Entity<Self>,
13123        proto_request: &T::ProtoRequest,
13124        cx: &mut AsyncApp,
13125    ) -> Result<(Global, Entity<Buffer>)>
13126    where
13127        T: LspCommand,
13128        T::ProtoRequest: proto::LspRequestMessage,
13129    {
13130        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13131        let version = deserialize_version(proto_request.buffer_version());
13132        let buffer = lsp_store.update(cx, |this, cx| {
13133            this.buffer_store.read(cx).get_existing(buffer_id)
13134        })?;
13135        buffer
13136            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13137            .await?;
13138        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13139        Ok((buffer_version, buffer))
13140    }
13141
13142    fn take_text_document_sync_options(
13143        capabilities: &mut lsp::ServerCapabilities,
13144    ) -> lsp::TextDocumentSyncOptions {
13145        match capabilities.text_document_sync.take() {
13146            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13147            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13148                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13149                sync_options.change = Some(sync_kind);
13150                sync_options
13151            }
13152            None => lsp::TextDocumentSyncOptions::default(),
13153        }
13154    }
13155
13156    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13157        self.downstream_client.clone()
13158    }
13159
13160    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13161        self.worktree_store.clone()
13162    }
13163
13164    /// Gets what's stored in the LSP data for the given buffer.
13165    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13166        self.lsp_data.get_mut(&buffer_id)
13167    }
13168
13169    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13170    /// new [`BufferLspData`] will be created to replace the previous state.
13171    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13172        let (buffer_id, buffer_version) =
13173            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13174        let lsp_data = self
13175            .lsp_data
13176            .entry(buffer_id)
13177            .or_insert_with(|| BufferLspData::new(buffer, cx));
13178        if buffer_version.changed_since(&lsp_data.buffer_version) {
13179            // To send delta requests for semantic tokens, the previous tokens
13180            // need to be kept between buffer changes.
13181            let semantic_tokens = lsp_data.semantic_tokens.take();
13182            *lsp_data = BufferLspData::new(buffer, cx);
13183            lsp_data.semantic_tokens = semantic_tokens;
13184        }
13185        lsp_data
13186    }
13187}
13188
13189// Registration with registerOptions as null, should fallback to true.
13190// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13191fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13192    reg: lsp::Registration,
13193) -> Result<OneOf<bool, T>> {
13194    Ok(match reg.register_options {
13195        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13196        None => OneOf::Left(true),
13197    })
13198}
13199
13200fn subscribe_to_binary_statuses(
13201    languages: &Arc<LanguageRegistry>,
13202    cx: &mut Context<'_, LspStore>,
13203) -> Task<()> {
13204    let mut server_statuses = languages.language_server_binary_statuses();
13205    cx.spawn(async move |lsp_store, cx| {
13206        while let Some((server_name, binary_status)) = server_statuses.next().await {
13207            if lsp_store
13208                .update(cx, |_, cx| {
13209                    let mut message = None;
13210                    let binary_status = match binary_status {
13211                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13212                        BinaryStatus::CheckingForUpdate => {
13213                            proto::ServerBinaryStatus::CheckingForUpdate
13214                        }
13215                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13216                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13217                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13218                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13219                        BinaryStatus::Failed { error } => {
13220                            message = Some(error);
13221                            proto::ServerBinaryStatus::Failed
13222                        }
13223                    };
13224                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13225                        // Binary updates are about the binary that might not have any language server id at that point.
13226                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13227                        language_server_id: LanguageServerId(0),
13228                        name: Some(server_name),
13229                        message: proto::update_language_server::Variant::StatusUpdate(
13230                            proto::StatusUpdate {
13231                                message,
13232                                status: Some(proto::status_update::Status::Binary(
13233                                    binary_status as i32,
13234                                )),
13235                            },
13236                        ),
13237                    });
13238                })
13239                .is_err()
13240            {
13241                break;
13242            }
13243        }
13244    })
13245}
13246
13247fn lsp_workspace_diagnostics_refresh(
13248    registration_id: Option<String>,
13249    options: DiagnosticServerCapabilities,
13250    server: Arc<LanguageServer>,
13251    cx: &mut Context<'_, LspStore>,
13252) -> Option<WorkspaceRefreshTask> {
13253    let identifier = workspace_diagnostic_identifier(&options)?;
13254    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13255
13256    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13257    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13258    refresh_tx.try_send(()).ok();
13259
13260    let request_timeout = ProjectSettings::get_global(cx)
13261        .global_lsp_settings
13262        .get_request_timeout();
13263
13264    // 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.
13265    // This allows users to increase the duration if need be
13266    let timeout = if request_timeout != Duration::ZERO {
13267        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13268    } else {
13269        request_timeout
13270    };
13271
13272    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13273        let mut attempts = 0;
13274        let max_attempts = 50;
13275        let mut requests = 0;
13276
13277        loop {
13278            let Some(()) = refresh_rx.recv().await else {
13279                return;
13280            };
13281
13282            'request: loop {
13283                requests += 1;
13284                if attempts > max_attempts {
13285                    log::error!(
13286                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13287                    );
13288                    return;
13289                }
13290                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13291                cx.background_executor()
13292                    .timer(Duration::from_millis(backoff_millis))
13293                    .await;
13294                attempts += 1;
13295
13296                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13297                    lsp_store
13298                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13299                        .into_iter()
13300                        .filter_map(|(abs_path, result_id)| {
13301                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13302                            Some(lsp::PreviousResultId {
13303                                uri,
13304                                value: result_id.to_string(),
13305                            })
13306                        })
13307                        .collect()
13308                }) else {
13309                    return;
13310                };
13311
13312                let token = if let Some(registration_id) = &registration_id {
13313                    format!(
13314                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13315                        server.server_id(),
13316                    )
13317                } else {
13318                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13319                };
13320
13321                progress_rx.try_recv().ok();
13322                let timer = server.request_timer(timeout).fuse();
13323                let progress = pin!(progress_rx.recv().fuse());
13324                let response_result = server
13325                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13326                        lsp::WorkspaceDiagnosticParams {
13327                            previous_result_ids,
13328                            identifier: identifier.clone(),
13329                            work_done_progress_params: Default::default(),
13330                            partial_result_params: lsp::PartialResultParams {
13331                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13332                            },
13333                        },
13334                        select(timer, progress).then(|either| match either {
13335                            Either::Left((message, ..)) => ready(message).left_future(),
13336                            Either::Right(..) => pending::<String>().right_future(),
13337                        }),
13338                    )
13339                    .await;
13340
13341                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13342                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13343                match response_result {
13344                    ConnectionResult::Timeout => {
13345                        log::error!("Timeout during workspace diagnostics pull");
13346                        continue 'request;
13347                    }
13348                    ConnectionResult::ConnectionReset => {
13349                        log::error!("Server closed a workspace diagnostics pull request");
13350                        continue 'request;
13351                    }
13352                    ConnectionResult::Result(Err(e)) => {
13353                        log::error!("Error during workspace diagnostics pull: {e:#}");
13354                        break 'request;
13355                    }
13356                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13357                        attempts = 0;
13358                        if lsp_store
13359                            .update(cx, |lsp_store, cx| {
13360                                lsp_store.apply_workspace_diagnostic_report(
13361                                    server.server_id(),
13362                                    pulled_diagnostics,
13363                                    registration_id_shared.clone(),
13364                                    cx,
13365                                )
13366                            })
13367                            .is_err()
13368                        {
13369                            return;
13370                        }
13371                        break 'request;
13372                    }
13373                }
13374            }
13375        }
13376    });
13377
13378    Some(WorkspaceRefreshTask {
13379        refresh_tx,
13380        progress_tx,
13381        task: workspace_query_language_server,
13382    })
13383}
13384
13385fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13386    match &options {
13387        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13388            .identifier
13389            .as_deref()
13390            .map(SharedString::new),
13391        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13392            let diagnostic_options = &registration_options.diagnostic_options;
13393            diagnostic_options
13394                .identifier
13395                .as_deref()
13396                .map(SharedString::new)
13397        }
13398    }
13399}
13400
13401fn workspace_diagnostic_identifier(
13402    options: &DiagnosticServerCapabilities,
13403) -> Option<Option<String>> {
13404    match &options {
13405        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13406            if !diagnostic_options.workspace_diagnostics {
13407                return None;
13408            }
13409            Some(diagnostic_options.identifier.clone())
13410        }
13411        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13412            let diagnostic_options = &registration_options.diagnostic_options;
13413            if !diagnostic_options.workspace_diagnostics {
13414                return None;
13415            }
13416            Some(diagnostic_options.identifier.clone())
13417        }
13418    }
13419}
13420
13421fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13422    let CompletionSource::BufferWord {
13423        word_range,
13424        resolved,
13425    } = &mut completion.source
13426    else {
13427        return;
13428    };
13429    if *resolved {
13430        return;
13431    }
13432
13433    if completion.new_text
13434        != snapshot
13435            .text_for_range(word_range.clone())
13436            .collect::<String>()
13437    {
13438        return;
13439    }
13440
13441    let mut offset = 0;
13442    for chunk in snapshot.chunks(word_range.clone(), true) {
13443        let end_offset = offset + chunk.text.len();
13444        if let Some(highlight_id) = chunk.syntax_highlight_id {
13445            completion
13446                .label
13447                .runs
13448                .push((offset..end_offset, highlight_id));
13449        }
13450        offset = end_offset;
13451    }
13452    *resolved = true;
13453}
13454
13455impl EventEmitter<LspStoreEvent> for LspStore {}
13456
13457fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13458    hover
13459        .contents
13460        .retain(|hover_block| !hover_block.text.trim().is_empty());
13461    if hover.contents.is_empty() {
13462        None
13463    } else {
13464        Some(hover)
13465    }
13466}
13467
13468async fn populate_labels_for_completions(
13469    new_completions: Vec<CoreCompletion>,
13470    language: Option<Arc<Language>>,
13471    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13472) -> Vec<Completion> {
13473    let lsp_completions = new_completions
13474        .iter()
13475        .filter_map(|new_completion| {
13476            new_completion
13477                .source
13478                .lsp_completion(true)
13479                .map(|lsp_completion| lsp_completion.into_owned())
13480        })
13481        .collect::<Vec<_>>();
13482
13483    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13484        lsp_adapter
13485            .labels_for_completions(&lsp_completions, language)
13486            .await
13487            .log_err()
13488            .unwrap_or_default()
13489    } else {
13490        Vec::new()
13491    }
13492    .into_iter()
13493    .fuse();
13494
13495    let mut completions = Vec::new();
13496    for completion in new_completions {
13497        match completion.source.lsp_completion(true) {
13498            Some(lsp_completion) => {
13499                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13500
13501                let mut label = labels.next().flatten().unwrap_or_else(|| {
13502                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13503                });
13504                ensure_uniform_list_compatible_label(&mut label);
13505                completions.push(Completion {
13506                    label,
13507                    documentation,
13508                    replace_range: completion.replace_range,
13509                    new_text: completion.new_text,
13510                    insert_text_mode: lsp_completion.insert_text_mode,
13511                    source: completion.source,
13512                    icon_path: None,
13513                    confirm: None,
13514                    match_start: None,
13515                    snippet_deduplication_key: None,
13516                });
13517            }
13518            None => {
13519                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13520                ensure_uniform_list_compatible_label(&mut label);
13521                completions.push(Completion {
13522                    label,
13523                    documentation: None,
13524                    replace_range: completion.replace_range,
13525                    new_text: completion.new_text,
13526                    source: completion.source,
13527                    insert_text_mode: None,
13528                    icon_path: None,
13529                    confirm: None,
13530                    match_start: None,
13531                    snippet_deduplication_key: None,
13532                });
13533            }
13534        }
13535    }
13536    completions
13537}
13538
13539#[derive(Debug)]
13540pub enum LanguageServerToQuery {
13541    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13542    FirstCapable,
13543    /// Query a specific language server.
13544    Other(LanguageServerId),
13545}
13546
13547#[derive(Default)]
13548struct RenamePathsWatchedForServer {
13549    did_rename: Vec<RenameActionPredicate>,
13550    will_rename: Vec<RenameActionPredicate>,
13551}
13552
13553impl RenamePathsWatchedForServer {
13554    fn with_did_rename_patterns(
13555        mut self,
13556        did_rename: Option<&FileOperationRegistrationOptions>,
13557    ) -> Self {
13558        if let Some(did_rename) = did_rename {
13559            self.did_rename = did_rename
13560                .filters
13561                .iter()
13562                .filter_map(|filter| filter.try_into().log_err())
13563                .collect();
13564        }
13565        self
13566    }
13567    fn with_will_rename_patterns(
13568        mut self,
13569        will_rename: Option<&FileOperationRegistrationOptions>,
13570    ) -> Self {
13571        if let Some(will_rename) = will_rename {
13572            self.will_rename = will_rename
13573                .filters
13574                .iter()
13575                .filter_map(|filter| filter.try_into().log_err())
13576                .collect();
13577        }
13578        self
13579    }
13580
13581    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13582        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13583    }
13584    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13585        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13586    }
13587}
13588
13589impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13590    type Error = globset::Error;
13591    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13592        Ok(Self {
13593            kind: ops.pattern.matches.clone(),
13594            glob: GlobBuilder::new(&ops.pattern.glob)
13595                .case_insensitive(
13596                    ops.pattern
13597                        .options
13598                        .as_ref()
13599                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13600                )
13601                .build()?
13602                .compile_matcher(),
13603        })
13604    }
13605}
13606struct RenameActionPredicate {
13607    glob: GlobMatcher,
13608    kind: Option<FileOperationPatternKind>,
13609}
13610
13611impl RenameActionPredicate {
13612    // Returns true if language server should be notified
13613    fn eval(&self, path: &str, is_dir: bool) -> bool {
13614        self.kind.as_ref().is_none_or(|kind| {
13615            let expected_kind = if is_dir {
13616                FileOperationPatternKind::Folder
13617            } else {
13618                FileOperationPatternKind::File
13619            };
13620            kind == &expected_kind
13621        }) && self.glob.is_match(path)
13622    }
13623}
13624
13625#[derive(Default)]
13626struct LanguageServerWatchedPaths {
13627    worktree_paths: HashMap<WorktreeId, GlobSet>,
13628    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13629}
13630
13631#[derive(Default)]
13632struct LanguageServerWatchedPathsBuilder {
13633    worktree_paths: HashMap<WorktreeId, GlobSet>,
13634    abs_paths: HashMap<Arc<Path>, GlobSet>,
13635}
13636
13637impl LanguageServerWatchedPathsBuilder {
13638    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13639        self.worktree_paths.insert(worktree_id, glob_set);
13640    }
13641    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13642        self.abs_paths.insert(path, glob_set);
13643    }
13644    fn build(
13645        self,
13646        fs: Arc<dyn Fs>,
13647        language_server_id: LanguageServerId,
13648        cx: &mut Context<LspStore>,
13649    ) -> LanguageServerWatchedPaths {
13650        let lsp_store = cx.weak_entity();
13651
13652        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13653        let abs_paths = self
13654            .abs_paths
13655            .into_iter()
13656            .map(|(abs_path, globset)| {
13657                let task = cx.spawn({
13658                    let abs_path = abs_path.clone();
13659                    let fs = fs.clone();
13660
13661                    let lsp_store = lsp_store.clone();
13662                    async move |_, cx| {
13663                        maybe!(async move {
13664                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13665                            while let Some(update) = push_updates.0.next().await {
13666                                let action = lsp_store
13667                                    .update(cx, |this, _| {
13668                                        let Some(local) = this.as_local() else {
13669                                            return ControlFlow::Break(());
13670                                        };
13671                                        let Some(watcher) = local
13672                                            .language_server_watched_paths
13673                                            .get(&language_server_id)
13674                                        else {
13675                                            return ControlFlow::Break(());
13676                                        };
13677                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13678                                            "Watched abs path is not registered with a watcher",
13679                                        );
13680                                        let matching_entries = update
13681                                            .into_iter()
13682                                            .filter(|event| globs.is_match(&event.path))
13683                                            .collect::<Vec<_>>();
13684                                        this.lsp_notify_abs_paths_changed(
13685                                            language_server_id,
13686                                            matching_entries,
13687                                        );
13688                                        ControlFlow::Continue(())
13689                                    })
13690                                    .ok()?;
13691
13692                                if action.is_break() {
13693                                    break;
13694                                }
13695                            }
13696                            Some(())
13697                        })
13698                        .await;
13699                    }
13700                });
13701                (abs_path, (globset, task))
13702            })
13703            .collect();
13704        LanguageServerWatchedPaths {
13705            worktree_paths: self.worktree_paths,
13706            abs_paths,
13707        }
13708    }
13709}
13710
13711struct LspBufferSnapshot {
13712    version: i32,
13713    snapshot: TextBufferSnapshot,
13714}
13715
13716/// A prompt requested by LSP server.
13717#[derive(Clone, Debug)]
13718pub struct LanguageServerPromptRequest {
13719    pub id: usize,
13720    pub level: PromptLevel,
13721    pub message: String,
13722    pub actions: Vec<MessageActionItem>,
13723    pub lsp_name: String,
13724    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13725}
13726
13727impl LanguageServerPromptRequest {
13728    pub fn new(
13729        level: PromptLevel,
13730        message: String,
13731        actions: Vec<MessageActionItem>,
13732        lsp_name: String,
13733        response_channel: smol::channel::Sender<MessageActionItem>,
13734    ) -> Self {
13735        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13736        LanguageServerPromptRequest {
13737            id,
13738            level,
13739            message,
13740            actions,
13741            lsp_name,
13742            response_channel,
13743        }
13744    }
13745    pub async fn respond(self, index: usize) -> Option<()> {
13746        if let Some(response) = self.actions.into_iter().nth(index) {
13747            self.response_channel.send(response).await.ok()
13748        } else {
13749            None
13750        }
13751    }
13752
13753    #[cfg(any(test, feature = "test-support"))]
13754    pub fn test(
13755        level: PromptLevel,
13756        message: String,
13757        actions: Vec<MessageActionItem>,
13758        lsp_name: String,
13759    ) -> Self {
13760        let (tx, _rx) = smol::channel::unbounded();
13761        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13762    }
13763}
13764impl PartialEq for LanguageServerPromptRequest {
13765    fn eq(&self, other: &Self) -> bool {
13766        self.message == other.message && self.actions == other.actions
13767    }
13768}
13769
13770#[derive(Clone, Debug, PartialEq)]
13771pub enum LanguageServerLogType {
13772    Log(MessageType),
13773    Trace { verbose_info: Option<String> },
13774    Rpc { received: bool },
13775}
13776
13777impl LanguageServerLogType {
13778    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13779        match self {
13780            Self::Log(log_type) => {
13781                use proto::log_message::LogLevel;
13782                let level = match *log_type {
13783                    MessageType::ERROR => LogLevel::Error,
13784                    MessageType::WARNING => LogLevel::Warning,
13785                    MessageType::INFO => LogLevel::Info,
13786                    MessageType::LOG => LogLevel::Log,
13787                    other => {
13788                        log::warn!("Unknown lsp log message type: {other:?}");
13789                        LogLevel::Log
13790                    }
13791                };
13792                proto::language_server_log::LogType::Log(proto::LogMessage {
13793                    level: level as i32,
13794                })
13795            }
13796            Self::Trace { verbose_info } => {
13797                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13798                    verbose_info: verbose_info.to_owned(),
13799                })
13800            }
13801            Self::Rpc { received } => {
13802                let kind = if *received {
13803                    proto::rpc_message::Kind::Received
13804                } else {
13805                    proto::rpc_message::Kind::Sent
13806                };
13807                let kind = kind as i32;
13808                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13809            }
13810        }
13811    }
13812
13813    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13814        use proto::log_message::LogLevel;
13815        use proto::rpc_message;
13816        match log_type {
13817            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13818                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13819                    LogLevel::Error => MessageType::ERROR,
13820                    LogLevel::Warning => MessageType::WARNING,
13821                    LogLevel::Info => MessageType::INFO,
13822                    LogLevel::Log => MessageType::LOG,
13823                },
13824            ),
13825            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13826                verbose_info: trace_message.verbose_info,
13827            },
13828            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13829                received: match rpc_message::Kind::from_i32(message.kind)
13830                    .unwrap_or(rpc_message::Kind::Received)
13831                {
13832                    rpc_message::Kind::Received => true,
13833                    rpc_message::Kind::Sent => false,
13834                },
13835            },
13836        }
13837    }
13838}
13839
13840pub struct WorkspaceRefreshTask {
13841    refresh_tx: mpsc::Sender<()>,
13842    progress_tx: mpsc::Sender<()>,
13843    #[allow(dead_code)]
13844    task: Task<()>,
13845}
13846
13847pub enum LanguageServerState {
13848    Starting {
13849        startup: Task<Option<Arc<LanguageServer>>>,
13850        /// List of language servers that will be added to the workspace once it's initialization completes.
13851        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13852    },
13853
13854    Running {
13855        adapter: Arc<CachedLspAdapter>,
13856        server: Arc<LanguageServer>,
13857        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13858        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13859    },
13860}
13861
13862impl LanguageServerState {
13863    fn add_workspace_folder(&self, uri: Uri) {
13864        match self {
13865            LanguageServerState::Starting {
13866                pending_workspace_folders,
13867                ..
13868            } => {
13869                pending_workspace_folders.lock().insert(uri);
13870            }
13871            LanguageServerState::Running { server, .. } => {
13872                server.add_workspace_folder(uri);
13873            }
13874        }
13875    }
13876    fn _remove_workspace_folder(&self, uri: Uri) {
13877        match self {
13878            LanguageServerState::Starting {
13879                pending_workspace_folders,
13880                ..
13881            } => {
13882                pending_workspace_folders.lock().remove(&uri);
13883            }
13884            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13885        }
13886    }
13887}
13888
13889impl std::fmt::Debug for LanguageServerState {
13890    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13891        match self {
13892            LanguageServerState::Starting { .. } => {
13893                f.debug_struct("LanguageServerState::Starting").finish()
13894            }
13895            LanguageServerState::Running { .. } => {
13896                f.debug_struct("LanguageServerState::Running").finish()
13897            }
13898        }
13899    }
13900}
13901
13902#[derive(Clone, Debug, Serialize)]
13903pub struct LanguageServerProgress {
13904    pub is_disk_based_diagnostics_progress: bool,
13905    pub is_cancellable: bool,
13906    pub title: Option<String>,
13907    pub message: Option<String>,
13908    pub percentage: Option<usize>,
13909    #[serde(skip_serializing)]
13910    pub last_update_at: Instant,
13911}
13912
13913#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13914pub struct DiagnosticSummary {
13915    pub error_count: usize,
13916    pub warning_count: usize,
13917}
13918
13919impl DiagnosticSummary {
13920    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13921        let mut this = Self {
13922            error_count: 0,
13923            warning_count: 0,
13924        };
13925
13926        for entry in diagnostics {
13927            if entry.diagnostic.is_primary {
13928                match entry.diagnostic.severity {
13929                    DiagnosticSeverity::ERROR => this.error_count += 1,
13930                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13931                    _ => {}
13932                }
13933            }
13934        }
13935
13936        this
13937    }
13938
13939    pub fn is_empty(&self) -> bool {
13940        self.error_count == 0 && self.warning_count == 0
13941    }
13942
13943    pub fn to_proto(
13944        self,
13945        language_server_id: LanguageServerId,
13946        path: &RelPath,
13947    ) -> proto::DiagnosticSummary {
13948        proto::DiagnosticSummary {
13949            path: path.to_proto(),
13950            language_server_id: language_server_id.0 as u64,
13951            error_count: self.error_count as u32,
13952            warning_count: self.warning_count as u32,
13953        }
13954    }
13955}
13956
13957#[derive(Clone, Debug)]
13958pub enum CompletionDocumentation {
13959    /// There is no documentation for this completion.
13960    Undocumented,
13961    /// A single line of documentation.
13962    SingleLine(SharedString),
13963    /// Multiple lines of plain text documentation.
13964    MultiLinePlainText(SharedString),
13965    /// Markdown documentation.
13966    MultiLineMarkdown(SharedString),
13967    /// Both single line and multiple lines of plain text documentation.
13968    SingleLineAndMultiLinePlainText {
13969        single_line: SharedString,
13970        plain_text: Option<SharedString>,
13971    },
13972}
13973
13974impl CompletionDocumentation {
13975    #[cfg(any(test, feature = "test-support"))]
13976    pub fn text(&self) -> SharedString {
13977        match self {
13978            CompletionDocumentation::Undocumented => "".into(),
13979            CompletionDocumentation::SingleLine(s) => s.clone(),
13980            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13981            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13982            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13983                single_line.clone()
13984            }
13985        }
13986    }
13987}
13988
13989impl From<lsp::Documentation> for CompletionDocumentation {
13990    fn from(docs: lsp::Documentation) -> Self {
13991        match docs {
13992            lsp::Documentation::String(text) => {
13993                if text.lines().count() <= 1 {
13994                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13995                } else {
13996                    CompletionDocumentation::MultiLinePlainText(text.into())
13997                }
13998            }
13999
14000            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14001                lsp::MarkupKind::PlainText => {
14002                    if value.lines().count() <= 1 {
14003                        CompletionDocumentation::SingleLine(value.into())
14004                    } else {
14005                        CompletionDocumentation::MultiLinePlainText(value.into())
14006                    }
14007                }
14008
14009                lsp::MarkupKind::Markdown => {
14010                    CompletionDocumentation::MultiLineMarkdown(value.into())
14011                }
14012            },
14013        }
14014    }
14015}
14016
14017pub enum ResolvedHint {
14018    Resolved(InlayHint),
14019    Resolving(Shared<Task<()>>),
14020}
14021
14022pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14023    glob.components()
14024        .take_while(|component| match component {
14025            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14026            _ => true,
14027        })
14028        .collect()
14029}
14030
14031pub struct SshLspAdapter {
14032    name: LanguageServerName,
14033    binary: LanguageServerBinary,
14034    initialization_options: Option<String>,
14035    code_action_kinds: Option<Vec<CodeActionKind>>,
14036}
14037
14038impl SshLspAdapter {
14039    pub fn new(
14040        name: LanguageServerName,
14041        binary: LanguageServerBinary,
14042        initialization_options: Option<String>,
14043        code_action_kinds: Option<String>,
14044    ) -> Self {
14045        Self {
14046            name,
14047            binary,
14048            initialization_options,
14049            code_action_kinds: code_action_kinds
14050                .as_ref()
14051                .and_then(|c| serde_json::from_str(c).ok()),
14052        }
14053    }
14054}
14055
14056impl LspInstaller for SshLspAdapter {
14057    type BinaryVersion = ();
14058    async fn check_if_user_installed(
14059        &self,
14060        _: &dyn LspAdapterDelegate,
14061        _: Option<Toolchain>,
14062        _: &AsyncApp,
14063    ) -> Option<LanguageServerBinary> {
14064        Some(self.binary.clone())
14065    }
14066
14067    async fn cached_server_binary(
14068        &self,
14069        _: PathBuf,
14070        _: &dyn LspAdapterDelegate,
14071    ) -> Option<LanguageServerBinary> {
14072        None
14073    }
14074
14075    async fn fetch_latest_server_version(
14076        &self,
14077        _: &dyn LspAdapterDelegate,
14078        _: bool,
14079        _: &mut AsyncApp,
14080    ) -> Result<()> {
14081        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14082    }
14083
14084    async fn fetch_server_binary(
14085        &self,
14086        _: (),
14087        _: PathBuf,
14088        _: &dyn LspAdapterDelegate,
14089    ) -> Result<LanguageServerBinary> {
14090        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14091    }
14092}
14093
14094#[async_trait(?Send)]
14095impl LspAdapter for SshLspAdapter {
14096    fn name(&self) -> LanguageServerName {
14097        self.name.clone()
14098    }
14099
14100    async fn initialization_options(
14101        self: Arc<Self>,
14102        _: &Arc<dyn LspAdapterDelegate>,
14103        _: &mut AsyncApp,
14104    ) -> Result<Option<serde_json::Value>> {
14105        let Some(options) = &self.initialization_options else {
14106            return Ok(None);
14107        };
14108        let result = serde_json::from_str(options)?;
14109        Ok(result)
14110    }
14111
14112    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14113        self.code_action_kinds.clone()
14114    }
14115}
14116
14117pub fn language_server_settings<'a>(
14118    delegate: &'a dyn LspAdapterDelegate,
14119    language: &LanguageServerName,
14120    cx: &'a App,
14121) -> Option<&'a LspSettings> {
14122    language_server_settings_for(
14123        SettingsLocation {
14124            worktree_id: delegate.worktree_id(),
14125            path: RelPath::empty(),
14126        },
14127        language,
14128        cx,
14129    )
14130}
14131
14132pub fn language_server_settings_for<'a>(
14133    location: SettingsLocation<'a>,
14134    language: &LanguageServerName,
14135    cx: &'a App,
14136) -> Option<&'a LspSettings> {
14137    ProjectSettings::get(Some(location), cx).lsp.get(language)
14138}
14139
14140pub struct LocalLspAdapterDelegate {
14141    lsp_store: WeakEntity<LspStore>,
14142    worktree: worktree::Snapshot,
14143    fs: Arc<dyn Fs>,
14144    http_client: Arc<dyn HttpClient>,
14145    language_registry: Arc<LanguageRegistry>,
14146    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14147}
14148
14149impl LocalLspAdapterDelegate {
14150    pub fn new(
14151        language_registry: Arc<LanguageRegistry>,
14152        environment: &Entity<ProjectEnvironment>,
14153        lsp_store: WeakEntity<LspStore>,
14154        worktree: &Entity<Worktree>,
14155        http_client: Arc<dyn HttpClient>,
14156        fs: Arc<dyn Fs>,
14157        cx: &mut App,
14158    ) -> Arc<Self> {
14159        let load_shell_env_task =
14160            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14161
14162        Arc::new(Self {
14163            lsp_store,
14164            worktree: worktree.read(cx).snapshot(),
14165            fs,
14166            http_client,
14167            language_registry,
14168            load_shell_env_task,
14169        })
14170    }
14171
14172    pub fn from_local_lsp(
14173        local: &LocalLspStore,
14174        worktree: &Entity<Worktree>,
14175        cx: &mut App,
14176    ) -> Arc<Self> {
14177        Self::new(
14178            local.languages.clone(),
14179            &local.environment,
14180            local.weak.clone(),
14181            worktree,
14182            local.http_client.clone(),
14183            local.fs.clone(),
14184            cx,
14185        )
14186    }
14187}
14188
14189#[async_trait]
14190impl LspAdapterDelegate for LocalLspAdapterDelegate {
14191    fn show_notification(&self, message: &str, cx: &mut App) {
14192        self.lsp_store
14193            .update(cx, |_, cx| {
14194                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14195            })
14196            .ok();
14197    }
14198
14199    fn http_client(&self) -> Arc<dyn HttpClient> {
14200        self.http_client.clone()
14201    }
14202
14203    fn worktree_id(&self) -> WorktreeId {
14204        self.worktree.id()
14205    }
14206
14207    fn worktree_root_path(&self) -> &Path {
14208        self.worktree.abs_path().as_ref()
14209    }
14210
14211    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14212        self.worktree.resolve_relative_path(path)
14213    }
14214
14215    async fn shell_env(&self) -> HashMap<String, String> {
14216        let task = self.load_shell_env_task.clone();
14217        task.await.unwrap_or_default()
14218    }
14219
14220    async fn npm_package_installed_version(
14221        &self,
14222        package_name: &str,
14223    ) -> Result<Option<(PathBuf, Version)>> {
14224        let local_package_directory = self.worktree_root_path();
14225        let node_modules_directory = local_package_directory.join("node_modules");
14226
14227        if let Some(version) =
14228            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14229        {
14230            return Ok(Some((node_modules_directory, version)));
14231        }
14232        let Some(npm) = self.which("npm".as_ref()).await else {
14233            log::warn!(
14234                "Failed to find npm executable for {:?}",
14235                local_package_directory
14236            );
14237            return Ok(None);
14238        };
14239
14240        let env = self.shell_env().await;
14241        let output = util::command::new_command(&npm)
14242            .args(["root", "-g"])
14243            .envs(env)
14244            .current_dir(local_package_directory)
14245            .output()
14246            .await?;
14247        let global_node_modules =
14248            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14249
14250        if let Some(version) =
14251            read_package_installed_version(global_node_modules.clone(), package_name).await?
14252        {
14253            return Ok(Some((global_node_modules, version)));
14254        }
14255        return Ok(None);
14256    }
14257
14258    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14259        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14260        if self.fs.is_file(&worktree_abs_path).await {
14261            worktree_abs_path.pop();
14262        }
14263
14264        let env = self.shell_env().await;
14265
14266        let shell_path = env.get("PATH").cloned();
14267
14268        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14269    }
14270
14271    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14272        let mut working_dir = self.worktree_root_path().to_path_buf();
14273        if self.fs.is_file(&working_dir).await {
14274            working_dir.pop();
14275        }
14276        let output = util::command::new_command(&command.path)
14277            .args(command.arguments)
14278            .envs(command.env.clone().unwrap_or_default())
14279            .current_dir(working_dir)
14280            .output()
14281            .await?;
14282
14283        anyhow::ensure!(
14284            output.status.success(),
14285            "{}, stdout: {:?}, stderr: {:?}",
14286            output.status,
14287            String::from_utf8_lossy(&output.stdout),
14288            String::from_utf8_lossy(&output.stderr)
14289        );
14290        Ok(())
14291    }
14292
14293    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14294        self.language_registry
14295            .update_lsp_binary_status(server_name, status);
14296    }
14297
14298    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14299        self.language_registry
14300            .all_lsp_adapters()
14301            .into_iter()
14302            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14303            .collect()
14304    }
14305
14306    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14307        let dir = self.language_registry.language_server_download_dir(name)?;
14308
14309        if !dir.exists() {
14310            smol::fs::create_dir_all(&dir)
14311                .await
14312                .context("failed to create container directory")
14313                .log_err()?;
14314        }
14315
14316        Some(dir)
14317    }
14318
14319    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14320        let entry = self
14321            .worktree
14322            .entry_for_path(path)
14323            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14324        let abs_path = self.worktree.absolutize(&entry.path);
14325        self.fs.load(&abs_path).await
14326    }
14327}
14328
14329async fn populate_labels_for_symbols(
14330    symbols: Vec<CoreSymbol>,
14331    language_registry: &Arc<LanguageRegistry>,
14332    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14333    output: &mut Vec<Symbol>,
14334) {
14335    #[allow(clippy::mutable_key_type)]
14336    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14337
14338    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14339    for symbol in symbols {
14340        let Some(file_name) = symbol.path.file_name() else {
14341            continue;
14342        };
14343        let language = language_registry
14344            .load_language_for_file_path(Path::new(file_name))
14345            .await
14346            .ok()
14347            .or_else(|| {
14348                unknown_paths.insert(file_name.into());
14349                None
14350            });
14351        symbols_by_language
14352            .entry(language)
14353            .or_default()
14354            .push(symbol);
14355    }
14356
14357    for unknown_path in unknown_paths {
14358        log::info!("no language found for symbol in file {unknown_path:?}");
14359    }
14360
14361    let mut label_params = Vec::new();
14362    for (language, mut symbols) in symbols_by_language {
14363        label_params.clear();
14364        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14365            name: mem::take(&mut symbol.name),
14366            kind: symbol.kind,
14367            container_name: symbol.container_name.take(),
14368        }));
14369
14370        let mut labels = Vec::new();
14371        if let Some(language) = language {
14372            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14373                language_registry
14374                    .lsp_adapters(&language.name())
14375                    .first()
14376                    .cloned()
14377            });
14378            if let Some(lsp_adapter) = lsp_adapter {
14379                labels = lsp_adapter
14380                    .labels_for_symbols(&label_params, &language)
14381                    .await
14382                    .log_err()
14383                    .unwrap_or_default();
14384            }
14385        }
14386
14387        for (
14388            (
14389                symbol,
14390                language::Symbol {
14391                    name,
14392                    container_name,
14393                    ..
14394                },
14395            ),
14396            label,
14397        ) in symbols
14398            .into_iter()
14399            .zip(label_params.drain(..))
14400            .zip(labels.into_iter().chain(iter::repeat(None)))
14401        {
14402            output.push(Symbol {
14403                language_server_name: symbol.language_server_name,
14404                source_worktree_id: symbol.source_worktree_id,
14405                source_language_server_id: symbol.source_language_server_id,
14406                path: symbol.path,
14407                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14408                name,
14409                kind: symbol.kind,
14410                range: symbol.range,
14411                container_name,
14412            });
14413        }
14414    }
14415}
14416
14417pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14418    text.lines()
14419        .map(|line| line.trim())
14420        .filter(|line| !line.is_empty())
14421        .join(separator)
14422}
14423
14424fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14425    match server.capabilities().text_document_sync.as_ref()? {
14426        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14427            // Server wants didSave but didn't specify includeText.
14428            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14429            // Server doesn't want didSave at all.
14430            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14431            // Server provided SaveOptions.
14432            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14433                Some(save_options.include_text.unwrap_or(false))
14434            }
14435        },
14436        // We do not have any save info. Kind affects didChange only.
14437        lsp::TextDocumentSyncCapability::Kind(_) => None,
14438    }
14439}
14440
14441/// Completion items are displayed in a `UniformList`.
14442/// Usually, those items are single-line strings, but in LSP responses,
14443/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14444/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14445/// 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,
14446/// breaking the completions menu presentation.
14447///
14448/// 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.
14449pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14450    let mut new_text = String::with_capacity(label.text.len());
14451    let mut offset_map = vec![0; label.text.len() + 1];
14452    let mut last_char_was_space = false;
14453    let mut new_idx = 0;
14454    let chars = label.text.char_indices().fuse();
14455    let mut newlines_removed = false;
14456
14457    for (idx, c) in chars {
14458        offset_map[idx] = new_idx;
14459
14460        match c {
14461            '\n' if last_char_was_space => {
14462                newlines_removed = true;
14463            }
14464            '\t' | ' ' if last_char_was_space => {}
14465            '\n' if !last_char_was_space => {
14466                new_text.push(' ');
14467                new_idx += 1;
14468                last_char_was_space = true;
14469                newlines_removed = true;
14470            }
14471            ' ' | '\t' => {
14472                new_text.push(' ');
14473                new_idx += 1;
14474                last_char_was_space = true;
14475            }
14476            _ => {
14477                new_text.push(c);
14478                new_idx += c.len_utf8();
14479                last_char_was_space = false;
14480            }
14481        }
14482    }
14483    offset_map[label.text.len()] = new_idx;
14484
14485    // Only modify the label if newlines were removed.
14486    if !newlines_removed {
14487        return;
14488    }
14489
14490    let last_index = new_idx;
14491    let mut run_ranges_errors = Vec::new();
14492    label.runs.retain_mut(|(range, _)| {
14493        match offset_map.get(range.start) {
14494            Some(&start) => range.start = start,
14495            None => {
14496                run_ranges_errors.push(range.clone());
14497                return false;
14498            }
14499        }
14500
14501        match offset_map.get(range.end) {
14502            Some(&end) => range.end = end,
14503            None => {
14504                run_ranges_errors.push(range.clone());
14505                range.end = last_index;
14506            }
14507        }
14508        true
14509    });
14510    if !run_ranges_errors.is_empty() {
14511        log::error!(
14512            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14513            label.text
14514        );
14515    }
14516
14517    let mut wrong_filter_range = None;
14518    if label.filter_range == (0..label.text.len()) {
14519        label.filter_range = 0..new_text.len();
14520    } else {
14521        let mut original_filter_range = Some(label.filter_range.clone());
14522        match offset_map.get(label.filter_range.start) {
14523            Some(&start) => label.filter_range.start = start,
14524            None => {
14525                wrong_filter_range = original_filter_range.take();
14526                label.filter_range.start = last_index;
14527            }
14528        }
14529
14530        match offset_map.get(label.filter_range.end) {
14531            Some(&end) => label.filter_range.end = end,
14532            None => {
14533                wrong_filter_range = original_filter_range.take();
14534                label.filter_range.end = last_index;
14535            }
14536        }
14537    }
14538    if let Some(wrong_filter_range) = wrong_filter_range {
14539        log::error!(
14540            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14541            label.text
14542        );
14543    }
14544
14545    label.text = new_text;
14546}
14547
14548/// Apply edits to the buffer that will become part of the formatting transaction.
14549/// Fails if the buffer has been edited since the start of that transaction.
14550fn extend_formatting_transaction(
14551    buffer: &FormattableBuffer,
14552    formatting_transaction_id: text::TransactionId,
14553    cx: &mut AsyncApp,
14554    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14555) -> anyhow::Result<()> {
14556    buffer.handle.update(cx, |buffer, cx| {
14557        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14558        if last_transaction_id != Some(formatting_transaction_id) {
14559            anyhow::bail!("Buffer edited while formatting. Aborting")
14560        }
14561        buffer.start_transaction();
14562        operation(buffer, cx);
14563        if let Some(transaction_id) = buffer.end_transaction(cx) {
14564            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14565        }
14566        Ok(())
14567    })
14568}