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, ModelineSettings, Patch, PointUtf16, TextBufferSnapshot,
   77    ToOffset, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152pub use semantic_tokens::{
  153    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  154};
  155
  156pub use worktree::{
  157    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  158    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  159};
  160
  161const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  162pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  163const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  164const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  165static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  166
  167#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  168pub enum ProgressToken {
  169    Number(i32),
  170    String(SharedString),
  171}
  172
  173impl std::fmt::Display for ProgressToken {
  174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  175        match self {
  176            Self::Number(number) => write!(f, "{number}"),
  177            Self::String(string) => write!(f, "{string}"),
  178        }
  179    }
  180}
  181
  182impl ProgressToken {
  183    fn from_lsp(value: lsp::NumberOrString) -> Self {
  184        match value {
  185            lsp::NumberOrString::Number(number) => Self::Number(number),
  186            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  187        }
  188    }
  189
  190    fn to_lsp(&self) -> lsp::NumberOrString {
  191        match self {
  192            Self::Number(number) => lsp::NumberOrString::Number(*number),
  193            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  194        }
  195    }
  196
  197    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  198        Some(match value.value? {
  199            proto::progress_token::Value::Number(number) => Self::Number(number),
  200            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  201        })
  202    }
  203
  204    fn to_proto(&self) -> proto::ProgressToken {
  205        proto::ProgressToken {
  206            value: Some(match self {
  207                Self::Number(number) => proto::progress_token::Value::Number(*number),
  208                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  209            }),
  210        }
  211    }
  212}
  213
  214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  215pub enum FormatTrigger {
  216    Save,
  217    Manual,
  218}
  219
  220pub enum LspFormatTarget {
  221    Buffers,
  222    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  223}
  224
  225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  226pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  227
  228struct OpenLspBuffer(Entity<Buffer>);
  229
  230impl FormatTrigger {
  231    fn from_proto(value: i32) -> FormatTrigger {
  232        match value {
  233            0 => FormatTrigger::Save,
  234            1 => FormatTrigger::Manual,
  235            _ => FormatTrigger::Save,
  236        }
  237    }
  238}
  239
  240#[derive(Clone)]
  241struct UnifiedLanguageServer {
  242    id: LanguageServerId,
  243    project_roots: HashSet<Arc<RelPath>>,
  244}
  245
  246/// Settings that affect language server identity.
  247///
  248/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  249/// updated via `workspace/didChangeConfiguration` without restarting the server.
  250#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  251struct LanguageServerSeedSettings {
  252    binary: Option<BinarySettings>,
  253    initialization_options: Option<serde_json::Value>,
  254}
  255
  256#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  257struct LanguageServerSeed {
  258    worktree_id: WorktreeId,
  259    name: LanguageServerName,
  260    toolchain: Option<Toolchain>,
  261    settings: LanguageServerSeedSettings,
  262}
  263
  264#[derive(Debug)]
  265pub struct DocumentDiagnosticsUpdate<'a, D> {
  266    pub diagnostics: D,
  267    pub result_id: Option<SharedString>,
  268    pub registration_id: Option<SharedString>,
  269    pub server_id: LanguageServerId,
  270    pub disk_based_sources: Cow<'a, [String]>,
  271}
  272
  273pub struct DocumentDiagnostics {
  274    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  275    document_abs_path: PathBuf,
  276    version: Option<i32>,
  277}
  278
  279#[derive(Default, Debug)]
  280struct DynamicRegistrations {
  281    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  282    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  283}
  284
  285pub struct LocalLspStore {
  286    weak: WeakEntity<LspStore>,
  287    pub worktree_store: Entity<WorktreeStore>,
  288    toolchain_store: Entity<LocalToolchainStore>,
  289    http_client: Arc<dyn HttpClient>,
  290    environment: Entity<ProjectEnvironment>,
  291    fs: Arc<dyn Fs>,
  292    languages: Arc<LanguageRegistry>,
  293    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  294    yarn: Entity<YarnPathStore>,
  295    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  296    buffers_being_formatted: HashSet<BufferId>,
  297    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  298    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  299    watched_manifest_filenames: HashSet<ManifestName>,
  300    language_server_paths_watched_for_rename:
  301        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  302    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  303    supplementary_language_servers:
  304        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  305    prettier_store: Entity<PrettierStore>,
  306    next_diagnostic_group_id: usize,
  307    diagnostics: HashMap<
  308        WorktreeId,
  309        HashMap<
  310            Arc<RelPath>,
  311            Vec<(
  312                LanguageServerId,
  313                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  314            )>,
  315        >,
  316    >,
  317    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  318    _subscription: gpui::Subscription,
  319    lsp_tree: LanguageServerTree,
  320    registered_buffers: HashMap<BufferId, usize>,
  321    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  322    buffer_pull_diagnostics_result_ids: HashMap<
  323        LanguageServerId,
  324        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  325    >,
  326    workspace_pull_diagnostics_result_ids: HashMap<
  327        LanguageServerId,
  328        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  329    >,
  330    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  331
  332    buffers_to_refresh_hash_set: HashSet<BufferId>,
  333    buffers_to_refresh_queue: VecDeque<BufferId>,
  334    _background_diagnostics_worker: Shared<Task<()>>,
  335}
  336
  337impl LocalLspStore {
  338    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  339    pub fn running_language_server_for_id(
  340        &self,
  341        id: LanguageServerId,
  342    ) -> Option<&Arc<LanguageServer>> {
  343        let language_server_state = self.language_servers.get(&id)?;
  344
  345        match language_server_state {
  346            LanguageServerState::Running { server, .. } => Some(server),
  347            LanguageServerState::Starting { .. } => None,
  348        }
  349    }
  350
  351    fn get_or_insert_language_server(
  352        &mut self,
  353        worktree_handle: &Entity<Worktree>,
  354        delegate: Arc<LocalLspAdapterDelegate>,
  355        disposition: &Arc<LaunchDisposition>,
  356        language_name: &LanguageName,
  357        cx: &mut App,
  358    ) -> LanguageServerId {
  359        let key = LanguageServerSeed {
  360            worktree_id: worktree_handle.read(cx).id(),
  361            name: disposition.server_name.clone(),
  362            settings: LanguageServerSeedSettings {
  363                binary: disposition.settings.binary.clone(),
  364                initialization_options: disposition.settings.initialization_options.clone(),
  365            },
  366            toolchain: disposition.toolchain.clone(),
  367        };
  368        if let Some(state) = self.language_server_ids.get_mut(&key) {
  369            state.project_roots.insert(disposition.path.path.clone());
  370            state.id
  371        } else {
  372            let adapter = self
  373                .languages
  374                .lsp_adapters(language_name)
  375                .into_iter()
  376                .find(|adapter| adapter.name() == disposition.server_name)
  377                .expect("To find LSP adapter");
  378            let new_language_server_id = self.start_language_server(
  379                worktree_handle,
  380                delegate,
  381                adapter,
  382                disposition.settings.clone(),
  383                key.clone(),
  384                language_name.clone(),
  385                cx,
  386            );
  387            if let Some(state) = self.language_server_ids.get_mut(&key) {
  388                state.project_roots.insert(disposition.path.path.clone());
  389            } else {
  390                debug_assert!(
  391                    false,
  392                    "Expected `start_language_server` to ensure that `key` exists in a map"
  393                );
  394            }
  395            new_language_server_id
  396        }
  397    }
  398
  399    fn start_language_server(
  400        &mut self,
  401        worktree_handle: &Entity<Worktree>,
  402        delegate: Arc<LocalLspAdapterDelegate>,
  403        adapter: Arc<CachedLspAdapter>,
  404        settings: Arc<LspSettings>,
  405        key: LanguageServerSeed,
  406        language_name: LanguageName,
  407        cx: &mut App,
  408    ) -> LanguageServerId {
  409        let worktree = worktree_handle.read(cx);
  410
  411        let worktree_id = worktree.id();
  412        let worktree_abs_path = worktree.abs_path();
  413        let toolchain = key.toolchain.clone();
  414        let override_options = settings.initialization_options.clone();
  415
  416        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  417
  418        let server_id = self.languages.next_language_server_id();
  419        log::trace!(
  420            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  421            adapter.name.0
  422        );
  423
  424        let wait_until_worktree_trust =
  425            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  426                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  427                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  428                });
  429                if can_trust {
  430                    self.restricted_worktrees_tasks.remove(&worktree_id);
  431                    None
  432                } else {
  433                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  434                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  435                        hash_map::Entry::Vacant(v) => {
  436                            let (mut tx, rx) = watch::channel::<bool>();
  437                            let lsp_store = self.weak.clone();
  438                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  439                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  440                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  441                                        tx.blocking_send(true).ok();
  442                                        lsp_store
  443                                            .update(cx, |lsp_store, _| {
  444                                                if let Some(local_lsp_store) =
  445                                                    lsp_store.as_local_mut()
  446                                                {
  447                                                    local_lsp_store
  448                                                        .restricted_worktrees_tasks
  449                                                        .remove(&worktree_id);
  450                                                }
  451                                            })
  452                                            .ok();
  453                                    }
  454                                }
  455                            });
  456                            v.insert((subscription, rx.clone()));
  457                            Some(rx)
  458                        }
  459                    }
  460                }
  461            });
  462        let update_binary_status = wait_until_worktree_trust.is_none();
  463
  464        let binary = self.get_language_server_binary(
  465            worktree_abs_path.clone(),
  466            adapter.clone(),
  467            settings,
  468            toolchain.clone(),
  469            delegate.clone(),
  470            true,
  471            wait_until_worktree_trust,
  472            cx,
  473        );
  474        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  475
  476        let pending_server = cx.spawn({
  477            let adapter = adapter.clone();
  478            let server_name = adapter.name.clone();
  479            let stderr_capture = stderr_capture.clone();
  480            #[cfg(any(test, feature = "test-support"))]
  481            let lsp_store = self.weak.clone();
  482            let pending_workspace_folders = pending_workspace_folders.clone();
  483            async move |cx| {
  484                let binary = binary.await?;
  485                #[cfg(any(test, feature = "test-support"))]
  486                if let Some(server) = lsp_store
  487                    .update(&mut cx.clone(), |this, cx| {
  488                        this.languages.create_fake_language_server(
  489                            server_id,
  490                            &server_name,
  491                            binary.clone(),
  492                            &mut cx.to_async(),
  493                        )
  494                    })
  495                    .ok()
  496                    .flatten()
  497                {
  498                    return Ok(server);
  499                }
  500
  501                let code_action_kinds = adapter.code_action_kinds();
  502                lsp::LanguageServer::new(
  503                    stderr_capture,
  504                    server_id,
  505                    server_name,
  506                    binary,
  507                    &worktree_abs_path,
  508                    code_action_kinds,
  509                    Some(pending_workspace_folders),
  510                    cx,
  511                )
  512            }
  513        });
  514
  515        let startup = {
  516            let server_name = adapter.name.0.clone();
  517            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  518            let key = key.clone();
  519            let adapter = adapter.clone();
  520            let lsp_store = self.weak.clone();
  521            let pending_workspace_folders = pending_workspace_folders.clone();
  522            let pull_diagnostics = ProjectSettings::get_global(cx)
  523                .diagnostics
  524                .lsp_pull_diagnostics
  525                .enabled;
  526            let settings_location = SettingsLocation {
  527                worktree_id,
  528                path: RelPath::empty(),
  529            };
  530            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  531                .language(Some(settings_location), Some(&language_name), cx)
  532                .semantic_tokens
  533                .use_tree_sitter();
  534            cx.spawn(async move |cx| {
  535                let result = async {
  536                    let language_server = pending_server.await?;
  537
  538                    let workspace_config = Self::workspace_configuration_for_adapter(
  539                        adapter.adapter.clone(),
  540                        &delegate,
  541                        toolchain,
  542                        None,
  543                        cx,
  544                    )
  545                    .await?;
  546
  547                    let mut initialization_options = Self::initialization_options_for_adapter(
  548                        adapter.adapter.clone(),
  549                        &delegate,
  550                        cx,
  551                    )
  552                    .await?;
  553
  554                    match (&mut initialization_options, override_options) {
  555                        (Some(initialization_options), Some(override_options)) => {
  556                            merge_json_value_into(override_options, initialization_options);
  557                        }
  558                        (None, override_options) => initialization_options = override_options,
  559                        _ => {}
  560                    }
  561
  562                    let initialization_params = cx.update(|cx| {
  563                        let mut params = language_server.default_initialize_params(
  564                            pull_diagnostics,
  565                            augments_syntax_tokens,
  566                            cx,
  567                        );
  568                        params.initialization_options = initialization_options;
  569                        adapter.adapter.prepare_initialize_params(params, cx)
  570                    })?;
  571
  572                    Self::setup_lsp_messages(
  573                        lsp_store.clone(),
  574                        &language_server,
  575                        delegate.clone(),
  576                        adapter.clone(),
  577                    );
  578
  579                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  580                        settings: workspace_config,
  581                    };
  582                    let language_server = cx
  583                        .update(|cx| {
  584                            let request_timeout = ProjectSettings::get_global(cx)
  585                                .global_lsp_settings
  586                                .get_request_timeout();
  587
  588                            language_server.initialize(
  589                                initialization_params,
  590                                Arc::new(did_change_configuration_params.clone()),
  591                                request_timeout,
  592                                cx,
  593                            )
  594                        })
  595                        .await
  596                        .inspect_err(|_| {
  597                            if let Some(lsp_store) = lsp_store.upgrade() {
  598                                lsp_store.update(cx, |lsp_store, cx| {
  599                                    lsp_store.cleanup_lsp_data(server_id);
  600                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  601                                });
  602                            }
  603                        })?;
  604
  605                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  606                        did_change_configuration_params,
  607                    )?;
  608
  609                    anyhow::Ok(language_server)
  610                }
  611                .await;
  612
  613                match result {
  614                    Ok(server) => {
  615                        lsp_store
  616                            .update(cx, |lsp_store, cx| {
  617                                lsp_store.insert_newly_running_language_server(
  618                                    adapter,
  619                                    server.clone(),
  620                                    server_id,
  621                                    key,
  622                                    pending_workspace_folders,
  623                                    cx,
  624                                );
  625                            })
  626                            .ok();
  627                        stderr_capture.lock().take();
  628                        Some(server)
  629                    }
  630
  631                    Err(err) => {
  632                        let log = stderr_capture.lock().take().unwrap_or_default();
  633                        delegate.update_status(
  634                            adapter.name(),
  635                            BinaryStatus::Failed {
  636                                error: if log.is_empty() {
  637                                    format!("{err:#}")
  638                                } else {
  639                                    format!("{err:#}\n-- stderr --\n{log}")
  640                                },
  641                            },
  642                        );
  643                        log::error!(
  644                            "Failed to start language server {server_name:?}: {}",
  645                            redact_command(&format!("{err:?}"))
  646                        );
  647                        if !log.is_empty() {
  648                            log::error!("server stderr: {}", redact_command(&log));
  649                        }
  650                        None
  651                    }
  652                }
  653            })
  654        };
  655        let state = LanguageServerState::Starting {
  656            startup,
  657            pending_workspace_folders,
  658        };
  659
  660        if update_binary_status {
  661            self.languages
  662                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663        }
  664
  665        self.language_servers.insert(server_id, state);
  666        self.language_server_ids
  667            .entry(key)
  668            .or_insert(UnifiedLanguageServer {
  669                id: server_id,
  670                project_roots: Default::default(),
  671            });
  672        server_id
  673    }
  674
  675    fn get_language_server_binary(
  676        &self,
  677        worktree_abs_path: Arc<Path>,
  678        adapter: Arc<CachedLspAdapter>,
  679        settings: Arc<LspSettings>,
  680        toolchain: Option<Toolchain>,
  681        delegate: Arc<dyn LspAdapterDelegate>,
  682        allow_binary_download: bool,
  683        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  684        cx: &mut App,
  685    ) -> Task<Result<LanguageServerBinary>> {
  686        if let Some(settings) = &settings.binary
  687            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  688        {
  689            let settings = settings.clone();
  690            let languages = self.languages.clone();
  691            return cx.background_spawn(async move {
  692                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  693                    let already_trusted =  *wait_until_worktree_trust.borrow();
  694                    if !already_trusted {
  695                        log::info!(
  696                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  697                            adapter.name(),
  698                        );
  699                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  700                            if worktree_trusted {
  701                                break;
  702                            }
  703                        }
  704                        log::info!(
  705                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  706                            adapter.name(),
  707                        );
  708                    }
  709                    languages
  710                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  711                }
  712                let mut env = delegate.shell_env().await;
  713                env.extend(settings.env.unwrap_or_default());
  714
  715                Ok(LanguageServerBinary {
  716                    path: delegate.resolve_relative_path(path),
  717                    env: Some(env),
  718                    arguments: settings
  719                        .arguments
  720                        .unwrap_or_default()
  721                        .iter()
  722                        .map(Into::into)
  723                        .collect(),
  724                })
  725            });
  726        }
  727        let lsp_binary_options = LanguageServerBinaryOptions {
  728            allow_path_lookup: !settings
  729                .binary
  730                .as_ref()
  731                .and_then(|b| b.ignore_system_version)
  732                .unwrap_or_default(),
  733            allow_binary_download,
  734            pre_release: settings
  735                .fetch
  736                .as_ref()
  737                .and_then(|f| f.pre_release)
  738                .unwrap_or(false),
  739        };
  740
  741        cx.spawn(async move |cx| {
  742            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  743                let already_trusted =  *wait_until_worktree_trust.borrow();
  744                if !already_trusted {
  745                    log::info!(
  746                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  747                        adapter.name(),
  748                    );
  749                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  750                        if worktree_trusted {
  751                            break;
  752                        }
  753                    }
  754                    log::info!(
  755                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  756                            adapter.name(),
  757                    );
  758                }
  759            }
  760
  761            let (existing_binary, maybe_download_binary) = adapter
  762                .clone()
  763                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  764                .await
  765                .await;
  766
  767            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  768
  769            let mut binary = match (existing_binary, maybe_download_binary) {
  770                (binary, None) => binary?,
  771                (Err(_), Some(downloader)) => downloader.await?,
  772                (Ok(existing_binary), Some(downloader)) => {
  773                    let mut download_timeout = cx
  774                        .background_executor()
  775                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  776                        .fuse();
  777                    let mut downloader = downloader.fuse();
  778                    futures::select! {
  779                        _ = download_timeout => {
  780                            // Return existing binary and kick the existing work to the background.
  781                            cx.spawn(async move |_| downloader.await).detach();
  782                            Ok(existing_binary)
  783                        },
  784                        downloaded_or_existing_binary = downloader => {
  785                            // If download fails, this results in the existing binary.
  786                            downloaded_or_existing_binary
  787                        }
  788                    }?
  789                }
  790            };
  791            let mut shell_env = delegate.shell_env().await;
  792
  793            shell_env.extend(binary.env.unwrap_or_default());
  794
  795            if let Some(settings) = settings.binary.as_ref() {
  796                if let Some(arguments) = &settings.arguments {
  797                    binary.arguments = arguments.iter().map(Into::into).collect();
  798                }
  799                if let Some(env) = &settings.env {
  800                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  801                }
  802            }
  803
  804            binary.env = Some(shell_env);
  805            Ok(binary)
  806        })
  807    }
  808
  809    fn setup_lsp_messages(
  810        lsp_store: WeakEntity<LspStore>,
  811        language_server: &LanguageServer,
  812        delegate: Arc<dyn LspAdapterDelegate>,
  813        adapter: Arc<CachedLspAdapter>,
  814    ) {
  815        let name = language_server.name();
  816        let server_id = language_server.server_id();
  817        language_server
  818            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  819                let adapter = adapter.clone();
  820                let this = lsp_store.clone();
  821                move |mut params, cx| {
  822                    let adapter = adapter.clone();
  823                    if let Some(this) = this.upgrade() {
  824                        this.update(cx, |this, cx| {
  825                            {
  826                                let buffer = params
  827                                    .uri
  828                                    .to_file_path()
  829                                    .map(|file_path| this.get_buffer(&file_path, cx))
  830                                    .ok()
  831                                    .flatten();
  832                                adapter.process_diagnostics(&mut params, server_id, buffer);
  833                            }
  834
  835                            this.merge_lsp_diagnostics(
  836                                DiagnosticSourceKind::Pushed,
  837                                vec![DocumentDiagnosticsUpdate {
  838                                    server_id,
  839                                    diagnostics: params,
  840                                    result_id: None,
  841                                    disk_based_sources: Cow::Borrowed(
  842                                        &adapter.disk_based_diagnostic_sources,
  843                                    ),
  844                                    registration_id: None,
  845                                }],
  846                                |_, diagnostic, cx| match diagnostic.source_kind {
  847                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  848                                        adapter.retain_old_diagnostic(diagnostic, cx)
  849                                    }
  850                                    DiagnosticSourceKind::Pulled => true,
  851                                },
  852                                cx,
  853                            )
  854                            .log_err();
  855                        });
  856                    }
  857                }
  858            })
  859            .detach();
  860        language_server
  861            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  862                let adapter = adapter.adapter.clone();
  863                let delegate = delegate.clone();
  864                let this = lsp_store.clone();
  865                move |params, cx| {
  866                    let adapter = adapter.clone();
  867                    let delegate = delegate.clone();
  868                    let this = this.clone();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let toolchain_for_id = this
  872                            .update(&mut cx, |this, _| {
  873                                this.as_local()?.language_server_ids.iter().find_map(
  874                                    |(seed, value)| {
  875                                        (value.id == server_id).then(|| seed.toolchain.clone())
  876                                    },
  877                                )
  878                            })?
  879                            .context("Expected the LSP store to be in a local mode")?;
  880
  881                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  882                        for item in &params.items {
  883                            let scope_uri = item.scope_uri.clone();
  884                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  885                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  886                            else {
  887                                // We've already queried workspace configuration of this URI.
  888                                continue;
  889                            };
  890                            let workspace_config = Self::workspace_configuration_for_adapter(
  891                                adapter.clone(),
  892                                &delegate,
  893                                toolchain_for_id.clone(),
  894                                scope_uri,
  895                                &mut cx,
  896                            )
  897                            .await?;
  898                            new_scope_uri.insert(workspace_config);
  899                        }
  900
  901                        Ok(params
  902                            .items
  903                            .into_iter()
  904                            .filter_map(|item| {
  905                                let workspace_config =
  906                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  907                                if let Some(section) = &item.section {
  908                                    Some(
  909                                        workspace_config
  910                                            .get(section)
  911                                            .cloned()
  912                                            .unwrap_or(serde_json::Value::Null),
  913                                    )
  914                                } else {
  915                                    Some(workspace_config.clone())
  916                                }
  917                            })
  918                            .collect())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  926                let this = lsp_store.clone();
  927                move |_, cx| {
  928                    let this = this.clone();
  929                    let cx = cx.clone();
  930                    async move {
  931                        let Some(server) =
  932                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  933                        else {
  934                            return Ok(None);
  935                        };
  936                        let root = server.workspace_folders();
  937                        Ok(Some(
  938                            root.into_iter()
  939                                .map(|uri| WorkspaceFolder {
  940                                    uri,
  941                                    name: Default::default(),
  942                                })
  943                                .collect(),
  944                        ))
  945                    }
  946                }
  947            })
  948            .detach();
  949        // Even though we don't have handling for these requests, respond to them to
  950        // avoid stalling any language server like `gopls` which waits for a response
  951        // to these requests when initializing.
  952        language_server
  953            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let this = this.clone();
  957                    let mut cx = cx.clone();
  958                    async move {
  959                        this.update(&mut cx, |this, _| {
  960                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  961                            {
  962                                status
  963                                    .progress_tokens
  964                                    .insert(ProgressToken::from_lsp(params.token));
  965                            }
  966                        })?;
  967
  968                        Ok(())
  969                    }
  970                }
  971            })
  972            .detach();
  973
  974        language_server
  975            .on_request::<lsp::request::RegisterCapability, _, _>({
  976                let lsp_store = lsp_store.clone();
  977                move |params, cx| {
  978                    let lsp_store = lsp_store.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                if lsp_store.as_local().is_some() {
  984                                    match lsp_store
  985                                        .register_server_capabilities(server_id, params, cx)
  986                                    {
  987                                        Ok(()) => {}
  988                                        Err(e) => {
  989                                            log::error!(
  990                                                "Failed to register server capabilities: {e:#}"
  991                                            );
  992                                        }
  993                                    };
  994                                }
  995                            })
  996                            .ok();
  997                        Ok(())
  998                    }
  999                }
 1000            })
 1001            .detach();
 1002
 1003        language_server
 1004            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1005                let lsp_store = lsp_store.clone();
 1006                move |params, cx| {
 1007                    let lsp_store = lsp_store.clone();
 1008                    let mut cx = cx.clone();
 1009                    async move {
 1010                        lsp_store
 1011                            .update(&mut cx, |lsp_store, cx| {
 1012                                if lsp_store.as_local().is_some() {
 1013                                    match lsp_store
 1014                                        .unregister_server_capabilities(server_id, params, cx)
 1015                                    {
 1016                                        Ok(()) => {}
 1017                                        Err(e) => {
 1018                                            log::error!(
 1019                                                "Failed to unregister server capabilities: {e:#}"
 1020                                            );
 1021                                        }
 1022                                    }
 1023                                }
 1024                            })
 1025                            .ok();
 1026                        Ok(())
 1027                    }
 1028                }
 1029            })
 1030            .detach();
 1031
 1032        language_server
 1033            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1034                let this = lsp_store.clone();
 1035                move |params, cx| {
 1036                    let mut cx = cx.clone();
 1037                    let this = this.clone();
 1038                    async move {
 1039                        LocalLspStore::on_lsp_workspace_edit(
 1040                            this.clone(),
 1041                            params,
 1042                            server_id,
 1043                            &mut cx,
 1044                        )
 1045                        .await
 1046                    }
 1047                }
 1048            })
 1049            .detach();
 1050
 1051        language_server
 1052            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1053                let lsp_store = lsp_store.clone();
 1054                let request_id = Arc::new(AtomicUsize::new(0));
 1055                move |(), cx| {
 1056                    let lsp_store = lsp_store.clone();
 1057                    let request_id = request_id.clone();
 1058                    let mut cx = cx.clone();
 1059                    async move {
 1060                        lsp_store
 1061                            .update(&mut cx, |lsp_store, cx| {
 1062                                let request_id =
 1063                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1064                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1065                                    server_id,
 1066                                    request_id,
 1067                                });
 1068                                lsp_store
 1069                                    .downstream_client
 1070                                    .as_ref()
 1071                                    .map(|(client, project_id)| {
 1072                                        client.send(proto::RefreshInlayHints {
 1073                                            project_id: *project_id,
 1074                                            server_id: server_id.to_proto(),
 1075                                            request_id: request_id.map(|id| id as u64),
 1076                                        })
 1077                                    })
 1078                            })?
 1079                            .transpose()?;
 1080                        Ok(())
 1081                    }
 1082                }
 1083            })
 1084            .detach();
 1085
 1086        language_server
 1087            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1088                let this = lsp_store.clone();
 1089                move |(), cx| {
 1090                    let this = this.clone();
 1091                    let mut cx = cx.clone();
 1092                    async move {
 1093                        this.update(&mut cx, |this, cx| {
 1094                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1095                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1096                                client.send(proto::RefreshCodeLens {
 1097                                    project_id: *project_id,
 1098                                })
 1099                            })
 1100                        })?
 1101                        .transpose()?;
 1102                        Ok(())
 1103                    }
 1104                }
 1105            })
 1106            .detach();
 1107
 1108        language_server
 1109            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1110                let lsp_store = lsp_store.clone();
 1111                let request_id = Arc::new(AtomicUsize::new(0));
 1112                move |(), cx| {
 1113                    let lsp_store = lsp_store.clone();
 1114                    let request_id = request_id.clone();
 1115                    let mut cx = cx.clone();
 1116                    async move {
 1117                        lsp_store
 1118                            .update(&mut cx, |lsp_store, cx| {
 1119                                let request_id =
 1120                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1121                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1122                                    server_id,
 1123                                    request_id,
 1124                                });
 1125                                lsp_store
 1126                                    .downstream_client
 1127                                    .as_ref()
 1128                                    .map(|(client, project_id)| {
 1129                                        client.send(proto::RefreshSemanticTokens {
 1130                                            project_id: *project_id,
 1131                                            server_id: server_id.to_proto(),
 1132                                            request_id: request_id.map(|id| id as u64),
 1133                                        })
 1134                                    })
 1135                            })?
 1136                            .transpose()?;
 1137                        Ok(())
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1145                let this = lsp_store.clone();
 1146                move |(), cx| {
 1147                    let this = this.clone();
 1148                    let mut cx = cx.clone();
 1149                    async move {
 1150                        this.update(&mut cx, |lsp_store, cx| {
 1151                            lsp_store.pull_workspace_diagnostics(server_id);
 1152                            lsp_store
 1153                                .downstream_client
 1154                                .as_ref()
 1155                                .map(|(client, project_id)| {
 1156                                    client.send(proto::PullWorkspaceDiagnostics {
 1157                                        project_id: *project_id,
 1158                                        server_id: server_id.to_proto(),
 1159                                    })
 1160                                })
 1161                                .transpose()?;
 1162                            anyhow::Ok(
 1163                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1164                            )
 1165                        })??
 1166                        .await;
 1167                        Ok(())
 1168                    }
 1169                }
 1170            })
 1171            .detach();
 1172
 1173        language_server
 1174            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1175                let this = lsp_store.clone();
 1176                let name = name.to_string();
 1177                let adapter = adapter.clone();
 1178                move |params, cx| {
 1179                    let this = this.clone();
 1180                    let name = name.to_string();
 1181                    let adapter = adapter.clone();
 1182                    let mut cx = cx.clone();
 1183                    async move {
 1184                        let actions = params.actions.unwrap_or_default();
 1185                        let message = params.message.clone();
 1186                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1187                        let level = match params.typ {
 1188                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1189                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1190                            _ => PromptLevel::Info,
 1191                        };
 1192                        let request = LanguageServerPromptRequest::new(
 1193                            level,
 1194                            params.message,
 1195                            actions,
 1196                            name.clone(),
 1197                            tx,
 1198                        );
 1199
 1200                        let did_update = this
 1201                            .update(&mut cx, |_, cx| {
 1202                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1203                            })
 1204                            .is_ok();
 1205                        if did_update {
 1206                            let response = rx.recv().await.ok();
 1207                            if let Some(ref selected_action) = response {
 1208                                let context = language::PromptResponseContext {
 1209                                    message,
 1210                                    selected_action: selected_action.clone(),
 1211                                };
 1212                                adapter.process_prompt_response(&context, &mut cx)
 1213                            }
 1214
 1215                            Ok(response)
 1216                        } else {
 1217                            Ok(None)
 1218                        }
 1219                    }
 1220                }
 1221            })
 1222            .detach();
 1223        language_server
 1224            .on_notification::<lsp::notification::ShowMessage, _>({
 1225                let this = lsp_store.clone();
 1226                let name = name.to_string();
 1227                move |params, cx| {
 1228                    let this = this.clone();
 1229                    let name = name.to_string();
 1230                    let mut cx = cx.clone();
 1231
 1232                    let (tx, _) = smol::channel::bounded(1);
 1233                    let level = match params.typ {
 1234                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1235                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1236                        _ => PromptLevel::Info,
 1237                    };
 1238                    let request =
 1239                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1240
 1241                    let _ = this.update(&mut cx, |_, cx| {
 1242                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1243                    });
 1244                }
 1245            })
 1246            .detach();
 1247
 1248        let disk_based_diagnostics_progress_token =
 1249            adapter.disk_based_diagnostics_progress_token.clone();
 1250
 1251        language_server
 1252            .on_notification::<lsp::notification::Progress, _>({
 1253                let this = lsp_store.clone();
 1254                move |params, cx| {
 1255                    if let Some(this) = this.upgrade() {
 1256                        this.update(cx, |this, cx| {
 1257                            this.on_lsp_progress(
 1258                                params,
 1259                                server_id,
 1260                                disk_based_diagnostics_progress_token.clone(),
 1261                                cx,
 1262                            );
 1263                        });
 1264                    }
 1265                }
 1266            })
 1267            .detach();
 1268
 1269        language_server
 1270            .on_notification::<lsp::notification::LogMessage, _>({
 1271                let this = lsp_store.clone();
 1272                move |params, cx| {
 1273                    if let Some(this) = this.upgrade() {
 1274                        this.update(cx, |_, cx| {
 1275                            cx.emit(LspStoreEvent::LanguageServerLog(
 1276                                server_id,
 1277                                LanguageServerLogType::Log(params.typ),
 1278                                params.message,
 1279                            ));
 1280                        });
 1281                    }
 1282                }
 1283            })
 1284            .detach();
 1285
 1286        language_server
 1287            .on_notification::<lsp::notification::LogTrace, _>({
 1288                let this = lsp_store.clone();
 1289                move |params, cx| {
 1290                    let mut cx = cx.clone();
 1291                    if let Some(this) = this.upgrade() {
 1292                        this.update(&mut cx, |_, cx| {
 1293                            cx.emit(LspStoreEvent::LanguageServerLog(
 1294                                server_id,
 1295                                LanguageServerLogType::Trace {
 1296                                    verbose_info: params.verbose,
 1297                                },
 1298                                params.message,
 1299                            ));
 1300                        });
 1301                    }
 1302                }
 1303            })
 1304            .detach();
 1305
 1306        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1307        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1309        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1310    }
 1311
 1312    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1313        let shutdown_futures = self
 1314            .language_servers
 1315            .drain()
 1316            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1317            .collect::<Vec<_>>();
 1318
 1319        async move {
 1320            join_all(shutdown_futures).await;
 1321        }
 1322    }
 1323
 1324    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1325        match server_state {
 1326            LanguageServerState::Running { server, .. } => {
 1327                if let Some(shutdown) = server.shutdown() {
 1328                    shutdown.await;
 1329                }
 1330            }
 1331            LanguageServerState::Starting { startup, .. } => {
 1332                if let Some(server) = startup.await
 1333                    && let Some(shutdown) = server.shutdown()
 1334                {
 1335                    shutdown.await;
 1336                }
 1337            }
 1338        }
 1339        Ok(())
 1340    }
 1341
 1342    fn language_servers_for_worktree(
 1343        &self,
 1344        worktree_id: WorktreeId,
 1345    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1346        self.language_server_ids
 1347            .iter()
 1348            .filter_map(move |(seed, state)| {
 1349                if seed.worktree_id != worktree_id {
 1350                    return None;
 1351                }
 1352
 1353                if let Some(LanguageServerState::Running { server, .. }) =
 1354                    self.language_servers.get(&state.id)
 1355                {
 1356                    Some(server)
 1357                } else {
 1358                    None
 1359                }
 1360            })
 1361    }
 1362
 1363    fn language_server_ids_for_project_path(
 1364        &self,
 1365        project_path: ProjectPath,
 1366        language: &Language,
 1367        cx: &mut App,
 1368    ) -> Vec<LanguageServerId> {
 1369        let Some(worktree) = self
 1370            .worktree_store
 1371            .read(cx)
 1372            .worktree_for_id(project_path.worktree_id, cx)
 1373        else {
 1374            return Vec::new();
 1375        };
 1376        let delegate: Arc<dyn ManifestDelegate> =
 1377            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1378
 1379        self.lsp_tree
 1380            .get(
 1381                project_path,
 1382                language.name(),
 1383                language.manifest(),
 1384                &delegate,
 1385                cx,
 1386            )
 1387            .collect::<Vec<_>>()
 1388    }
 1389
 1390    fn language_server_ids_for_buffer(
 1391        &self,
 1392        buffer: &Buffer,
 1393        cx: &mut App,
 1394    ) -> Vec<LanguageServerId> {
 1395        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1396            let worktree_id = file.worktree_id(cx);
 1397
 1398            let path: Arc<RelPath> = file
 1399                .path()
 1400                .parent()
 1401                .map(Arc::from)
 1402                .unwrap_or_else(|| file.path().clone());
 1403            let worktree_path = ProjectPath { worktree_id, path };
 1404            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1405        } else {
 1406            Vec::new()
 1407        }
 1408    }
 1409
 1410    fn language_servers_for_buffer<'a>(
 1411        &'a self,
 1412        buffer: &'a Buffer,
 1413        cx: &'a mut App,
 1414    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1415        self.language_server_ids_for_buffer(buffer, cx)
 1416            .into_iter()
 1417            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1418                LanguageServerState::Running {
 1419                    adapter, server, ..
 1420                } => Some((adapter, server)),
 1421                _ => None,
 1422            })
 1423    }
 1424
 1425    async fn execute_code_action_kind_locally(
 1426        lsp_store: WeakEntity<LspStore>,
 1427        mut buffers: Vec<Entity<Buffer>>,
 1428        kind: CodeActionKind,
 1429        push_to_history: bool,
 1430        cx: &mut AsyncApp,
 1431    ) -> anyhow::Result<ProjectTransaction> {
 1432        // Do not allow multiple concurrent code actions requests for the
 1433        // same buffer.
 1434        lsp_store.update(cx, |this, cx| {
 1435            let this = this.as_local_mut().unwrap();
 1436            buffers.retain(|buffer| {
 1437                this.buffers_being_formatted
 1438                    .insert(buffer.read(cx).remote_id())
 1439            });
 1440        })?;
 1441        let _cleanup = defer({
 1442            let this = lsp_store.clone();
 1443            let mut cx = cx.clone();
 1444            let buffers = &buffers;
 1445            move || {
 1446                this.update(&mut cx, |this, cx| {
 1447                    let this = this.as_local_mut().unwrap();
 1448                    for buffer in buffers {
 1449                        this.buffers_being_formatted
 1450                            .remove(&buffer.read(cx).remote_id());
 1451                    }
 1452                })
 1453                .ok();
 1454            }
 1455        });
 1456        let mut project_transaction = ProjectTransaction::default();
 1457
 1458        for buffer in &buffers {
 1459            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1460                buffer.update(cx, |buffer, cx| {
 1461                    lsp_store
 1462                        .as_local()
 1463                        .unwrap()
 1464                        .language_servers_for_buffer(buffer, cx)
 1465                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1466                        .collect::<Vec<_>>()
 1467                })
 1468            })?;
 1469            for (_, language_server) in adapters_and_servers.iter() {
 1470                let actions = Self::get_server_code_actions_from_action_kinds(
 1471                    &lsp_store,
 1472                    language_server.server_id(),
 1473                    vec![kind.clone()],
 1474                    buffer,
 1475                    cx,
 1476                )
 1477                .await?;
 1478                Self::execute_code_actions_on_server(
 1479                    &lsp_store,
 1480                    language_server,
 1481                    actions,
 1482                    push_to_history,
 1483                    &mut project_transaction,
 1484                    cx,
 1485                )
 1486                .await?;
 1487            }
 1488        }
 1489        Ok(project_transaction)
 1490    }
 1491
 1492    async fn format_locally(
 1493        lsp_store: WeakEntity<LspStore>,
 1494        mut buffers: Vec<FormattableBuffer>,
 1495        push_to_history: bool,
 1496        trigger: FormatTrigger,
 1497        logger: zlog::Logger,
 1498        cx: &mut AsyncApp,
 1499    ) -> anyhow::Result<ProjectTransaction> {
 1500        // Do not allow multiple concurrent formatting requests for the
 1501        // same buffer.
 1502        lsp_store.update(cx, |this, cx| {
 1503            let this = this.as_local_mut().unwrap();
 1504            buffers.retain(|buffer| {
 1505                this.buffers_being_formatted
 1506                    .insert(buffer.handle.read(cx).remote_id())
 1507            });
 1508        })?;
 1509
 1510        let _cleanup = defer({
 1511            let this = lsp_store.clone();
 1512            let mut cx = cx.clone();
 1513            let buffers = &buffers;
 1514            move || {
 1515                this.update(&mut cx, |this, cx| {
 1516                    let this = this.as_local_mut().unwrap();
 1517                    for buffer in buffers {
 1518                        this.buffers_being_formatted
 1519                            .remove(&buffer.handle.read(cx).remote_id());
 1520                    }
 1521                })
 1522                .ok();
 1523            }
 1524        });
 1525
 1526        let mut project_transaction = ProjectTransaction::default();
 1527
 1528        for buffer in &buffers {
 1529            zlog::debug!(
 1530                logger =>
 1531                "formatting buffer '{:?}'",
 1532                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1533            );
 1534            // Create an empty transaction to hold all of the formatting edits.
 1535            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1536                // ensure no transactions created while formatting are
 1537                // grouped with the previous transaction in the history
 1538                // based on the transaction group interval
 1539                buffer.finalize_last_transaction();
 1540                buffer
 1541                    .start_transaction()
 1542                    .context("transaction already open")?;
 1543                buffer.end_transaction(cx);
 1544                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1545                buffer.finalize_last_transaction();
 1546                anyhow::Ok(transaction_id)
 1547            })?;
 1548
 1549            let result = Self::format_buffer_locally(
 1550                lsp_store.clone(),
 1551                buffer,
 1552                formatting_transaction_id,
 1553                trigger,
 1554                logger,
 1555                cx,
 1556            )
 1557            .await;
 1558
 1559            buffer.handle.update(cx, |buffer, cx| {
 1560                let Some(formatting_transaction) =
 1561                    buffer.get_transaction(formatting_transaction_id).cloned()
 1562                else {
 1563                    zlog::warn!(logger => "no formatting transaction");
 1564                    return;
 1565                };
 1566                if formatting_transaction.edit_ids.is_empty() {
 1567                    zlog::debug!(logger => "no changes made while formatting");
 1568                    buffer.forget_transaction(formatting_transaction_id);
 1569                    return;
 1570                }
 1571                if !push_to_history {
 1572                    zlog::trace!(logger => "forgetting format transaction");
 1573                    buffer.forget_transaction(formatting_transaction.id);
 1574                }
 1575                project_transaction
 1576                    .0
 1577                    .insert(cx.entity(), formatting_transaction);
 1578            });
 1579
 1580            result?;
 1581        }
 1582
 1583        Ok(project_transaction)
 1584    }
 1585
 1586    async fn format_buffer_locally(
 1587        lsp_store: WeakEntity<LspStore>,
 1588        buffer: &FormattableBuffer,
 1589        formatting_transaction_id: clock::Lamport,
 1590        trigger: FormatTrigger,
 1591        logger: zlog::Logger,
 1592        cx: &mut AsyncApp,
 1593    ) -> Result<()> {
 1594        let (adapters_and_servers, settings, request_timeout) =
 1595            lsp_store.update(cx, |lsp_store, cx| {
 1596                buffer.handle.update(cx, |buffer, cx| {
 1597                    let adapters_and_servers = lsp_store
 1598                        .as_local()
 1599                        .unwrap()
 1600                        .language_servers_for_buffer(buffer, cx)
 1601                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1602                        .collect::<Vec<_>>();
 1603                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1604                    let request_timeout = ProjectSettings::get_global(cx)
 1605                        .global_lsp_settings
 1606                        .get_request_timeout();
 1607                    (adapters_and_servers, settings, request_timeout)
 1608                })
 1609            })?;
 1610
 1611        // handle whitespace formatting
 1612        if settings.remove_trailing_whitespace_on_save {
 1613            zlog::trace!(logger => "removing trailing whitespace");
 1614            let diff = buffer
 1615                .handle
 1616                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1617                .await;
 1618            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1619                buffer.apply_diff(diff, cx);
 1620            })?;
 1621        }
 1622
 1623        if settings.ensure_final_newline_on_save {
 1624            zlog::trace!(logger => "ensuring final newline");
 1625            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1626                buffer.ensure_final_newline(cx);
 1627            })?;
 1628        }
 1629
 1630        // Formatter for `code_actions_on_format` that runs before
 1631        // the rest of the formatters
 1632        let mut code_actions_on_format_formatters = None;
 1633        let should_run_code_actions_on_format = !matches!(
 1634            (trigger, &settings.format_on_save),
 1635            (FormatTrigger::Save, &FormatOnSave::Off)
 1636        );
 1637        if should_run_code_actions_on_format {
 1638            let have_code_actions_to_run_on_format = settings
 1639                .code_actions_on_format
 1640                .values()
 1641                .any(|enabled| *enabled);
 1642            if have_code_actions_to_run_on_format {
 1643                zlog::trace!(logger => "going to run code actions on format");
 1644                code_actions_on_format_formatters = Some(
 1645                    settings
 1646                        .code_actions_on_format
 1647                        .iter()
 1648                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1649                        .cloned()
 1650                        .map(Formatter::CodeAction)
 1651                        .collect::<Vec<_>>(),
 1652                );
 1653            }
 1654        }
 1655
 1656        let formatters = match (trigger, &settings.format_on_save) {
 1657            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1658            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1659                settings.formatter.as_ref()
 1660            }
 1661        };
 1662
 1663        let formatters = code_actions_on_format_formatters
 1664            .iter()
 1665            .flatten()
 1666            .chain(formatters);
 1667
 1668        for formatter in formatters {
 1669            let formatter = if formatter == &Formatter::Auto {
 1670                if settings.prettier.allowed {
 1671                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1672                    &Formatter::Prettier
 1673                } else {
 1674                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1675                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1676                }
 1677            } else {
 1678                formatter
 1679            };
 1680            if let Err(err) = Self::apply_formatter(
 1681                formatter,
 1682                &lsp_store,
 1683                buffer,
 1684                formatting_transaction_id,
 1685                &adapters_and_servers,
 1686                &settings,
 1687                request_timeout,
 1688                logger,
 1689                cx,
 1690            )
 1691            .await
 1692            {
 1693                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1694            }
 1695        }
 1696
 1697        Ok(())
 1698    }
 1699
 1700    async fn apply_formatter(
 1701        formatter: &Formatter,
 1702        lsp_store: &WeakEntity<LspStore>,
 1703        buffer: &FormattableBuffer,
 1704        formatting_transaction_id: clock::Lamport,
 1705        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1706        settings: &LanguageSettings,
 1707        request_timeout: Duration,
 1708        logger: zlog::Logger,
 1709        cx: &mut AsyncApp,
 1710    ) -> anyhow::Result<()> {
 1711        match formatter {
 1712            Formatter::None => {
 1713                zlog::trace!(logger => "skipping formatter 'none'");
 1714                return Ok(());
 1715            }
 1716            Formatter::Auto => {
 1717                debug_panic!("Auto resolved above");
 1718                return Ok(());
 1719            }
 1720            Formatter::Prettier => {
 1721                let logger = zlog::scoped!(logger => "prettier");
 1722                zlog::trace!(logger => "formatting");
 1723                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1724
 1725                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1726                    lsp_store.prettier_store().unwrap().downgrade()
 1727                })?;
 1728                let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1729                    .await
 1730                    .transpose()?;
 1731                let Some(diff) = diff else {
 1732                    zlog::trace!(logger => "No changes");
 1733                    return Ok(());
 1734                };
 1735
 1736                extend_formatting_transaction(
 1737                    buffer,
 1738                    formatting_transaction_id,
 1739                    cx,
 1740                    |buffer, cx| {
 1741                        buffer.apply_diff(diff, cx);
 1742                    },
 1743                )?;
 1744            }
 1745            Formatter::External { command, arguments } => {
 1746                let logger = zlog::scoped!(logger => "command");
 1747                zlog::trace!(logger => "formatting");
 1748                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1749
 1750                let diff =
 1751                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1752                        .await
 1753                        .with_context(|| {
 1754                            format!("Failed to format buffer via external command: {}", command)
 1755                        })?;
 1756                let Some(diff) = diff else {
 1757                    zlog::trace!(logger => "No changes");
 1758                    return Ok(());
 1759                };
 1760
 1761                extend_formatting_transaction(
 1762                    buffer,
 1763                    formatting_transaction_id,
 1764                    cx,
 1765                    |buffer, cx| {
 1766                        buffer.apply_diff(diff, cx);
 1767                    },
 1768                )?;
 1769            }
 1770            Formatter::LanguageServer(specifier) => {
 1771                let logger = zlog::scoped!(logger => "language-server");
 1772                zlog::trace!(logger => "formatting");
 1773                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1774
 1775                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1776                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1777                    return Ok(());
 1778                };
 1779
 1780                let language_server = match specifier {
 1781                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1782                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1783                            if adapter.name.0.as_ref() == name {
 1784                                Some(server.clone())
 1785                            } else {
 1786                                None
 1787                            }
 1788                        })
 1789                    }
 1790                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1791                        .iter()
 1792                        .find(|(_, server)| Self::server_supports_formatting(server))
 1793                        .map(|(_, server)| server.clone()),
 1794                };
 1795
 1796                let Some(language_server) = language_server else {
 1797                    log::debug!(
 1798                        "No language server found to format buffer '{:?}'. Skipping",
 1799                        buffer_path_abs.as_path().to_string_lossy()
 1800                    );
 1801                    return Ok(());
 1802                };
 1803
 1804                zlog::trace!(
 1805                    logger =>
 1806                    "Formatting buffer '{:?}' using language server '{:?}'",
 1807                    buffer_path_abs.as_path().to_string_lossy(),
 1808                    language_server.name()
 1809                );
 1810
 1811                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1812                    zlog::trace!(logger => "formatting ranges");
 1813                    Self::format_ranges_via_lsp(
 1814                        &lsp_store,
 1815                        &buffer.handle,
 1816                        ranges,
 1817                        buffer_path_abs,
 1818                        &language_server,
 1819                        &settings,
 1820                        cx,
 1821                    )
 1822                    .await
 1823                    .context("Failed to format ranges via language server")?
 1824                } else {
 1825                    zlog::trace!(logger => "formatting full");
 1826                    Self::format_via_lsp(
 1827                        &lsp_store,
 1828                        &buffer.handle,
 1829                        buffer_path_abs,
 1830                        &language_server,
 1831                        &settings,
 1832                        cx,
 1833                    )
 1834                    .await
 1835                    .context("failed to format via language server")?
 1836                };
 1837
 1838                if edits.is_empty() {
 1839                    zlog::trace!(logger => "No changes");
 1840                    return Ok(());
 1841                }
 1842                extend_formatting_transaction(
 1843                    buffer,
 1844                    formatting_transaction_id,
 1845                    cx,
 1846                    |buffer, cx| {
 1847                        buffer.edit(edits, None, cx);
 1848                    },
 1849                )?;
 1850            }
 1851            Formatter::CodeAction(code_action_name) => {
 1852                let logger = zlog::scoped!(logger => "code-actions");
 1853                zlog::trace!(logger => "formatting");
 1854                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1855
 1856                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1857                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1858                    return Ok(());
 1859                };
 1860
 1861                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1862                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1863
 1864                let mut actions_and_servers = Vec::new();
 1865
 1866                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1867                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1868                        &lsp_store,
 1869                        language_server.server_id(),
 1870                        vec![code_action_kind.clone()],
 1871                        &buffer.handle,
 1872                        cx,
 1873                    )
 1874                    .await
 1875                    .with_context(|| {
 1876                        format!(
 1877                            "Failed to resolve code action {:?} with language server {}",
 1878                            code_action_kind,
 1879                            language_server.name()
 1880                        )
 1881                    });
 1882                    let Ok(actions) = actions_result else {
 1883                        // note: it may be better to set result to the error and break formatters here
 1884                        // but for now we try to execute the actions that we can resolve and skip the rest
 1885                        zlog::error!(
 1886                            logger =>
 1887                            "Failed to resolve code action {:?} with language server {}",
 1888                            code_action_kind,
 1889                            language_server.name()
 1890                        );
 1891                        continue;
 1892                    };
 1893                    for action in actions {
 1894                        actions_and_servers.push((action, index));
 1895                    }
 1896                }
 1897
 1898                if actions_and_servers.is_empty() {
 1899                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1900                    return Ok(());
 1901                }
 1902
 1903                'actions: for (mut action, server_index) in actions_and_servers {
 1904                    let server = &adapters_and_servers[server_index].1;
 1905
 1906                    let describe_code_action = |action: &CodeAction| {
 1907                        format!(
 1908                            "code action '{}' with title \"{}\" on server {}",
 1909                            action
 1910                                .lsp_action
 1911                                .action_kind()
 1912                                .unwrap_or("unknown".into())
 1913                                .as_str(),
 1914                            action.lsp_action.title(),
 1915                            server.name(),
 1916                        )
 1917                    };
 1918
 1919                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1920
 1921                    if let Err(err) =
 1922                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1923                    {
 1924                        zlog::error!(
 1925                            logger =>
 1926                            "Failed to resolve {}. Error: {}",
 1927                            describe_code_action(&action),
 1928                            err
 1929                        );
 1930                        continue;
 1931                    }
 1932
 1933                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1934                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1935                        // but filters out and logs warnings for code actions that require unreasonably
 1936                        // difficult handling on our part, such as:
 1937                        // - applying edits that call commands
 1938                        //   which can result in arbitrary workspace edits being sent from the server that
 1939                        //   have no way of being tied back to the command that initiated them (i.e. we
 1940                        //   can't know which edits are part of the format request, or if the server is done sending
 1941                        //   actions in response to the command)
 1942                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1943                        //   as we then would need to handle such changes correctly in the local history as well
 1944                        //   as the remote history through the ProjectTransaction
 1945                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1946                        // Supporting these actions is not impossible, but not supported as of yet.
 1947                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1948                            zlog::trace!(
 1949                                logger =>
 1950                                "No changes for code action. Skipping {}",
 1951                                describe_code_action(&action),
 1952                            );
 1953                            continue;
 1954                        }
 1955
 1956                        let mut operations = Vec::new();
 1957                        if let Some(document_changes) = edit.document_changes {
 1958                            match document_changes {
 1959                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 1960                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1961                                ),
 1962                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 1963                            }
 1964                        } else if let Some(changes) = edit.changes {
 1965                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 1966                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1967                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 1968                                        uri,
 1969                                        version: None,
 1970                                    },
 1971                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 1972                                })
 1973                            }));
 1974                        }
 1975
 1976                        let mut edits = Vec::with_capacity(operations.len());
 1977
 1978                        if operations.is_empty() {
 1979                            zlog::trace!(
 1980                                logger =>
 1981                                "No changes for code action. Skipping {}",
 1982                                describe_code_action(&action),
 1983                            );
 1984                            continue;
 1985                        }
 1986                        for operation in operations {
 1987                            let op = match operation {
 1988                                lsp::DocumentChangeOperation::Edit(op) => op,
 1989                                lsp::DocumentChangeOperation::Op(_) => {
 1990                                    zlog::warn!(
 1991                                        logger =>
 1992                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1993                                        describe_code_action(&action),
 1994                                    );
 1995                                    continue 'actions;
 1996                                }
 1997                            };
 1998                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1999                                zlog::warn!(
 2000                                    logger =>
 2001                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2002                                    &op.text_document.uri,
 2003                                    describe_code_action(&action),
 2004                                );
 2005                                continue 'actions;
 2006                            };
 2007                            if &file_path != buffer_path_abs {
 2008                                zlog::warn!(
 2009                                    logger =>
 2010                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2011                                    file_path,
 2012                                    buffer_path_abs,
 2013                                    describe_code_action(&action),
 2014                                );
 2015                                continue 'actions;
 2016                            }
 2017
 2018                            let mut lsp_edits = Vec::new();
 2019                            for edit in op.edits {
 2020                                match edit {
 2021                                    Edit::Plain(edit) => {
 2022                                        if !lsp_edits.contains(&edit) {
 2023                                            lsp_edits.push(edit);
 2024                                        }
 2025                                    }
 2026                                    Edit::Annotated(edit) => {
 2027                                        if !lsp_edits.contains(&edit.text_edit) {
 2028                                            lsp_edits.push(edit.text_edit);
 2029                                        }
 2030                                    }
 2031                                    Edit::Snippet(_) => {
 2032                                        zlog::warn!(
 2033                                            logger =>
 2034                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2035                                            describe_code_action(&action),
 2036                                        );
 2037                                        continue 'actions;
 2038                                    }
 2039                                }
 2040                            }
 2041                            let edits_result = lsp_store
 2042                                .update(cx, |lsp_store, cx| {
 2043                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2044                                        &buffer.handle,
 2045                                        lsp_edits,
 2046                                        server.server_id(),
 2047                                        op.text_document.version,
 2048                                        cx,
 2049                                    )
 2050                                })?
 2051                                .await;
 2052                            let Ok(resolved_edits) = edits_result else {
 2053                                zlog::warn!(
 2054                                    logger =>
 2055                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2056                                    buffer_path_abs.as_path(),
 2057                                    describe_code_action(&action),
 2058                                );
 2059                                continue 'actions;
 2060                            };
 2061                            edits.extend(resolved_edits);
 2062                        }
 2063
 2064                        if edits.is_empty() {
 2065                            zlog::warn!(logger => "No edits resolved from LSP");
 2066                            continue;
 2067                        }
 2068
 2069                        extend_formatting_transaction(
 2070                            buffer,
 2071                            formatting_transaction_id,
 2072                            cx,
 2073                            |buffer, cx| {
 2074                                zlog::info!(
 2075                                    "Applying edits {edits:?}. Content: {:?}",
 2076                                    buffer.text()
 2077                                );
 2078                                buffer.edit(edits, None, cx);
 2079                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2080                            },
 2081                        )?;
 2082                    }
 2083
 2084                    let Some(command) = action.lsp_action.command() else {
 2085                        continue;
 2086                    };
 2087
 2088                    zlog::warn!(
 2089                        logger =>
 2090                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2091                        &command.command,
 2092                    );
 2093
 2094                    let server_capabilities = server.capabilities();
 2095                    let available_commands = server_capabilities
 2096                        .execute_command_provider
 2097                        .as_ref()
 2098                        .map(|options| options.commands.as_slice())
 2099                        .unwrap_or_default();
 2100                    if !available_commands.contains(&command.command) {
 2101                        zlog::warn!(
 2102                            logger =>
 2103                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2104                            command.command,
 2105                            server.name(),
 2106                        );
 2107                        continue;
 2108                    }
 2109
 2110                    extend_formatting_transaction(
 2111                        buffer,
 2112                        formatting_transaction_id,
 2113                        cx,
 2114                        |_, _| {},
 2115                    )?;
 2116                    zlog::info!(logger => "Executing command {}", &command.command);
 2117
 2118                    lsp_store.update(cx, |this, _| {
 2119                        this.as_local_mut()
 2120                            .unwrap()
 2121                            .last_workspace_edits_by_language_server
 2122                            .remove(&server.server_id());
 2123                    })?;
 2124
 2125                    let execute_command_result = server
 2126                        .request::<lsp::request::ExecuteCommand>(
 2127                            lsp::ExecuteCommandParams {
 2128                                command: command.command.clone(),
 2129                                arguments: command.arguments.clone().unwrap_or_default(),
 2130                                ..Default::default()
 2131                            },
 2132                            request_timeout,
 2133                        )
 2134                        .await
 2135                        .into_response();
 2136
 2137                    if execute_command_result.is_err() {
 2138                        zlog::error!(
 2139                            logger =>
 2140                            "Failed to execute command '{}' as part of {}",
 2141                            &command.command,
 2142                            describe_code_action(&action),
 2143                        );
 2144                        continue 'actions;
 2145                    }
 2146
 2147                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2148                        this.as_local_mut()
 2149                            .unwrap()
 2150                            .last_workspace_edits_by_language_server
 2151                            .remove(&server.server_id())
 2152                            .unwrap_or_default()
 2153                    })?;
 2154
 2155                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2156                    {
 2157                        zlog::trace!(
 2158                            logger =>
 2159                            "Successfully captured {} edits that resulted from command {}",
 2160                            transaction.edit_ids.len(),
 2161                            &command.command,
 2162                        );
 2163                        let transaction_id_project_transaction = transaction.id;
 2164                        buffer.handle.update(cx, |buffer, _| {
 2165                            // it may have been removed from history if push_to_history was
 2166                            // false in deserialize_workspace_edit. If so push it so we
 2167                            // can merge it with the format transaction
 2168                            // and pop the combined transaction off the history stack
 2169                            // later if push_to_history is false
 2170                            if buffer.get_transaction(transaction.id).is_none() {
 2171                                buffer.push_transaction(transaction, Instant::now());
 2172                            }
 2173                            buffer.merge_transactions(
 2174                                transaction_id_project_transaction,
 2175                                formatting_transaction_id,
 2176                            );
 2177                        });
 2178                    }
 2179
 2180                    if project_transaction_command.0.is_empty() {
 2181                        continue;
 2182                    }
 2183
 2184                    let mut extra_buffers = String::new();
 2185                    for buffer in project_transaction_command.0.keys() {
 2186                        buffer.read_with(cx, |b, cx| {
 2187                            let Some(path) = b.project_path(cx) else {
 2188                                return;
 2189                            };
 2190
 2191                            if !extra_buffers.is_empty() {
 2192                                extra_buffers.push_str(", ");
 2193                            }
 2194                            extra_buffers.push_str(path.path.as_unix_str());
 2195                        });
 2196                    }
 2197                    zlog::warn!(
 2198                        logger =>
 2199                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2200                        &command.command,
 2201                        extra_buffers,
 2202                    );
 2203                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2204                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2205                    // add it so it's included, and merge it into the format transaction when its created later
 2206                }
 2207            }
 2208        }
 2209
 2210        Ok(())
 2211    }
 2212
 2213    pub async fn format_ranges_via_lsp(
 2214        this: &WeakEntity<LspStore>,
 2215        buffer_handle: &Entity<Buffer>,
 2216        ranges: &[Range<Anchor>],
 2217        abs_path: &Path,
 2218        language_server: &Arc<LanguageServer>,
 2219        settings: &LanguageSettings,
 2220        cx: &mut AsyncApp,
 2221    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2222        let capabilities = &language_server.capabilities();
 2223        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2224        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2225            anyhow::bail!(
 2226                "{} language server does not support range formatting",
 2227                language_server.name()
 2228            );
 2229        }
 2230
 2231        let uri = file_path_to_lsp_url(abs_path)?;
 2232        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2233
 2234        let request_timeout = cx.update(|app| {
 2235            ProjectSettings::get_global(app)
 2236                .global_lsp_settings
 2237                .get_request_timeout()
 2238        });
 2239        let lsp_edits = {
 2240            let mut lsp_ranges = Vec::new();
 2241            this.update(cx, |_this, cx| {
 2242                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2243                // not have been sent to the language server. This seems like a fairly systemic
 2244                // issue, though, the resolution probably is not specific to formatting.
 2245                //
 2246                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2247                // LSP.
 2248                let snapshot = buffer_handle.read(cx).snapshot();
 2249                for range in ranges {
 2250                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2251                }
 2252                anyhow::Ok(())
 2253            })??;
 2254
 2255            let mut edits = None;
 2256            for range in lsp_ranges {
 2257                if let Some(mut edit) = language_server
 2258                    .request::<lsp::request::RangeFormatting>(
 2259                        lsp::DocumentRangeFormattingParams {
 2260                            text_document: text_document.clone(),
 2261                            range,
 2262                            options: lsp_command::lsp_formatting_options(settings),
 2263                            work_done_progress_params: Default::default(),
 2264                        },
 2265                        request_timeout,
 2266                    )
 2267                    .await
 2268                    .into_response()?
 2269                {
 2270                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2271                }
 2272            }
 2273            edits
 2274        };
 2275
 2276        if let Some(lsp_edits) = lsp_edits {
 2277            this.update(cx, |this, cx| {
 2278                this.as_local_mut().unwrap().edits_from_lsp(
 2279                    buffer_handle,
 2280                    lsp_edits,
 2281                    language_server.server_id(),
 2282                    None,
 2283                    cx,
 2284                )
 2285            })?
 2286            .await
 2287        } else {
 2288            Ok(Vec::with_capacity(0))
 2289        }
 2290    }
 2291
 2292    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2293        let capabilities = server.capabilities();
 2294        let formatting = capabilities.document_formatting_provider.as_ref();
 2295        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2296        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2297            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2298    }
 2299
 2300    async fn format_via_lsp(
 2301        this: &WeakEntity<LspStore>,
 2302        buffer: &Entity<Buffer>,
 2303        abs_path: &Path,
 2304        language_server: &Arc<LanguageServer>,
 2305        settings: &LanguageSettings,
 2306        cx: &mut AsyncApp,
 2307    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2308        let logger = zlog::scoped!("lsp_format");
 2309        zlog::debug!(logger => "Formatting via LSP");
 2310
 2311        let uri = file_path_to_lsp_url(abs_path)?;
 2312        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2313        let capabilities = &language_server.capabilities();
 2314
 2315        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2316        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2317
 2318        let request_timeout = cx.update(|app| {
 2319            ProjectSettings::get_global(app)
 2320                .global_lsp_settings
 2321                .get_request_timeout()
 2322        });
 2323
 2324        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2325            let _timer = zlog::time!(logger => "format-full");
 2326            language_server
 2327                .request::<lsp::request::Formatting>(
 2328                    lsp::DocumentFormattingParams {
 2329                        text_document,
 2330                        options: lsp_command::lsp_formatting_options(settings),
 2331                        work_done_progress_params: Default::default(),
 2332                    },
 2333                    request_timeout,
 2334                )
 2335                .await
 2336                .into_response()?
 2337        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2338            let _timer = zlog::time!(logger => "format-range");
 2339            let buffer_start = lsp::Position::new(0, 0);
 2340            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2341            language_server
 2342                .request::<lsp::request::RangeFormatting>(
 2343                    lsp::DocumentRangeFormattingParams {
 2344                        text_document: text_document.clone(),
 2345                        range: lsp::Range::new(buffer_start, buffer_end),
 2346                        options: lsp_command::lsp_formatting_options(settings),
 2347                        work_done_progress_params: Default::default(),
 2348                    },
 2349                    request_timeout,
 2350                )
 2351                .await
 2352                .into_response()?
 2353        } else {
 2354            None
 2355        };
 2356
 2357        if let Some(lsp_edits) = lsp_edits {
 2358            this.update(cx, |this, cx| {
 2359                this.as_local_mut().unwrap().edits_from_lsp(
 2360                    buffer,
 2361                    lsp_edits,
 2362                    language_server.server_id(),
 2363                    None,
 2364                    cx,
 2365                )
 2366            })?
 2367            .await
 2368        } else {
 2369            Ok(Vec::with_capacity(0))
 2370        }
 2371    }
 2372
 2373    async fn format_via_external_command(
 2374        buffer: &FormattableBuffer,
 2375        command: &str,
 2376        arguments: Option<&[String]>,
 2377        cx: &mut AsyncApp,
 2378    ) -> Result<Option<Diff>> {
 2379        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2380            let file = File::from_dyn(buffer.file())?;
 2381            let worktree = file.worktree.read(cx);
 2382            let mut worktree_path = worktree.abs_path().to_path_buf();
 2383            if worktree.root_entry()?.is_file() {
 2384                worktree_path.pop();
 2385            }
 2386            Some(worktree_path)
 2387        });
 2388
 2389        use util::command::Stdio;
 2390        let mut child = util::command::new_command(command);
 2391
 2392        if let Some(buffer_env) = buffer.env.as_ref() {
 2393            child.envs(buffer_env);
 2394        }
 2395
 2396        if let Some(working_dir_path) = working_dir_path {
 2397            child.current_dir(working_dir_path);
 2398        }
 2399
 2400        if let Some(arguments) = arguments {
 2401            child.args(arguments.iter().map(|arg| {
 2402                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2403                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2404                } else {
 2405                    arg.replace("{buffer_path}", "Untitled")
 2406                }
 2407            }));
 2408        }
 2409
 2410        let mut child = child
 2411            .stdin(Stdio::piped())
 2412            .stdout(Stdio::piped())
 2413            .stderr(Stdio::piped())
 2414            .spawn()?;
 2415
 2416        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2417        let text = buffer
 2418            .handle
 2419            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2420        for chunk in text.chunks() {
 2421            stdin.write_all(chunk.as_bytes()).await?;
 2422        }
 2423        stdin.flush().await?;
 2424
 2425        let output = child.output().await?;
 2426        anyhow::ensure!(
 2427            output.status.success(),
 2428            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2429            output.status.code(),
 2430            String::from_utf8_lossy(&output.stdout),
 2431            String::from_utf8_lossy(&output.stderr),
 2432        );
 2433
 2434        let stdout = String::from_utf8(output.stdout)?;
 2435        Ok(Some(
 2436            buffer
 2437                .handle
 2438                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2439                .await,
 2440        ))
 2441    }
 2442
 2443    async fn try_resolve_code_action(
 2444        lang_server: &LanguageServer,
 2445        action: &mut CodeAction,
 2446        request_timeout: Duration,
 2447    ) -> anyhow::Result<()> {
 2448        match &mut action.lsp_action {
 2449            LspAction::Action(lsp_action) => {
 2450                if !action.resolved
 2451                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2452                    && lsp_action.data.is_some()
 2453                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2454                {
 2455                    **lsp_action = lang_server
 2456                        .request::<lsp::request::CodeActionResolveRequest>(
 2457                            *lsp_action.clone(),
 2458                            request_timeout,
 2459                        )
 2460                        .await
 2461                        .into_response()?;
 2462                }
 2463            }
 2464            LspAction::CodeLens(lens) => {
 2465                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2466                    *lens = lang_server
 2467                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2468                        .await
 2469                        .into_response()?;
 2470                }
 2471            }
 2472            LspAction::Command(_) => {}
 2473        }
 2474
 2475        action.resolved = true;
 2476        anyhow::Ok(())
 2477    }
 2478
 2479    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2480        let buffer = buffer_handle.read(cx);
 2481
 2482        let file = buffer.file().cloned();
 2483
 2484        let Some(file) = File::from_dyn(file.as_ref()) else {
 2485            return;
 2486        };
 2487        if !file.is_local() {
 2488            return;
 2489        }
 2490        let path = ProjectPath::from_file(file, cx);
 2491        let worktree_id = file.worktree_id(cx);
 2492        let language = buffer.language().cloned();
 2493
 2494        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2495            for (server_id, diagnostics) in
 2496                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2497            {
 2498                self.update_buffer_diagnostics(
 2499                    buffer_handle,
 2500                    server_id,
 2501                    None,
 2502                    None,
 2503                    None,
 2504                    Vec::new(),
 2505                    diagnostics,
 2506                    cx,
 2507                )
 2508                .log_err();
 2509            }
 2510        }
 2511        let Some(language) = language else {
 2512            return;
 2513        };
 2514        let Some(snapshot) = self
 2515            .worktree_store
 2516            .read(cx)
 2517            .worktree_for_id(worktree_id, cx)
 2518            .map(|worktree| worktree.read(cx).snapshot())
 2519        else {
 2520            return;
 2521        };
 2522        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2523
 2524        for server_id in
 2525            self.lsp_tree
 2526                .get(path, language.name(), language.manifest(), &delegate, cx)
 2527        {
 2528            let server = self
 2529                .language_servers
 2530                .get(&server_id)
 2531                .and_then(|server_state| {
 2532                    if let LanguageServerState::Running { server, .. } = server_state {
 2533                        Some(server.clone())
 2534                    } else {
 2535                        None
 2536                    }
 2537                });
 2538            let server = match server {
 2539                Some(server) => server,
 2540                None => continue,
 2541            };
 2542
 2543            buffer_handle.update(cx, |buffer, cx| {
 2544                buffer.set_completion_triggers(
 2545                    server.server_id(),
 2546                    server
 2547                        .capabilities()
 2548                        .completion_provider
 2549                        .as_ref()
 2550                        .and_then(|provider| {
 2551                            provider
 2552                                .trigger_characters
 2553                                .as_ref()
 2554                                .map(|characters| characters.iter().cloned().collect())
 2555                        })
 2556                        .unwrap_or_default(),
 2557                    cx,
 2558                );
 2559            });
 2560        }
 2561    }
 2562
 2563    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2564        buffer.update(cx, |buffer, cx| {
 2565            let Some(language) = buffer.language() else {
 2566                return;
 2567            };
 2568            let path = ProjectPath {
 2569                worktree_id: old_file.worktree_id(cx),
 2570                path: old_file.path.clone(),
 2571            };
 2572            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2573                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2574                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2575            }
 2576        });
 2577    }
 2578
 2579    fn update_buffer_diagnostics(
 2580        &mut self,
 2581        buffer: &Entity<Buffer>,
 2582        server_id: LanguageServerId,
 2583        registration_id: Option<Option<SharedString>>,
 2584        result_id: Option<SharedString>,
 2585        version: Option<i32>,
 2586        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2587        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2588        cx: &mut Context<LspStore>,
 2589    ) -> Result<()> {
 2590        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2591            Ordering::Equal
 2592                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2593                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2594                .then_with(|| a.severity.cmp(&b.severity))
 2595                .then_with(|| a.message.cmp(&b.message))
 2596        }
 2597
 2598        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2599        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2600        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2601
 2602        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2603            Ordering::Equal
 2604                .then_with(|| a.range.start.cmp(&b.range.start))
 2605                .then_with(|| b.range.end.cmp(&a.range.end))
 2606                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2607        });
 2608
 2609        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2610
 2611        let edits_since_save = std::cell::LazyCell::new(|| {
 2612            let saved_version = buffer.read(cx).saved_version();
 2613            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2614        });
 2615
 2616        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2617
 2618        for (new_diagnostic, entry) in diagnostics {
 2619            let start;
 2620            let end;
 2621            if new_diagnostic && entry.diagnostic.is_disk_based {
 2622                // Some diagnostics are based on files on disk instead of buffers'
 2623                // current contents. Adjust these diagnostics' ranges to reflect
 2624                // any unsaved edits.
 2625                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2626                // and were properly adjusted on reuse.
 2627                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2628                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2629            } else {
 2630                start = entry.range.start;
 2631                end = entry.range.end;
 2632            }
 2633
 2634            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2635                ..snapshot.clip_point_utf16(end, Bias::Right);
 2636
 2637            // Expand empty ranges by one codepoint
 2638            if range.start == range.end {
 2639                // This will be go to the next boundary when being clipped
 2640                range.end.column += 1;
 2641                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2642                if range.start == range.end && range.end.column > 0 {
 2643                    range.start.column -= 1;
 2644                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2645                }
 2646            }
 2647
 2648            sanitized_diagnostics.push(DiagnosticEntry {
 2649                range,
 2650                diagnostic: entry.diagnostic,
 2651            });
 2652        }
 2653        drop(edits_since_save);
 2654
 2655        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2656        buffer.update(cx, |buffer, cx| {
 2657            if let Some(registration_id) = registration_id {
 2658                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2659                    self.buffer_pull_diagnostics_result_ids
 2660                        .entry(server_id)
 2661                        .or_default()
 2662                        .entry(registration_id)
 2663                        .or_default()
 2664                        .insert(abs_path, result_id);
 2665                }
 2666            }
 2667
 2668            buffer.update_diagnostics(server_id, set, cx)
 2669        });
 2670
 2671        Ok(())
 2672    }
 2673
 2674    fn register_language_server_for_invisible_worktree(
 2675        &mut self,
 2676        worktree: &Entity<Worktree>,
 2677        language_server_id: LanguageServerId,
 2678        cx: &mut App,
 2679    ) {
 2680        let worktree = worktree.read(cx);
 2681        let worktree_id = worktree.id();
 2682        debug_assert!(!worktree.is_visible());
 2683        let Some(mut origin_seed) = self
 2684            .language_server_ids
 2685            .iter()
 2686            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2687        else {
 2688            return;
 2689        };
 2690        origin_seed.worktree_id = worktree_id;
 2691        self.language_server_ids
 2692            .entry(origin_seed)
 2693            .or_insert_with(|| UnifiedLanguageServer {
 2694                id: language_server_id,
 2695                project_roots: Default::default(),
 2696            });
 2697    }
 2698
 2699    fn register_buffer_with_language_servers(
 2700        &mut self,
 2701        buffer_handle: &Entity<Buffer>,
 2702        only_register_servers: HashSet<LanguageServerSelector>,
 2703        cx: &mut Context<LspStore>,
 2704    ) {
 2705        let buffer = buffer_handle.read(cx);
 2706        let buffer_id = buffer.remote_id();
 2707
 2708        let Some(file) = File::from_dyn(buffer.file()) else {
 2709            return;
 2710        };
 2711        if !file.is_local() {
 2712            return;
 2713        }
 2714
 2715        let abs_path = file.abs_path(cx);
 2716        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2717            return;
 2718        };
 2719        let initial_snapshot = buffer.text_snapshot();
 2720        let worktree_id = file.worktree_id(cx);
 2721
 2722        let Some(language) = buffer.language().cloned() else {
 2723            return;
 2724        };
 2725        let path: Arc<RelPath> = file
 2726            .path()
 2727            .parent()
 2728            .map(Arc::from)
 2729            .unwrap_or_else(|| file.path().clone());
 2730        let Some(worktree) = self
 2731            .worktree_store
 2732            .read(cx)
 2733            .worktree_for_id(worktree_id, cx)
 2734        else {
 2735            return;
 2736        };
 2737        let language_name = language.name();
 2738        let (reused, delegate, servers) = self
 2739            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2740            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2741            .unwrap_or_else(|| {
 2742                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2743                let delegate: Arc<dyn ManifestDelegate> =
 2744                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2745
 2746                let servers = self
 2747                    .lsp_tree
 2748                    .walk(
 2749                        ProjectPath { worktree_id, path },
 2750                        language.name(),
 2751                        language.manifest(),
 2752                        &delegate,
 2753                        cx,
 2754                    )
 2755                    .collect::<Vec<_>>();
 2756                (false, lsp_delegate, servers)
 2757            });
 2758        let servers_and_adapters = servers
 2759            .into_iter()
 2760            .filter_map(|server_node| {
 2761                if reused && server_node.server_id().is_none() {
 2762                    return None;
 2763                }
 2764                if !only_register_servers.is_empty() {
 2765                    if let Some(server_id) = server_node.server_id()
 2766                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2767                    {
 2768                        return None;
 2769                    }
 2770                    if let Some(name) = server_node.name()
 2771                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2772                    {
 2773                        return None;
 2774                    }
 2775                }
 2776
 2777                let server_id = server_node.server_id_or_init(|disposition| {
 2778                    let path = &disposition.path;
 2779
 2780                    {
 2781                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2782
 2783                        let server_id = self.get_or_insert_language_server(
 2784                            &worktree,
 2785                            delegate.clone(),
 2786                            disposition,
 2787                            &language_name,
 2788                            cx,
 2789                        );
 2790
 2791                        if let Some(state) = self.language_servers.get(&server_id)
 2792                            && let Ok(uri) = uri
 2793                        {
 2794                            state.add_workspace_folder(uri);
 2795                        };
 2796                        server_id
 2797                    }
 2798                })?;
 2799                let server_state = self.language_servers.get(&server_id)?;
 2800                if let LanguageServerState::Running {
 2801                    server, adapter, ..
 2802                } = server_state
 2803                {
 2804                    Some((server.clone(), adapter.clone()))
 2805                } else {
 2806                    None
 2807                }
 2808            })
 2809            .collect::<Vec<_>>();
 2810        for (server, adapter) in servers_and_adapters {
 2811            buffer_handle.update(cx, |buffer, cx| {
 2812                buffer.set_completion_triggers(
 2813                    server.server_id(),
 2814                    server
 2815                        .capabilities()
 2816                        .completion_provider
 2817                        .as_ref()
 2818                        .and_then(|provider| {
 2819                            provider
 2820                                .trigger_characters
 2821                                .as_ref()
 2822                                .map(|characters| characters.iter().cloned().collect())
 2823                        })
 2824                        .unwrap_or_default(),
 2825                    cx,
 2826                );
 2827            });
 2828
 2829            let snapshot = LspBufferSnapshot {
 2830                version: 0,
 2831                snapshot: initial_snapshot.clone(),
 2832            };
 2833
 2834            let mut registered = false;
 2835            self.buffer_snapshots
 2836                .entry(buffer_id)
 2837                .or_default()
 2838                .entry(server.server_id())
 2839                .or_insert_with(|| {
 2840                    registered = true;
 2841                    server.register_buffer(
 2842                        uri.clone(),
 2843                        adapter.language_id(&language.name()),
 2844                        0,
 2845                        initial_snapshot.text(),
 2846                    );
 2847
 2848                    vec![snapshot]
 2849                });
 2850
 2851            self.buffers_opened_in_servers
 2852                .entry(buffer_id)
 2853                .or_default()
 2854                .insert(server.server_id());
 2855            if registered {
 2856                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2857                    language_server_id: server.server_id(),
 2858                    name: None,
 2859                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2860                        proto::RegisteredForBuffer {
 2861                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2862                            buffer_id: buffer_id.to_proto(),
 2863                        },
 2864                    ),
 2865                });
 2866            }
 2867        }
 2868    }
 2869
 2870    fn reuse_existing_language_server<'lang_name>(
 2871        &self,
 2872        server_tree: &LanguageServerTree,
 2873        worktree: &Entity<Worktree>,
 2874        language_name: &'lang_name LanguageName,
 2875        cx: &mut App,
 2876    ) -> Option<(
 2877        Arc<LocalLspAdapterDelegate>,
 2878        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2879    )> {
 2880        if worktree.read(cx).is_visible() {
 2881            return None;
 2882        }
 2883
 2884        let worktree_store = self.worktree_store.read(cx);
 2885        let servers = server_tree
 2886            .instances
 2887            .iter()
 2888            .filter(|(worktree_id, _)| {
 2889                worktree_store
 2890                    .worktree_for_id(**worktree_id, cx)
 2891                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2892            })
 2893            .flat_map(|(worktree_id, servers)| {
 2894                servers
 2895                    .roots
 2896                    .iter()
 2897                    .flat_map(|(_, language_servers)| language_servers)
 2898                    .map(move |(_, (server_node, server_languages))| {
 2899                        (worktree_id, server_node, server_languages)
 2900                    })
 2901                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2902                    .map(|(worktree_id, server_node, _)| {
 2903                        (
 2904                            *worktree_id,
 2905                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2906                        )
 2907                    })
 2908            })
 2909            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2910                acc.entry(worktree_id)
 2911                    .or_insert_with(Vec::new)
 2912                    .push(server_node);
 2913                acc
 2914            })
 2915            .into_values()
 2916            .max_by_key(|servers| servers.len())?;
 2917
 2918        let worktree_id = worktree.read(cx).id();
 2919        let apply = move |tree: &mut LanguageServerTree| {
 2920            for server_node in &servers {
 2921                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2922            }
 2923            servers
 2924        };
 2925
 2926        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2927        Some((delegate, apply))
 2928    }
 2929
 2930    pub(crate) fn unregister_old_buffer_from_language_servers(
 2931        &mut self,
 2932        buffer: &Entity<Buffer>,
 2933        old_file: &File,
 2934        cx: &mut App,
 2935    ) {
 2936        let old_path = match old_file.as_local() {
 2937            Some(local) => local.abs_path(cx),
 2938            None => return,
 2939        };
 2940
 2941        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2942            debug_panic!("{old_path:?} is not parseable as an URI");
 2943            return;
 2944        };
 2945        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2946    }
 2947
 2948    pub(crate) fn unregister_buffer_from_language_servers(
 2949        &mut self,
 2950        buffer: &Entity<Buffer>,
 2951        file_url: &lsp::Uri,
 2952        cx: &mut App,
 2953    ) {
 2954        buffer.update(cx, |buffer, cx| {
 2955            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2956
 2957            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2958                if snapshots
 2959                    .as_mut()
 2960                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2961                {
 2962                    language_server.unregister_buffer(file_url.clone());
 2963                }
 2964            }
 2965        });
 2966    }
 2967
 2968    fn buffer_snapshot_for_lsp_version(
 2969        &mut self,
 2970        buffer: &Entity<Buffer>,
 2971        server_id: LanguageServerId,
 2972        version: Option<i32>,
 2973        cx: &App,
 2974    ) -> Result<TextBufferSnapshot> {
 2975        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2976
 2977        if let Some(version) = version {
 2978            let buffer_id = buffer.read(cx).remote_id();
 2979            let snapshots = if let Some(snapshots) = self
 2980                .buffer_snapshots
 2981                .get_mut(&buffer_id)
 2982                .and_then(|m| m.get_mut(&server_id))
 2983            {
 2984                snapshots
 2985            } else if version == 0 {
 2986                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2987                // We detect this case and treat it as if the version was `None`.
 2988                return Ok(buffer.read(cx).text_snapshot());
 2989            } else {
 2990                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2991            };
 2992
 2993            let found_snapshot = snapshots
 2994                    .binary_search_by_key(&version, |e| e.version)
 2995                    .map(|ix| snapshots[ix].snapshot.clone())
 2996                    .map_err(|_| {
 2997                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2998                    })?;
 2999
 3000            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3001            Ok(found_snapshot)
 3002        } else {
 3003            Ok((buffer.read(cx)).text_snapshot())
 3004        }
 3005    }
 3006
 3007    async fn get_server_code_actions_from_action_kinds(
 3008        lsp_store: &WeakEntity<LspStore>,
 3009        language_server_id: LanguageServerId,
 3010        code_action_kinds: Vec<lsp::CodeActionKind>,
 3011        buffer: &Entity<Buffer>,
 3012        cx: &mut AsyncApp,
 3013    ) -> Result<Vec<CodeAction>> {
 3014        let actions = lsp_store
 3015            .update(cx, move |this, cx| {
 3016                let request = GetCodeActions {
 3017                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3018                    kinds: Some(code_action_kinds),
 3019                };
 3020                let server = LanguageServerToQuery::Other(language_server_id);
 3021                this.request_lsp(buffer.clone(), server, request, cx)
 3022            })?
 3023            .await?;
 3024        Ok(actions)
 3025    }
 3026
 3027    pub async fn execute_code_actions_on_server(
 3028        lsp_store: &WeakEntity<LspStore>,
 3029        language_server: &Arc<LanguageServer>,
 3030        actions: Vec<CodeAction>,
 3031        push_to_history: bool,
 3032        project_transaction: &mut ProjectTransaction,
 3033        cx: &mut AsyncApp,
 3034    ) -> anyhow::Result<()> {
 3035        let request_timeout = cx.update(|app| {
 3036            ProjectSettings::get_global(app)
 3037                .global_lsp_settings
 3038                .get_request_timeout()
 3039        });
 3040
 3041        for mut action in actions {
 3042            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3043                .await
 3044                .context("resolving a formatting code action")?;
 3045
 3046            if let Some(edit) = action.lsp_action.edit() {
 3047                if edit.changes.is_none() && edit.document_changes.is_none() {
 3048                    continue;
 3049                }
 3050
 3051                let new = Self::deserialize_workspace_edit(
 3052                    lsp_store.upgrade().context("project dropped")?,
 3053                    edit.clone(),
 3054                    push_to_history,
 3055                    language_server.clone(),
 3056                    cx,
 3057                )
 3058                .await?;
 3059                project_transaction.0.extend(new.0);
 3060            }
 3061
 3062            let Some(command) = action.lsp_action.command() else {
 3063                continue;
 3064            };
 3065
 3066            let server_capabilities = language_server.capabilities();
 3067            let available_commands = server_capabilities
 3068                .execute_command_provider
 3069                .as_ref()
 3070                .map(|options| options.commands.as_slice())
 3071                .unwrap_or_default();
 3072            if !available_commands.contains(&command.command) {
 3073                log::warn!(
 3074                    "Cannot execute a command {} not listed in the language server capabilities",
 3075                    command.command
 3076                );
 3077                continue;
 3078            }
 3079
 3080            lsp_store.update(cx, |lsp_store, _| {
 3081                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3082                    mode.last_workspace_edits_by_language_server
 3083                        .remove(&language_server.server_id());
 3084                }
 3085            })?;
 3086
 3087            language_server
 3088                .request::<lsp::request::ExecuteCommand>(
 3089                    lsp::ExecuteCommandParams {
 3090                        command: command.command.clone(),
 3091                        arguments: command.arguments.clone().unwrap_or_default(),
 3092                        ..Default::default()
 3093                    },
 3094                    request_timeout,
 3095                )
 3096                .await
 3097                .into_response()
 3098                .context("execute command")?;
 3099
 3100            lsp_store.update(cx, |this, _| {
 3101                if let LspStoreMode::Local(mode) = &mut this.mode {
 3102                    project_transaction.0.extend(
 3103                        mode.last_workspace_edits_by_language_server
 3104                            .remove(&language_server.server_id())
 3105                            .unwrap_or_default()
 3106                            .0,
 3107                    )
 3108                }
 3109            })?;
 3110        }
 3111        Ok(())
 3112    }
 3113
 3114    pub async fn deserialize_text_edits(
 3115        this: Entity<LspStore>,
 3116        buffer_to_edit: Entity<Buffer>,
 3117        edits: Vec<lsp::TextEdit>,
 3118        push_to_history: bool,
 3119        _: Arc<CachedLspAdapter>,
 3120        language_server: Arc<LanguageServer>,
 3121        cx: &mut AsyncApp,
 3122    ) -> Result<Option<Transaction>> {
 3123        let edits = this
 3124            .update(cx, |this, cx| {
 3125                this.as_local_mut().unwrap().edits_from_lsp(
 3126                    &buffer_to_edit,
 3127                    edits,
 3128                    language_server.server_id(),
 3129                    None,
 3130                    cx,
 3131                )
 3132            })
 3133            .await?;
 3134
 3135        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3136            buffer.finalize_last_transaction();
 3137            buffer.start_transaction();
 3138            for (range, text) in edits {
 3139                buffer.edit([(range, text)], None, cx);
 3140            }
 3141
 3142            if buffer.end_transaction(cx).is_some() {
 3143                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3144                if !push_to_history {
 3145                    buffer.forget_transaction(transaction.id);
 3146                }
 3147                Some(transaction)
 3148            } else {
 3149                None
 3150            }
 3151        });
 3152
 3153        Ok(transaction)
 3154    }
 3155
 3156    #[allow(clippy::type_complexity)]
 3157    pub fn edits_from_lsp(
 3158        &mut self,
 3159        buffer: &Entity<Buffer>,
 3160        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3161        server_id: LanguageServerId,
 3162        version: Option<i32>,
 3163        cx: &mut Context<LspStore>,
 3164    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3165        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3166        cx.background_spawn(async move {
 3167            let snapshot = snapshot?;
 3168            let mut lsp_edits = lsp_edits
 3169                .into_iter()
 3170                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3171                .collect::<Vec<_>>();
 3172
 3173            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3174
 3175            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3176            let mut edits = Vec::new();
 3177            while let Some((range, mut new_text)) = lsp_edits.next() {
 3178                // Clip invalid ranges provided by the language server.
 3179                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3180                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3181
 3182                // Combine any LSP edits that are adjacent.
 3183                //
 3184                // Also, combine LSP edits that are separated from each other by only
 3185                // a newline. This is important because for some code actions,
 3186                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3187                // are separated by unchanged newline characters.
 3188                //
 3189                // In order for the diffing logic below to work properly, any edits that
 3190                // cancel each other out must be combined into one.
 3191                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3192                    if next_range.start.0 > range.end {
 3193                        if next_range.start.0.row > range.end.row + 1
 3194                            || next_range.start.0.column > 0
 3195                            || snapshot.clip_point_utf16(
 3196                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3197                                Bias::Left,
 3198                            ) > range.end
 3199                        {
 3200                            break;
 3201                        }
 3202                        new_text.push('\n');
 3203                    }
 3204                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3205                    new_text.push_str(next_text);
 3206                    lsp_edits.next();
 3207                }
 3208
 3209                // For multiline edits, perform a diff of the old and new text so that
 3210                // we can identify the changes more precisely, preserving the locations
 3211                // of any anchors positioned in the unchanged regions.
 3212                if range.end.row > range.start.row {
 3213                    let offset = range.start.to_offset(&snapshot);
 3214                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3215                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3216                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3217                        (
 3218                            snapshot.anchor_after(offset + range.start)
 3219                                ..snapshot.anchor_before(offset + range.end),
 3220                            replacement,
 3221                        )
 3222                    }));
 3223                } else if range.end == range.start {
 3224                    let anchor = snapshot.anchor_after(range.start);
 3225                    edits.push((anchor..anchor, new_text.into()));
 3226                } else {
 3227                    let edit_start = snapshot.anchor_after(range.start);
 3228                    let edit_end = snapshot.anchor_before(range.end);
 3229                    edits.push((edit_start..edit_end, new_text.into()));
 3230                }
 3231            }
 3232
 3233            Ok(edits)
 3234        })
 3235    }
 3236
 3237    pub(crate) async fn deserialize_workspace_edit(
 3238        this: Entity<LspStore>,
 3239        edit: lsp::WorkspaceEdit,
 3240        push_to_history: bool,
 3241        language_server: Arc<LanguageServer>,
 3242        cx: &mut AsyncApp,
 3243    ) -> Result<ProjectTransaction> {
 3244        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3245
 3246        let mut operations = Vec::new();
 3247        if let Some(document_changes) = edit.document_changes {
 3248            match document_changes {
 3249                lsp::DocumentChanges::Edits(edits) => {
 3250                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3251                }
 3252                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3253            }
 3254        } else if let Some(changes) = edit.changes {
 3255            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3256                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3257                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3258                        uri,
 3259                        version: None,
 3260                    },
 3261                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3262                })
 3263            }));
 3264        }
 3265
 3266        let mut project_transaction = ProjectTransaction::default();
 3267        for operation in operations {
 3268            match operation {
 3269                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3270                    let abs_path = op
 3271                        .uri
 3272                        .to_file_path()
 3273                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3274
 3275                    if let Some(parent_path) = abs_path.parent() {
 3276                        fs.create_dir(parent_path).await?;
 3277                    }
 3278                    if abs_path.ends_with("/") {
 3279                        fs.create_dir(&abs_path).await?;
 3280                    } else {
 3281                        fs.create_file(
 3282                            &abs_path,
 3283                            op.options
 3284                                .map(|options| fs::CreateOptions {
 3285                                    overwrite: options.overwrite.unwrap_or(false),
 3286                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3287                                })
 3288                                .unwrap_or_default(),
 3289                        )
 3290                        .await?;
 3291                    }
 3292                }
 3293
 3294                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3295                    let source_abs_path = op
 3296                        .old_uri
 3297                        .to_file_path()
 3298                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3299                    let target_abs_path = op
 3300                        .new_uri
 3301                        .to_file_path()
 3302                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3303
 3304                    let options = fs::RenameOptions {
 3305                        overwrite: op
 3306                            .options
 3307                            .as_ref()
 3308                            .and_then(|options| options.overwrite)
 3309                            .unwrap_or(false),
 3310                        ignore_if_exists: op
 3311                            .options
 3312                            .as_ref()
 3313                            .and_then(|options| options.ignore_if_exists)
 3314                            .unwrap_or(false),
 3315                        create_parents: true,
 3316                    };
 3317
 3318                    fs.rename(&source_abs_path, &target_abs_path, options)
 3319                        .await?;
 3320                }
 3321
 3322                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3323                    let abs_path = op
 3324                        .uri
 3325                        .to_file_path()
 3326                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3327                    let options = op
 3328                        .options
 3329                        .map(|options| fs::RemoveOptions {
 3330                            recursive: options.recursive.unwrap_or(false),
 3331                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3332                        })
 3333                        .unwrap_or_default();
 3334                    if abs_path.ends_with("/") {
 3335                        fs.remove_dir(&abs_path, options).await?;
 3336                    } else {
 3337                        fs.remove_file(&abs_path, options).await?;
 3338                    }
 3339                }
 3340
 3341                lsp::DocumentChangeOperation::Edit(op) => {
 3342                    let buffer_to_edit = this
 3343                        .update(cx, |this, cx| {
 3344                            this.open_local_buffer_via_lsp(
 3345                                op.text_document.uri.clone(),
 3346                                language_server.server_id(),
 3347                                cx,
 3348                            )
 3349                        })
 3350                        .await?;
 3351
 3352                    let edits = this
 3353                        .update(cx, |this, cx| {
 3354                            let path = buffer_to_edit.read(cx).project_path(cx);
 3355                            let active_entry = this.active_entry;
 3356                            let is_active_entry = path.is_some_and(|project_path| {
 3357                                this.worktree_store
 3358                                    .read(cx)
 3359                                    .entry_for_path(&project_path, cx)
 3360                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3361                            });
 3362                            let local = this.as_local_mut().unwrap();
 3363
 3364                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3365                            for edit in op.edits {
 3366                                match edit {
 3367                                    Edit::Plain(edit) => {
 3368                                        if !edits.contains(&edit) {
 3369                                            edits.push(edit)
 3370                                        }
 3371                                    }
 3372                                    Edit::Annotated(edit) => {
 3373                                        if !edits.contains(&edit.text_edit) {
 3374                                            edits.push(edit.text_edit)
 3375                                        }
 3376                                    }
 3377                                    Edit::Snippet(edit) => {
 3378                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3379                                        else {
 3380                                            continue;
 3381                                        };
 3382
 3383                                        if is_active_entry {
 3384                                            snippet_edits.push((edit.range, snippet));
 3385                                        } else {
 3386                                            // Since this buffer is not focused, apply a normal edit.
 3387                                            let new_edit = TextEdit {
 3388                                                range: edit.range,
 3389                                                new_text: snippet.text,
 3390                                            };
 3391                                            if !edits.contains(&new_edit) {
 3392                                                edits.push(new_edit);
 3393                                            }
 3394                                        }
 3395                                    }
 3396                                }
 3397                            }
 3398                            if !snippet_edits.is_empty() {
 3399                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3400                                let version = if let Some(buffer_version) = op.text_document.version
 3401                                {
 3402                                    local
 3403                                        .buffer_snapshot_for_lsp_version(
 3404                                            &buffer_to_edit,
 3405                                            language_server.server_id(),
 3406                                            Some(buffer_version),
 3407                                            cx,
 3408                                        )
 3409                                        .ok()
 3410                                        .map(|snapshot| snapshot.version)
 3411                                } else {
 3412                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3413                                };
 3414
 3415                                let most_recent_edit =
 3416                                    version.and_then(|version| version.most_recent());
 3417                                // Check if the edit that triggered that edit has been made by this participant.
 3418
 3419                                if let Some(most_recent_edit) = most_recent_edit {
 3420                                    cx.emit(LspStoreEvent::SnippetEdit {
 3421                                        buffer_id,
 3422                                        edits: snippet_edits,
 3423                                        most_recent_edit,
 3424                                    });
 3425                                }
 3426                            }
 3427
 3428                            local.edits_from_lsp(
 3429                                &buffer_to_edit,
 3430                                edits,
 3431                                language_server.server_id(),
 3432                                op.text_document.version,
 3433                                cx,
 3434                            )
 3435                        })
 3436                        .await?;
 3437
 3438                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3439                        buffer.finalize_last_transaction();
 3440                        buffer.start_transaction();
 3441                        for (range, text) in edits {
 3442                            buffer.edit([(range, text)], None, cx);
 3443                        }
 3444
 3445                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3446                            if push_to_history {
 3447                                buffer.finalize_last_transaction();
 3448                                buffer.get_transaction(transaction_id).cloned()
 3449                            } else {
 3450                                buffer.forget_transaction(transaction_id)
 3451                            }
 3452                        })
 3453                    });
 3454                    if let Some(transaction) = transaction {
 3455                        project_transaction.0.insert(buffer_to_edit, transaction);
 3456                    }
 3457                }
 3458            }
 3459        }
 3460
 3461        Ok(project_transaction)
 3462    }
 3463
 3464    async fn on_lsp_workspace_edit(
 3465        this: WeakEntity<LspStore>,
 3466        params: lsp::ApplyWorkspaceEditParams,
 3467        server_id: LanguageServerId,
 3468        cx: &mut AsyncApp,
 3469    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3470        let this = this.upgrade().context("project project closed")?;
 3471        let language_server = this
 3472            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3473            .context("language server not found")?;
 3474        let transaction = Self::deserialize_workspace_edit(
 3475            this.clone(),
 3476            params.edit,
 3477            true,
 3478            language_server.clone(),
 3479            cx,
 3480        )
 3481        .await
 3482        .log_err();
 3483        this.update(cx, |this, cx| {
 3484            if let Some(transaction) = transaction {
 3485                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3486
 3487                this.as_local_mut()
 3488                    .unwrap()
 3489                    .last_workspace_edits_by_language_server
 3490                    .insert(server_id, transaction);
 3491            }
 3492        });
 3493        Ok(lsp::ApplyWorkspaceEditResponse {
 3494            applied: true,
 3495            failed_change: None,
 3496            failure_reason: None,
 3497        })
 3498    }
 3499
 3500    fn remove_worktree(
 3501        &mut self,
 3502        id_to_remove: WorktreeId,
 3503        cx: &mut Context<LspStore>,
 3504    ) -> Vec<LanguageServerId> {
 3505        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3506        self.diagnostics.remove(&id_to_remove);
 3507        self.prettier_store.update(cx, |prettier_store, cx| {
 3508            prettier_store.remove_worktree(id_to_remove, cx);
 3509        });
 3510
 3511        let mut servers_to_remove = BTreeSet::default();
 3512        let mut servers_to_preserve = HashSet::default();
 3513        for (seed, state) in &self.language_server_ids {
 3514            if seed.worktree_id == id_to_remove {
 3515                servers_to_remove.insert(state.id);
 3516            } else {
 3517                servers_to_preserve.insert(state.id);
 3518            }
 3519        }
 3520        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3521        self.language_server_ids
 3522            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3523        for server_id_to_remove in &servers_to_remove {
 3524            self.language_server_watched_paths
 3525                .remove(server_id_to_remove);
 3526            self.language_server_paths_watched_for_rename
 3527                .remove(server_id_to_remove);
 3528            self.last_workspace_edits_by_language_server
 3529                .remove(server_id_to_remove);
 3530            self.language_servers.remove(server_id_to_remove);
 3531            self.buffer_pull_diagnostics_result_ids
 3532                .remove(server_id_to_remove);
 3533            self.workspace_pull_diagnostics_result_ids
 3534                .remove(server_id_to_remove);
 3535            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3536                buffer_servers.remove(server_id_to_remove);
 3537            }
 3538            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3539        }
 3540        servers_to_remove.into_iter().collect()
 3541    }
 3542
 3543    fn rebuild_watched_paths_inner<'a>(
 3544        &'a self,
 3545        language_server_id: LanguageServerId,
 3546        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3547        cx: &mut Context<LspStore>,
 3548    ) -> LanguageServerWatchedPathsBuilder {
 3549        let worktrees = self
 3550            .worktree_store
 3551            .read(cx)
 3552            .worktrees()
 3553            .filter_map(|worktree| {
 3554                self.language_servers_for_worktree(worktree.read(cx).id())
 3555                    .find(|server| server.server_id() == language_server_id)
 3556                    .map(|_| worktree)
 3557            })
 3558            .collect::<Vec<_>>();
 3559
 3560        let mut worktree_globs = HashMap::default();
 3561        let mut abs_globs = HashMap::default();
 3562        log::trace!(
 3563            "Processing new watcher paths for language server with id {}",
 3564            language_server_id
 3565        );
 3566
 3567        for watcher in watchers {
 3568            if let Some((worktree, literal_prefix, pattern)) =
 3569                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3570            {
 3571                worktree.update(cx, |worktree, _| {
 3572                    if let Some((tree, glob)) =
 3573                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3574                    {
 3575                        tree.add_path_prefix_to_scan(literal_prefix);
 3576                        worktree_globs
 3577                            .entry(tree.id())
 3578                            .or_insert_with(GlobSetBuilder::new)
 3579                            .add(glob);
 3580                    }
 3581                });
 3582            } else {
 3583                let (path, pattern) = match &watcher.glob_pattern {
 3584                    lsp::GlobPattern::String(s) => {
 3585                        let watcher_path = SanitizedPath::new(s);
 3586                        let path = glob_literal_prefix(watcher_path.as_path());
 3587                        let pattern = watcher_path
 3588                            .as_path()
 3589                            .strip_prefix(&path)
 3590                            .map(|p| p.to_string_lossy().into_owned())
 3591                            .unwrap_or_else(|e| {
 3592                                debug_panic!(
 3593                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3594                                    s,
 3595                                    path.display(),
 3596                                    e
 3597                                );
 3598                                watcher_path.as_path().to_string_lossy().into_owned()
 3599                            });
 3600                        (path, pattern)
 3601                    }
 3602                    lsp::GlobPattern::Relative(rp) => {
 3603                        let Ok(mut base_uri) = match &rp.base_uri {
 3604                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3605                            lsp::OneOf::Right(base_uri) => base_uri,
 3606                        }
 3607                        .to_file_path() else {
 3608                            continue;
 3609                        };
 3610
 3611                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3612                        let pattern = Path::new(&rp.pattern)
 3613                            .strip_prefix(&path)
 3614                            .map(|p| p.to_string_lossy().into_owned())
 3615                            .unwrap_or_else(|e| {
 3616                                debug_panic!(
 3617                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3618                                    rp.pattern,
 3619                                    path.display(),
 3620                                    e
 3621                                );
 3622                                rp.pattern.clone()
 3623                            });
 3624                        base_uri.push(path);
 3625                        (base_uri, pattern)
 3626                    }
 3627                };
 3628
 3629                if let Some(glob) = Glob::new(&pattern).log_err() {
 3630                    if !path
 3631                        .components()
 3632                        .any(|c| matches!(c, path::Component::Normal(_)))
 3633                    {
 3634                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3635                        // rather than adding a new watcher for `/`.
 3636                        for worktree in &worktrees {
 3637                            worktree_globs
 3638                                .entry(worktree.read(cx).id())
 3639                                .or_insert_with(GlobSetBuilder::new)
 3640                                .add(glob.clone());
 3641                        }
 3642                    } else {
 3643                        abs_globs
 3644                            .entry(path.into())
 3645                            .or_insert_with(GlobSetBuilder::new)
 3646                            .add(glob);
 3647                    }
 3648                }
 3649            }
 3650        }
 3651
 3652        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3653        for (worktree_id, builder) in worktree_globs {
 3654            if let Ok(globset) = builder.build() {
 3655                watch_builder.watch_worktree(worktree_id, globset);
 3656            }
 3657        }
 3658        for (abs_path, builder) in abs_globs {
 3659            if let Ok(globset) = builder.build() {
 3660                watch_builder.watch_abs_path(abs_path, globset);
 3661            }
 3662        }
 3663        watch_builder
 3664    }
 3665
 3666    fn worktree_and_path_for_file_watcher(
 3667        worktrees: &[Entity<Worktree>],
 3668        watcher: &FileSystemWatcher,
 3669        cx: &App,
 3670    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3671        worktrees.iter().find_map(|worktree| {
 3672            let tree = worktree.read(cx);
 3673            let worktree_root_path = tree.abs_path();
 3674            let path_style = tree.path_style();
 3675            match &watcher.glob_pattern {
 3676                lsp::GlobPattern::String(s) => {
 3677                    let watcher_path = SanitizedPath::new(s);
 3678                    let relative = watcher_path
 3679                        .as_path()
 3680                        .strip_prefix(&worktree_root_path)
 3681                        .ok()?;
 3682                    let literal_prefix = glob_literal_prefix(relative);
 3683                    Some((
 3684                        worktree.clone(),
 3685                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3686                        relative.to_string_lossy().into_owned(),
 3687                    ))
 3688                }
 3689                lsp::GlobPattern::Relative(rp) => {
 3690                    let base_uri = match &rp.base_uri {
 3691                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3692                        lsp::OneOf::Right(base_uri) => base_uri,
 3693                    }
 3694                    .to_file_path()
 3695                    .ok()?;
 3696                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3697                    let mut literal_prefix = relative.to_owned();
 3698                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3699                    Some((
 3700                        worktree.clone(),
 3701                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3702                        rp.pattern.clone(),
 3703                    ))
 3704                }
 3705            }
 3706        })
 3707    }
 3708
 3709    fn rebuild_watched_paths(
 3710        &mut self,
 3711        language_server_id: LanguageServerId,
 3712        cx: &mut Context<LspStore>,
 3713    ) {
 3714        let Some(registrations) = self
 3715            .language_server_dynamic_registrations
 3716            .get(&language_server_id)
 3717        else {
 3718            return;
 3719        };
 3720
 3721        let watch_builder = self.rebuild_watched_paths_inner(
 3722            language_server_id,
 3723            registrations.did_change_watched_files.values().flatten(),
 3724            cx,
 3725        );
 3726        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3727        self.language_server_watched_paths
 3728            .insert(language_server_id, watcher);
 3729
 3730        cx.notify();
 3731    }
 3732
 3733    fn on_lsp_did_change_watched_files(
 3734        &mut self,
 3735        language_server_id: LanguageServerId,
 3736        registration_id: &str,
 3737        params: DidChangeWatchedFilesRegistrationOptions,
 3738        cx: &mut Context<LspStore>,
 3739    ) {
 3740        let registrations = self
 3741            .language_server_dynamic_registrations
 3742            .entry(language_server_id)
 3743            .or_default();
 3744
 3745        registrations
 3746            .did_change_watched_files
 3747            .insert(registration_id.to_string(), params.watchers);
 3748
 3749        self.rebuild_watched_paths(language_server_id, cx);
 3750    }
 3751
 3752    fn on_lsp_unregister_did_change_watched_files(
 3753        &mut self,
 3754        language_server_id: LanguageServerId,
 3755        registration_id: &str,
 3756        cx: &mut Context<LspStore>,
 3757    ) {
 3758        let registrations = self
 3759            .language_server_dynamic_registrations
 3760            .entry(language_server_id)
 3761            .or_default();
 3762
 3763        if registrations
 3764            .did_change_watched_files
 3765            .remove(registration_id)
 3766            .is_some()
 3767        {
 3768            log::info!(
 3769                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3770                language_server_id,
 3771                registration_id
 3772            );
 3773        } else {
 3774            log::warn!(
 3775                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3776                language_server_id,
 3777                registration_id
 3778            );
 3779        }
 3780
 3781        self.rebuild_watched_paths(language_server_id, cx);
 3782    }
 3783
 3784    async fn initialization_options_for_adapter(
 3785        adapter: Arc<dyn LspAdapter>,
 3786        delegate: &Arc<dyn LspAdapterDelegate>,
 3787        cx: &mut AsyncApp,
 3788    ) -> Result<Option<serde_json::Value>> {
 3789        let Some(mut initialization_config) =
 3790            adapter.clone().initialization_options(delegate, cx).await?
 3791        else {
 3792            return Ok(None);
 3793        };
 3794
 3795        for other_adapter in delegate.registered_lsp_adapters() {
 3796            if other_adapter.name() == adapter.name() {
 3797                continue;
 3798            }
 3799            if let Ok(Some(target_config)) = other_adapter
 3800                .clone()
 3801                .additional_initialization_options(adapter.name(), delegate)
 3802                .await
 3803            {
 3804                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3805            }
 3806        }
 3807
 3808        Ok(Some(initialization_config))
 3809    }
 3810
 3811    async fn workspace_configuration_for_adapter(
 3812        adapter: Arc<dyn LspAdapter>,
 3813        delegate: &Arc<dyn LspAdapterDelegate>,
 3814        toolchain: Option<Toolchain>,
 3815        requested_uri: Option<Uri>,
 3816        cx: &mut AsyncApp,
 3817    ) -> Result<serde_json::Value> {
 3818        let mut workspace_config = adapter
 3819            .clone()
 3820            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3821            .await?;
 3822
 3823        for other_adapter in delegate.registered_lsp_adapters() {
 3824            if other_adapter.name() == adapter.name() {
 3825                continue;
 3826            }
 3827            if let Ok(Some(target_config)) = other_adapter
 3828                .clone()
 3829                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3830                .await
 3831            {
 3832                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3833            }
 3834        }
 3835
 3836        Ok(workspace_config)
 3837    }
 3838
 3839    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3840        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3841            Some(server.clone())
 3842        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3843            Some(Arc::clone(server))
 3844        } else {
 3845            None
 3846        }
 3847    }
 3848}
 3849
 3850fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3851    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3852        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3853            language_server_id: server.server_id(),
 3854            name: Some(server.name()),
 3855            message: proto::update_language_server::Variant::MetadataUpdated(
 3856                proto::ServerMetadataUpdated {
 3857                    capabilities: Some(capabilities),
 3858                    binary: Some(proto::LanguageServerBinaryInfo {
 3859                        path: server.binary().path.to_string_lossy().into_owned(),
 3860                        arguments: server
 3861                            .binary()
 3862                            .arguments
 3863                            .iter()
 3864                            .map(|arg| arg.to_string_lossy().into_owned())
 3865                            .collect(),
 3866                    }),
 3867                    configuration: serde_json::to_string(server.configuration()).ok(),
 3868                    workspace_folders: server
 3869                        .workspace_folders()
 3870                        .iter()
 3871                        .map(|uri| uri.to_string())
 3872                        .collect(),
 3873                },
 3874            ),
 3875        });
 3876    }
 3877}
 3878
 3879#[derive(Debug)]
 3880pub struct FormattableBuffer {
 3881    handle: Entity<Buffer>,
 3882    abs_path: Option<PathBuf>,
 3883    env: Option<HashMap<String, String>>,
 3884    ranges: Option<Vec<Range<Anchor>>>,
 3885}
 3886
 3887pub struct RemoteLspStore {
 3888    upstream_client: Option<AnyProtoClient>,
 3889    upstream_project_id: u64,
 3890}
 3891
 3892pub(crate) enum LspStoreMode {
 3893    Local(LocalLspStore),   // ssh host and collab host
 3894    Remote(RemoteLspStore), // collab guest
 3895}
 3896
 3897impl LspStoreMode {
 3898    fn is_local(&self) -> bool {
 3899        matches!(self, LspStoreMode::Local(_))
 3900    }
 3901}
 3902
 3903pub struct LspStore {
 3904    mode: LspStoreMode,
 3905    last_formatting_failure: Option<String>,
 3906    downstream_client: Option<(AnyProtoClient, u64)>,
 3907    nonce: u128,
 3908    buffer_store: Entity<BufferStore>,
 3909    worktree_store: Entity<WorktreeStore>,
 3910    pub languages: Arc<LanguageRegistry>,
 3911    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3912    active_entry: Option<ProjectEntryId>,
 3913    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3914    _maintain_buffer_languages: Task<()>,
 3915    diagnostic_summaries:
 3916        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3917    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3918    semantic_token_config: SemanticTokenConfig,
 3919    lsp_data: HashMap<BufferId, BufferLspData>,
 3920    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3921    next_hint_id: Arc<AtomicUsize>,
 3922}
 3923
 3924#[derive(Debug)]
 3925pub struct BufferLspData {
 3926    buffer_version: Global,
 3927    document_colors: Option<DocumentColorData>,
 3928    code_lens: Option<CodeLensData>,
 3929    semantic_tokens: Option<SemanticTokensData>,
 3930    folding_ranges: Option<FoldingRangeData>,
 3931    document_symbols: Option<DocumentSymbolsData>,
 3932    inlay_hints: BufferInlayHints,
 3933    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3934    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3935}
 3936
 3937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3938struct LspKey {
 3939    request_type: TypeId,
 3940    server_queried: Option<LanguageServerId>,
 3941}
 3942
 3943impl BufferLspData {
 3944    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3945        Self {
 3946            buffer_version: buffer.read(cx).version(),
 3947            document_colors: None,
 3948            code_lens: None,
 3949            semantic_tokens: None,
 3950            folding_ranges: None,
 3951            document_symbols: None,
 3952            inlay_hints: BufferInlayHints::new(buffer, cx),
 3953            lsp_requests: HashMap::default(),
 3954            chunk_lsp_requests: HashMap::default(),
 3955        }
 3956    }
 3957
 3958    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3959        if let Some(document_colors) = &mut self.document_colors {
 3960            document_colors.remove_server_data(for_server);
 3961        }
 3962
 3963        if let Some(code_lens) = &mut self.code_lens {
 3964            code_lens.remove_server_data(for_server);
 3965        }
 3966
 3967        self.inlay_hints.remove_server_data(for_server);
 3968
 3969        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3970            semantic_tokens.remove_server_data(for_server);
 3971        }
 3972
 3973        if let Some(folding_ranges) = &mut self.folding_ranges {
 3974            folding_ranges.ranges.remove(&for_server);
 3975        }
 3976
 3977        if let Some(document_symbols) = &mut self.document_symbols {
 3978            document_symbols.remove_server_data(for_server);
 3979        }
 3980    }
 3981
 3982    #[cfg(any(test, feature = "test-support"))]
 3983    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3984        &self.inlay_hints
 3985    }
 3986}
 3987
 3988#[derive(Debug)]
 3989pub enum LspStoreEvent {
 3990    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3991    LanguageServerRemoved(LanguageServerId),
 3992    LanguageServerUpdate {
 3993        language_server_id: LanguageServerId,
 3994        name: Option<LanguageServerName>,
 3995        message: proto::update_language_server::Variant,
 3996    },
 3997    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3998    LanguageServerPrompt(LanguageServerPromptRequest),
 3999    LanguageDetected {
 4000        buffer: Entity<Buffer>,
 4001        new_language: Option<Arc<Language>>,
 4002    },
 4003    Notification(String),
 4004    RefreshInlayHints {
 4005        server_id: LanguageServerId,
 4006        request_id: Option<usize>,
 4007    },
 4008    RefreshSemanticTokens {
 4009        server_id: LanguageServerId,
 4010        request_id: Option<usize>,
 4011    },
 4012    RefreshCodeLens,
 4013    DiagnosticsUpdated {
 4014        server_id: LanguageServerId,
 4015        paths: Vec<ProjectPath>,
 4016    },
 4017    DiskBasedDiagnosticsStarted {
 4018        language_server_id: LanguageServerId,
 4019    },
 4020    DiskBasedDiagnosticsFinished {
 4021        language_server_id: LanguageServerId,
 4022    },
 4023    SnippetEdit {
 4024        buffer_id: BufferId,
 4025        edits: Vec<(lsp::Range, Snippet)>,
 4026        most_recent_edit: clock::Lamport,
 4027    },
 4028    WorkspaceEditApplied(ProjectTransaction),
 4029}
 4030
 4031#[derive(Clone, Debug, Serialize)]
 4032pub struct LanguageServerStatus {
 4033    pub name: LanguageServerName,
 4034    pub server_version: Option<SharedString>,
 4035    pub server_readable_version: Option<SharedString>,
 4036    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4037    pub has_pending_diagnostic_updates: bool,
 4038    pub progress_tokens: HashSet<ProgressToken>,
 4039    pub worktree: Option<WorktreeId>,
 4040    pub binary: Option<LanguageServerBinary>,
 4041    pub configuration: Option<Value>,
 4042    pub workspace_folders: BTreeSet<Uri>,
 4043    pub process_id: Option<u32>,
 4044}
 4045
 4046#[derive(Clone, Debug)]
 4047struct CoreSymbol {
 4048    pub language_server_name: LanguageServerName,
 4049    pub source_worktree_id: WorktreeId,
 4050    pub source_language_server_id: LanguageServerId,
 4051    pub path: SymbolLocation,
 4052    pub name: String,
 4053    pub kind: lsp::SymbolKind,
 4054    pub range: Range<Unclipped<PointUtf16>>,
 4055    pub container_name: Option<String>,
 4056}
 4057
 4058#[derive(Clone, Debug, PartialEq, Eq)]
 4059pub enum SymbolLocation {
 4060    InProject(ProjectPath),
 4061    OutsideProject {
 4062        abs_path: Arc<Path>,
 4063        signature: [u8; 32],
 4064    },
 4065}
 4066
 4067impl SymbolLocation {
 4068    fn file_name(&self) -> Option<&str> {
 4069        match self {
 4070            Self::InProject(path) => path.path.file_name(),
 4071            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4072        }
 4073    }
 4074}
 4075
 4076impl LspStore {
 4077    pub fn init(client: &AnyProtoClient) {
 4078        client.add_entity_request_handler(Self::handle_lsp_query);
 4079        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4080        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4081        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4082        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4083        client.add_entity_message_handler(Self::handle_start_language_server);
 4084        client.add_entity_message_handler(Self::handle_update_language_server);
 4085        client.add_entity_message_handler(Self::handle_language_server_log);
 4086        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4087        client.add_entity_request_handler(Self::handle_format_buffers);
 4088        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4089        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4090        client.add_entity_request_handler(Self::handle_apply_code_action);
 4091        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4092        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4093        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4094        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4095        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4096        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4097        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4098        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4099        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4100        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4101        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4102        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4103        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4104        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4107        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4109
 4110        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4111        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4112        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4113        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4114        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4115        client.add_entity_request_handler(
 4116            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4117        );
 4118        client.add_entity_request_handler(
 4119            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4120        );
 4121        client.add_entity_request_handler(
 4122            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4123        );
 4124    }
 4125
 4126    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4127        match &self.mode {
 4128            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4129            _ => None,
 4130        }
 4131    }
 4132
 4133    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4134        match &self.mode {
 4135            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4136            _ => None,
 4137        }
 4138    }
 4139
 4140    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4141        match &mut self.mode {
 4142            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4143            _ => None,
 4144        }
 4145    }
 4146
 4147    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4148        match &self.mode {
 4149            LspStoreMode::Remote(RemoteLspStore {
 4150                upstream_client: Some(upstream_client),
 4151                upstream_project_id,
 4152                ..
 4153            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4154
 4155            LspStoreMode::Remote(RemoteLspStore {
 4156                upstream_client: None,
 4157                ..
 4158            }) => None,
 4159            LspStoreMode::Local(_) => None,
 4160        }
 4161    }
 4162
 4163    pub fn new_local(
 4164        buffer_store: Entity<BufferStore>,
 4165        worktree_store: Entity<WorktreeStore>,
 4166        prettier_store: Entity<PrettierStore>,
 4167        toolchain_store: Entity<LocalToolchainStore>,
 4168        environment: Entity<ProjectEnvironment>,
 4169        manifest_tree: Entity<ManifestTree>,
 4170        languages: Arc<LanguageRegistry>,
 4171        http_client: Arc<dyn HttpClient>,
 4172        fs: Arc<dyn Fs>,
 4173        cx: &mut Context<Self>,
 4174    ) -> Self {
 4175        let yarn = YarnPathStore::new(fs.clone(), cx);
 4176        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4177            .detach();
 4178        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4179            .detach();
 4180        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4181            .detach();
 4182        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4183            .detach();
 4184        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4185            .detach();
 4186        subscribe_to_binary_statuses(&languages, cx).detach();
 4187
 4188        let _maintain_workspace_config = {
 4189            let (sender, receiver) = watch::channel();
 4190            (Self::maintain_workspace_config(receiver, cx), sender)
 4191        };
 4192
 4193        Self {
 4194            mode: LspStoreMode::Local(LocalLspStore {
 4195                weak: cx.weak_entity(),
 4196                worktree_store: worktree_store.clone(),
 4197
 4198                supplementary_language_servers: Default::default(),
 4199                languages: languages.clone(),
 4200                language_server_ids: Default::default(),
 4201                language_servers: Default::default(),
 4202                last_workspace_edits_by_language_server: Default::default(),
 4203                language_server_watched_paths: Default::default(),
 4204                language_server_paths_watched_for_rename: Default::default(),
 4205                language_server_dynamic_registrations: Default::default(),
 4206                buffers_being_formatted: Default::default(),
 4207                buffers_to_refresh_hash_set: HashSet::default(),
 4208                buffers_to_refresh_queue: VecDeque::new(),
 4209                _background_diagnostics_worker: Task::ready(()).shared(),
 4210                buffer_snapshots: Default::default(),
 4211                prettier_store,
 4212                environment,
 4213                http_client,
 4214                fs,
 4215                yarn,
 4216                next_diagnostic_group_id: Default::default(),
 4217                diagnostics: Default::default(),
 4218                _subscription: cx.on_app_quit(|this, _| {
 4219                    this.as_local_mut()
 4220                        .unwrap()
 4221                        .shutdown_language_servers_on_quit()
 4222                }),
 4223                lsp_tree: LanguageServerTree::new(
 4224                    manifest_tree,
 4225                    languages.clone(),
 4226                    toolchain_store.clone(),
 4227                ),
 4228                toolchain_store,
 4229                registered_buffers: HashMap::default(),
 4230                buffers_opened_in_servers: HashMap::default(),
 4231                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4232                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4233                restricted_worktrees_tasks: HashMap::default(),
 4234                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4235                    .manifest_file_names(),
 4236            }),
 4237            last_formatting_failure: None,
 4238            downstream_client: None,
 4239            buffer_store,
 4240            worktree_store,
 4241            languages: languages.clone(),
 4242            language_server_statuses: Default::default(),
 4243            nonce: StdRng::from_os_rng().random(),
 4244            diagnostic_summaries: HashMap::default(),
 4245            lsp_server_capabilities: HashMap::default(),
 4246            semantic_token_config: SemanticTokenConfig::new(cx),
 4247            lsp_data: HashMap::default(),
 4248            buffer_reload_tasks: HashMap::default(),
 4249            next_hint_id: Arc::default(),
 4250            active_entry: None,
 4251            _maintain_workspace_config,
 4252            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4253        }
 4254    }
 4255
 4256    fn send_lsp_proto_request<R: LspCommand>(
 4257        &self,
 4258        buffer: Entity<Buffer>,
 4259        client: AnyProtoClient,
 4260        upstream_project_id: u64,
 4261        request: R,
 4262        cx: &mut Context<LspStore>,
 4263    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4264        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4265            return Task::ready(Ok(R::Response::default()));
 4266        }
 4267        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4268        cx.spawn(async move |this, cx| {
 4269            let response = client.request(message).await?;
 4270            let this = this.upgrade().context("project dropped")?;
 4271            request
 4272                .response_from_proto(response, this, buffer, cx.clone())
 4273                .await
 4274        })
 4275    }
 4276
 4277    pub(super) fn new_remote(
 4278        buffer_store: Entity<BufferStore>,
 4279        worktree_store: Entity<WorktreeStore>,
 4280        languages: Arc<LanguageRegistry>,
 4281        upstream_client: AnyProtoClient,
 4282        project_id: u64,
 4283        cx: &mut Context<Self>,
 4284    ) -> Self {
 4285        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4286            .detach();
 4287        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4288            .detach();
 4289        subscribe_to_binary_statuses(&languages, cx).detach();
 4290        let _maintain_workspace_config = {
 4291            let (sender, receiver) = watch::channel();
 4292            (Self::maintain_workspace_config(receiver, cx), sender)
 4293        };
 4294        Self {
 4295            mode: LspStoreMode::Remote(RemoteLspStore {
 4296                upstream_client: Some(upstream_client),
 4297                upstream_project_id: project_id,
 4298            }),
 4299            downstream_client: None,
 4300            last_formatting_failure: None,
 4301            buffer_store,
 4302            worktree_store,
 4303            languages: languages.clone(),
 4304            language_server_statuses: Default::default(),
 4305            nonce: StdRng::from_os_rng().random(),
 4306            diagnostic_summaries: HashMap::default(),
 4307            lsp_server_capabilities: HashMap::default(),
 4308            semantic_token_config: SemanticTokenConfig::new(cx),
 4309            next_hint_id: Arc::default(),
 4310            lsp_data: HashMap::default(),
 4311            buffer_reload_tasks: HashMap::default(),
 4312            active_entry: None,
 4313
 4314            _maintain_workspace_config,
 4315            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4316        }
 4317    }
 4318
 4319    fn on_buffer_store_event(
 4320        &mut self,
 4321        _: Entity<BufferStore>,
 4322        event: &BufferStoreEvent,
 4323        cx: &mut Context<Self>,
 4324    ) {
 4325        match event {
 4326            BufferStoreEvent::BufferAdded(buffer) => {
 4327                self.on_buffer_added(buffer, cx).log_err();
 4328            }
 4329            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4330                let buffer_id = buffer.read(cx).remote_id();
 4331                if let Some(local) = self.as_local_mut()
 4332                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4333                {
 4334                    local.reset_buffer(buffer, old_file, cx);
 4335
 4336                    if local.registered_buffers.contains_key(&buffer_id) {
 4337                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4338                    }
 4339                }
 4340
 4341                self.detect_language_for_buffer(buffer, cx);
 4342                if let Some(local) = self.as_local_mut() {
 4343                    local.initialize_buffer(buffer, cx);
 4344                    if local.registered_buffers.contains_key(&buffer_id) {
 4345                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4346                    }
 4347                }
 4348            }
 4349            _ => {}
 4350        }
 4351    }
 4352
 4353    fn on_worktree_store_event(
 4354        &mut self,
 4355        _: Entity<WorktreeStore>,
 4356        event: &WorktreeStoreEvent,
 4357        cx: &mut Context<Self>,
 4358    ) {
 4359        match event {
 4360            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4361                if !worktree.read(cx).is_local() {
 4362                    return;
 4363                }
 4364                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4365                    worktree::Event::UpdatedEntries(changes) => {
 4366                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4367                    }
 4368                    worktree::Event::UpdatedGitRepositories(_)
 4369                    | worktree::Event::DeletedEntry(_) => {}
 4370                })
 4371                .detach()
 4372            }
 4373            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4374            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4375                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4376            }
 4377            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4378                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4379            }
 4380            WorktreeStoreEvent::WorktreeReleased(..)
 4381            | WorktreeStoreEvent::WorktreeOrderChanged
 4382            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4383            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4384        }
 4385    }
 4386
 4387    fn on_prettier_store_event(
 4388        &mut self,
 4389        _: Entity<PrettierStore>,
 4390        event: &PrettierStoreEvent,
 4391        cx: &mut Context<Self>,
 4392    ) {
 4393        match event {
 4394            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4395                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4396            }
 4397            PrettierStoreEvent::LanguageServerAdded {
 4398                new_server_id,
 4399                name,
 4400                prettier_server,
 4401            } => {
 4402                self.register_supplementary_language_server(
 4403                    *new_server_id,
 4404                    name.clone(),
 4405                    prettier_server.clone(),
 4406                    cx,
 4407                );
 4408            }
 4409        }
 4410    }
 4411
 4412    fn on_toolchain_store_event(
 4413        &mut self,
 4414        _: Entity<LocalToolchainStore>,
 4415        event: &ToolchainStoreEvent,
 4416        _: &mut Context<Self>,
 4417    ) {
 4418        if let ToolchainStoreEvent::ToolchainActivated = event {
 4419            self.request_workspace_config_refresh()
 4420        }
 4421    }
 4422
 4423    fn request_workspace_config_refresh(&mut self) {
 4424        *self._maintain_workspace_config.1.borrow_mut() = ();
 4425    }
 4426
 4427    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4428        self.as_local().map(|local| local.prettier_store.clone())
 4429    }
 4430
 4431    fn on_buffer_event(
 4432        &mut self,
 4433        buffer: Entity<Buffer>,
 4434        event: &language::BufferEvent,
 4435        cx: &mut Context<Self>,
 4436    ) {
 4437        match event {
 4438            language::BufferEvent::Edited { .. } => {
 4439                self.on_buffer_edited(buffer, cx);
 4440            }
 4441
 4442            language::BufferEvent::Saved => {
 4443                self.on_buffer_saved(buffer, cx);
 4444            }
 4445
 4446            language::BufferEvent::Reloaded => {
 4447                self.on_buffer_reloaded(buffer, cx);
 4448            }
 4449
 4450            _ => {}
 4451        }
 4452    }
 4453
 4454    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4455        buffer
 4456            .read(cx)
 4457            .set_language_registry(self.languages.clone());
 4458
 4459        cx.subscribe(buffer, |this, buffer, event, cx| {
 4460            this.on_buffer_event(buffer, event, cx);
 4461        })
 4462        .detach();
 4463
 4464        self.parse_modeline(buffer, cx);
 4465        self.detect_language_for_buffer(buffer, cx);
 4466        if let Some(local) = self.as_local_mut() {
 4467            local.initialize_buffer(buffer, cx);
 4468        }
 4469
 4470        Ok(())
 4471    }
 4472
 4473    pub fn refresh_background_diagnostics_for_buffers(
 4474        &mut self,
 4475        buffers: HashSet<BufferId>,
 4476        cx: &mut Context<Self>,
 4477    ) -> Shared<Task<()>> {
 4478        let Some(local) = self.as_local_mut() else {
 4479            return Task::ready(()).shared();
 4480        };
 4481        for buffer in buffers {
 4482            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4483                local.buffers_to_refresh_queue.push_back(buffer);
 4484                if local.buffers_to_refresh_queue.len() == 1 {
 4485                    local._background_diagnostics_worker =
 4486                        Self::background_diagnostics_worker(cx).shared();
 4487                }
 4488            }
 4489        }
 4490
 4491        local._background_diagnostics_worker.clone()
 4492    }
 4493
 4494    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4495        let buffer_store = self.buffer_store.clone();
 4496        let local = self.as_local_mut()?;
 4497        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4498            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4499            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4500                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4501            }
 4502        }
 4503        None
 4504    }
 4505
 4506    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4507        cx.spawn(async move |this, cx| {
 4508            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4509                task.await.log_err();
 4510            }
 4511        })
 4512    }
 4513
 4514    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4515        if self.parse_modeline(&buffer, cx) {
 4516            self.detect_language_for_buffer(&buffer, cx);
 4517        }
 4518
 4519        let buffer_id = buffer.read(cx).remote_id();
 4520        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4521        self.buffer_reload_tasks.insert(buffer_id, task);
 4522    }
 4523
 4524    pub(crate) fn register_buffer_with_language_servers(
 4525        &mut self,
 4526        buffer: &Entity<Buffer>,
 4527        only_register_servers: HashSet<LanguageServerSelector>,
 4528        ignore_refcounts: bool,
 4529        cx: &mut Context<Self>,
 4530    ) -> OpenLspBufferHandle {
 4531        let buffer_id = buffer.read(cx).remote_id();
 4532        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4533        if let Some(local) = self.as_local_mut() {
 4534            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4535            if !ignore_refcounts {
 4536                *refcount += 1;
 4537            }
 4538
 4539            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4540            // 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
 4541            // 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
 4542            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4543            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4544                return handle;
 4545            };
 4546            if !file.is_local() {
 4547                return handle;
 4548            }
 4549
 4550            if ignore_refcounts || *refcount == 1 {
 4551                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4552            }
 4553            if !ignore_refcounts {
 4554                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4555                    let refcount = {
 4556                        let local = lsp_store.as_local_mut().unwrap();
 4557                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4558                            debug_panic!("bad refcounting");
 4559                            return;
 4560                        };
 4561
 4562                        *refcount -= 1;
 4563                        *refcount
 4564                    };
 4565                    if refcount == 0 {
 4566                        lsp_store.lsp_data.remove(&buffer_id);
 4567                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4568                        let local = lsp_store.as_local_mut().unwrap();
 4569                        local.registered_buffers.remove(&buffer_id);
 4570
 4571                        local.buffers_opened_in_servers.remove(&buffer_id);
 4572                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4573                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4574
 4575                            let buffer_abs_path = file.abs_path(cx);
 4576                            for (_, buffer_pull_diagnostics_result_ids) in
 4577                                &mut local.buffer_pull_diagnostics_result_ids
 4578                            {
 4579                                buffer_pull_diagnostics_result_ids.retain(
 4580                                    |_, buffer_result_ids| {
 4581                                        buffer_result_ids.remove(&buffer_abs_path);
 4582                                        !buffer_result_ids.is_empty()
 4583                                    },
 4584                                );
 4585                            }
 4586
 4587                            let diagnostic_updates = local
 4588                                .language_servers
 4589                                .keys()
 4590                                .cloned()
 4591                                .map(|server_id| DocumentDiagnosticsUpdate {
 4592                                    diagnostics: DocumentDiagnostics {
 4593                                        document_abs_path: buffer_abs_path.clone(),
 4594                                        version: None,
 4595                                        diagnostics: Vec::new(),
 4596                                    },
 4597                                    result_id: None,
 4598                                    registration_id: None,
 4599                                    server_id,
 4600                                    disk_based_sources: Cow::Borrowed(&[]),
 4601                                })
 4602                                .collect::<Vec<_>>();
 4603
 4604                            lsp_store
 4605                                .merge_diagnostic_entries(
 4606                                    diagnostic_updates,
 4607                                    |_, diagnostic, _| {
 4608                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4609                                    },
 4610                                    cx,
 4611                                )
 4612                                .context("Clearing diagnostics for the closed buffer")
 4613                                .log_err();
 4614                        }
 4615                    }
 4616                })
 4617                .detach();
 4618            }
 4619        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4620            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4621            cx.background_spawn(async move {
 4622                upstream_client
 4623                    .request(proto::RegisterBufferWithLanguageServers {
 4624                        project_id: upstream_project_id,
 4625                        buffer_id,
 4626                        only_servers: only_register_servers
 4627                            .into_iter()
 4628                            .map(|selector| {
 4629                                let selector = match selector {
 4630                                    LanguageServerSelector::Id(language_server_id) => {
 4631                                        proto::language_server_selector::Selector::ServerId(
 4632                                            language_server_id.to_proto(),
 4633                                        )
 4634                                    }
 4635                                    LanguageServerSelector::Name(language_server_name) => {
 4636                                        proto::language_server_selector::Selector::Name(
 4637                                            language_server_name.to_string(),
 4638                                        )
 4639                                    }
 4640                                };
 4641                                proto::LanguageServerSelector {
 4642                                    selector: Some(selector),
 4643                                }
 4644                            })
 4645                            .collect(),
 4646                    })
 4647                    .await
 4648            })
 4649            .detach();
 4650        } else {
 4651            // Our remote connection got closed
 4652        }
 4653        handle
 4654    }
 4655
 4656    fn maintain_buffer_languages(
 4657        languages: Arc<LanguageRegistry>,
 4658        cx: &mut Context<Self>,
 4659    ) -> Task<()> {
 4660        let mut subscription = languages.subscribe();
 4661        let mut prev_reload_count = languages.reload_count();
 4662        cx.spawn(async move |this, cx| {
 4663            while let Some(()) = subscription.next().await {
 4664                if let Some(this) = this.upgrade() {
 4665                    // If the language registry has been reloaded, then remove and
 4666                    // re-assign the languages on all open buffers.
 4667                    let reload_count = languages.reload_count();
 4668                    if reload_count > prev_reload_count {
 4669                        prev_reload_count = reload_count;
 4670                        this.update(cx, |this, cx| {
 4671                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4672                                for buffer in buffer_store.buffers() {
 4673                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4674                                    {
 4675                                        buffer.update(cx, |buffer, cx| {
 4676                                            buffer.set_language_async(None, cx)
 4677                                        });
 4678                                        if let Some(local) = this.as_local_mut() {
 4679                                            local.reset_buffer(&buffer, &f, cx);
 4680
 4681                                            if local
 4682                                                .registered_buffers
 4683                                                .contains_key(&buffer.read(cx).remote_id())
 4684                                                && let Some(file_url) =
 4685                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4686                                            {
 4687                                                local.unregister_buffer_from_language_servers(
 4688                                                    &buffer, &file_url, cx,
 4689                                                );
 4690                                            }
 4691                                        }
 4692                                    }
 4693                                }
 4694                            });
 4695                        });
 4696                    }
 4697
 4698                    this.update(cx, |this, cx| {
 4699                        let mut plain_text_buffers = Vec::new();
 4700                        let mut buffers_with_unknown_injections = Vec::new();
 4701                        for handle in this.buffer_store.read(cx).buffers() {
 4702                            let buffer = handle.read(cx);
 4703                            if buffer.language().is_none()
 4704                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4705                            {
 4706                                plain_text_buffers.push(handle);
 4707                            } else if buffer.contains_unknown_injections() {
 4708                                buffers_with_unknown_injections.push(handle);
 4709                            }
 4710                        }
 4711
 4712                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4713                        // and reused later in the invisible worktrees.
 4714                        plain_text_buffers.sort_by_key(|buffer| {
 4715                            Reverse(
 4716                                File::from_dyn(buffer.read(cx).file())
 4717                                    .map(|file| file.worktree.read(cx).is_visible()),
 4718                            )
 4719                        });
 4720
 4721                        for buffer in plain_text_buffers {
 4722                            this.detect_language_for_buffer(&buffer, cx);
 4723                            if let Some(local) = this.as_local_mut() {
 4724                                local.initialize_buffer(&buffer, cx);
 4725                                if local
 4726                                    .registered_buffers
 4727                                    .contains_key(&buffer.read(cx).remote_id())
 4728                                {
 4729                                    local.register_buffer_with_language_servers(
 4730                                        &buffer,
 4731                                        HashSet::default(),
 4732                                        cx,
 4733                                    );
 4734                                }
 4735                            }
 4736                        }
 4737
 4738                        for buffer in buffers_with_unknown_injections {
 4739                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4740                        }
 4741                    });
 4742                }
 4743            }
 4744        })
 4745    }
 4746
 4747    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4748        let buffer = buffer_handle.read(cx);
 4749        let content = buffer.as_rope();
 4750
 4751        let modeline_settings = {
 4752            let settings_store = cx.global::<SettingsStore>();
 4753            let modeline_lines = settings_store
 4754                .raw_user_settings()
 4755                .and_then(|s| s.content.modeline_lines)
 4756                .or(settings_store.raw_default_settings().modeline_lines)
 4757                .unwrap_or(5);
 4758
 4759            const MAX_MODELINE_BYTES: usize = 1024;
 4760
 4761            let first_bytes =
 4762                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4763            let mut first_lines = Vec::new();
 4764            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4765            for _ in 0..modeline_lines {
 4766                if let Some(line) = lines.next() {
 4767                    first_lines.push(line.to_string());
 4768                } else {
 4769                    break;
 4770                }
 4771            }
 4772            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4773
 4774            let last_start =
 4775                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4776            let mut last_lines = Vec::new();
 4777            let mut lines = content
 4778                .reversed_chunks_in_range(last_start..content.len())
 4779                .lines();
 4780            for _ in 0..modeline_lines {
 4781                if let Some(line) = lines.next() {
 4782                    last_lines.push(line.to_string());
 4783                } else {
 4784                    break;
 4785                }
 4786            }
 4787            let last_lines_ref: Vec<_> =
 4788                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4789            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4790        };
 4791
 4792        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4793
 4794        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4795    }
 4796
 4797    fn detect_language_for_buffer(
 4798        &mut self,
 4799        buffer_handle: &Entity<Buffer>,
 4800        cx: &mut Context<Self>,
 4801    ) -> Option<language::AvailableLanguage> {
 4802        // If the buffer has a language, set it and start the language server if we haven't already.
 4803        let buffer = buffer_handle.read(cx);
 4804        let file = buffer.file()?;
 4805        let content = buffer.as_rope();
 4806        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4807
 4808        let available_language = if let Some(ModelineSettings {
 4809            mode: Some(mode_name),
 4810            ..
 4811        }) = modeline_settings
 4812        {
 4813            self.languages
 4814                .available_language_for_modeline_name(mode_name)
 4815        } else {
 4816            self.languages.language_for_file(file, Some(content), cx)
 4817        };
 4818        if let Some(available_language) = &available_language {
 4819            if let Some(Ok(Ok(new_language))) = self
 4820                .languages
 4821                .load_language(available_language)
 4822                .now_or_never()
 4823            {
 4824                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4825            }
 4826        } else {
 4827            cx.emit(LspStoreEvent::LanguageDetected {
 4828                buffer: buffer_handle.clone(),
 4829                new_language: None,
 4830            });
 4831        }
 4832
 4833        available_language
 4834    }
 4835
 4836    pub(crate) fn set_language_for_buffer(
 4837        &mut self,
 4838        buffer_entity: &Entity<Buffer>,
 4839        new_language: Arc<Language>,
 4840        cx: &mut Context<Self>,
 4841    ) {
 4842        let buffer = buffer_entity.read(cx);
 4843        let buffer_file = buffer.file().cloned();
 4844        let buffer_id = buffer.remote_id();
 4845        if let Some(local_store) = self.as_local_mut()
 4846            && local_store.registered_buffers.contains_key(&buffer_id)
 4847            && let Some(abs_path) =
 4848                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4849            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4850        {
 4851            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4852        }
 4853        buffer_entity.update(cx, |buffer, cx| {
 4854            if buffer
 4855                .language()
 4856                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4857            {
 4858                buffer.set_language_async(Some(new_language.clone()), cx);
 4859            }
 4860        });
 4861
 4862        let settings = LanguageSettings::resolve(
 4863            Some(&buffer_entity.read(cx)),
 4864            Some(&new_language.name()),
 4865            cx,
 4866        )
 4867        .into_owned();
 4868        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4869
 4870        let worktree_id = if let Some(file) = buffer_file {
 4871            let worktree = file.worktree.clone();
 4872
 4873            if let Some(local) = self.as_local_mut()
 4874                && local.registered_buffers.contains_key(&buffer_id)
 4875            {
 4876                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4877            }
 4878            Some(worktree.read(cx).id())
 4879        } else {
 4880            None
 4881        };
 4882
 4883        if settings.prettier.allowed
 4884            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4885        {
 4886            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4887            if let Some(prettier_store) = prettier_store {
 4888                prettier_store.update(cx, |prettier_store, cx| {
 4889                    prettier_store.install_default_prettier(
 4890                        worktree_id,
 4891                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4892                        cx,
 4893                    )
 4894                })
 4895            }
 4896        }
 4897
 4898        cx.emit(LspStoreEvent::LanguageDetected {
 4899            buffer: buffer_entity.clone(),
 4900            new_language: Some(new_language),
 4901        })
 4902    }
 4903
 4904    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4905        self.buffer_store.clone()
 4906    }
 4907
 4908    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4909        self.active_entry = active_entry;
 4910    }
 4911
 4912    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4913        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4914            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4915        {
 4916            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4917                summaries
 4918                    .iter()
 4919                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4920            });
 4921            if let Some(summary) = summaries.next() {
 4922                client
 4923                    .send(proto::UpdateDiagnosticSummary {
 4924                        project_id: downstream_project_id,
 4925                        worktree_id: worktree.id().to_proto(),
 4926                        summary: Some(summary),
 4927                        more_summaries: summaries.collect(),
 4928                    })
 4929                    .log_err();
 4930            }
 4931        }
 4932    }
 4933
 4934    fn is_capable_for_proto_request<R>(
 4935        &self,
 4936        buffer: &Entity<Buffer>,
 4937        request: &R,
 4938        cx: &App,
 4939    ) -> bool
 4940    where
 4941        R: LspCommand,
 4942    {
 4943        self.check_if_capable_for_proto_request(
 4944            buffer,
 4945            |capabilities| {
 4946                request.check_capabilities(AdapterServerCapabilities {
 4947                    server_capabilities: capabilities.clone(),
 4948                    code_action_kinds: None,
 4949                })
 4950            },
 4951            cx,
 4952        )
 4953    }
 4954
 4955    fn check_if_capable_for_proto_request<F>(
 4956        &self,
 4957        buffer: &Entity<Buffer>,
 4958        check: F,
 4959        cx: &App,
 4960    ) -> bool
 4961    where
 4962        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4963    {
 4964        let Some(language) = buffer.read(cx).language().cloned() else {
 4965            return false;
 4966        };
 4967        let registered_language_servers = self
 4968            .languages
 4969            .lsp_adapters(&language.name())
 4970            .into_iter()
 4971            .map(|lsp_adapter| lsp_adapter.name())
 4972            .collect::<HashSet<_>>();
 4973        self.language_server_statuses
 4974            .iter()
 4975            .filter_map(|(server_id, server_status)| {
 4976                // Include servers that are either registered for this language OR
 4977                // available to be loaded (for SSH remote mode where adapters like
 4978                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4979                // but only loaded on the server side)
 4980                let is_relevant = registered_language_servers.contains(&server_status.name)
 4981                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4982                is_relevant.then_some(server_id)
 4983            })
 4984            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4985            .any(check)
 4986    }
 4987
 4988    fn all_capable_for_proto_request<F>(
 4989        &self,
 4990        buffer: &Entity<Buffer>,
 4991        mut check: F,
 4992        cx: &App,
 4993    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4994    where
 4995        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4996    {
 4997        let Some(language) = buffer.read(cx).language().cloned() else {
 4998            return Vec::default();
 4999        };
 5000        let registered_language_servers = self
 5001            .languages
 5002            .lsp_adapters(&language.name())
 5003            .into_iter()
 5004            .map(|lsp_adapter| lsp_adapter.name())
 5005            .collect::<HashSet<_>>();
 5006        self.language_server_statuses
 5007            .iter()
 5008            .filter_map(|(server_id, server_status)| {
 5009                // Include servers that are either registered for this language OR
 5010                // available to be loaded (for SSH remote mode where adapters like
 5011                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5012                // but only loaded on the server side)
 5013                let is_relevant = registered_language_servers.contains(&server_status.name)
 5014                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5015                is_relevant.then_some((server_id, &server_status.name))
 5016            })
 5017            .filter_map(|(server_id, server_name)| {
 5018                self.lsp_server_capabilities
 5019                    .get(server_id)
 5020                    .map(|c| (server_id, server_name, c))
 5021            })
 5022            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5023            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5024            .collect()
 5025    }
 5026
 5027    pub fn request_lsp<R>(
 5028        &mut self,
 5029        buffer: Entity<Buffer>,
 5030        server: LanguageServerToQuery,
 5031        request: R,
 5032        cx: &mut Context<Self>,
 5033    ) -> Task<Result<R::Response>>
 5034    where
 5035        R: LspCommand,
 5036        <R::LspRequest as lsp::request::Request>::Result: Send,
 5037        <R::LspRequest as lsp::request::Request>::Params: Send,
 5038    {
 5039        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5040            return self.send_lsp_proto_request(
 5041                buffer,
 5042                upstream_client,
 5043                upstream_project_id,
 5044                request,
 5045                cx,
 5046            );
 5047        }
 5048
 5049        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5050            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5051                local
 5052                    .language_servers_for_buffer(buffer, cx)
 5053                    .find(|(_, server)| {
 5054                        request.check_capabilities(server.adapter_server_capabilities())
 5055                    })
 5056                    .map(|(_, server)| server.clone())
 5057            }),
 5058            LanguageServerToQuery::Other(id) => self
 5059                .language_server_for_local_buffer(buffer, id, cx)
 5060                .and_then(|(_, server)| {
 5061                    request
 5062                        .check_capabilities(server.adapter_server_capabilities())
 5063                        .then(|| Arc::clone(server))
 5064                }),
 5065        }) else {
 5066            return Task::ready(Ok(Default::default()));
 5067        };
 5068
 5069        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5070
 5071        let Some(file) = file else {
 5072            return Task::ready(Ok(Default::default()));
 5073        };
 5074
 5075        let lsp_params = match request.to_lsp_params_or_response(
 5076            &file.abs_path(cx),
 5077            buffer.read(cx),
 5078            &language_server,
 5079            cx,
 5080        ) {
 5081            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5082            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5083            Err(err) => {
 5084                let message = format!(
 5085                    "{} via {} failed: {}",
 5086                    request.display_name(),
 5087                    language_server.name(),
 5088                    err
 5089                );
 5090                // rust-analyzer likes to error with this when its still loading up
 5091                if !message.ends_with("content modified") {
 5092                    log::warn!("{message}");
 5093                }
 5094                return Task::ready(Err(anyhow!(message)));
 5095            }
 5096        };
 5097
 5098        let status = request.status();
 5099        let request_timeout = ProjectSettings::get_global(cx)
 5100            .global_lsp_settings
 5101            .get_request_timeout();
 5102
 5103        cx.spawn(async move |this, cx| {
 5104            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5105
 5106            let id = lsp_request.id();
 5107            let _cleanup = if status.is_some() {
 5108                cx.update(|cx| {
 5109                    this.update(cx, |this, cx| {
 5110                        this.on_lsp_work_start(
 5111                            language_server.server_id(),
 5112                            ProgressToken::Number(id),
 5113                            LanguageServerProgress {
 5114                                is_disk_based_diagnostics_progress: false,
 5115                                is_cancellable: false,
 5116                                title: None,
 5117                                message: status.clone(),
 5118                                percentage: None,
 5119                                last_update_at: cx.background_executor().now(),
 5120                            },
 5121                            cx,
 5122                        );
 5123                    })
 5124                })
 5125                .log_err();
 5126
 5127                Some(defer(|| {
 5128                    cx.update(|cx| {
 5129                        this.update(cx, |this, cx| {
 5130                            this.on_lsp_work_end(
 5131                                language_server.server_id(),
 5132                                ProgressToken::Number(id),
 5133                                cx,
 5134                            );
 5135                        })
 5136                    })
 5137                    .log_err();
 5138                }))
 5139            } else {
 5140                None
 5141            };
 5142
 5143            let result = lsp_request.await.into_response();
 5144
 5145            let response = result.map_err(|err| {
 5146                let message = format!(
 5147                    "{} via {} failed: {}",
 5148                    request.display_name(),
 5149                    language_server.name(),
 5150                    err
 5151                );
 5152                // rust-analyzer likes to error with this when its still loading up
 5153                if !message.ends_with("content modified") {
 5154                    log::warn!("{message}");
 5155                }
 5156                anyhow::anyhow!(message)
 5157            })?;
 5158
 5159            request
 5160                .response_from_lsp(
 5161                    response,
 5162                    this.upgrade().context("no app context")?,
 5163                    buffer,
 5164                    language_server.server_id(),
 5165                    cx.clone(),
 5166                )
 5167                .await
 5168        })
 5169    }
 5170
 5171    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5172        let mut language_formatters_to_check = Vec::new();
 5173        for buffer in self.buffer_store.read(cx).buffers() {
 5174            let buffer = buffer.read(cx);
 5175            let settings = LanguageSettings::for_buffer(buffer, cx);
 5176            if buffer.language().is_some() {
 5177                let buffer_file = File::from_dyn(buffer.file());
 5178                language_formatters_to_check.push((
 5179                    buffer_file.map(|f| f.worktree_id(cx)),
 5180                    settings.into_owned(),
 5181                ));
 5182            }
 5183        }
 5184
 5185        self.request_workspace_config_refresh();
 5186
 5187        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5188            prettier_store.update(cx, |prettier_store, cx| {
 5189                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5190            })
 5191        }
 5192
 5193        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5194            .global_lsp_settings
 5195            .semantic_token_rules
 5196            .clone();
 5197        self.semantic_token_config
 5198            .update_rules(new_semantic_token_rules);
 5199        // Always clear cached stylizers so that changes to language-specific
 5200        // semantic token rules (e.g. from extension install/uninstall) are
 5201        // picked up. Stylizers are recreated lazily, so this is cheap.
 5202        self.semantic_token_config.clear_stylizers();
 5203
 5204        let new_global_semantic_tokens_mode =
 5205            all_language_settings(None, cx).defaults.semantic_tokens;
 5206        if self
 5207            .semantic_token_config
 5208            .update_global_mode(new_global_semantic_tokens_mode)
 5209        {
 5210            self.restart_all_language_servers(cx);
 5211        }
 5212
 5213        cx.notify();
 5214    }
 5215
 5216    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5217        let buffer_store = self.buffer_store.clone();
 5218        let Some(local) = self.as_local_mut() else {
 5219            return;
 5220        };
 5221        let mut adapters = BTreeMap::default();
 5222        let get_adapter = {
 5223            let languages = local.languages.clone();
 5224            let environment = local.environment.clone();
 5225            let weak = local.weak.clone();
 5226            let worktree_store = local.worktree_store.clone();
 5227            let http_client = local.http_client.clone();
 5228            let fs = local.fs.clone();
 5229            move |worktree_id, cx: &mut App| {
 5230                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5231                Some(LocalLspAdapterDelegate::new(
 5232                    languages.clone(),
 5233                    &environment,
 5234                    weak.clone(),
 5235                    &worktree,
 5236                    http_client.clone(),
 5237                    fs.clone(),
 5238                    cx,
 5239                ))
 5240            }
 5241        };
 5242
 5243        let mut messages_to_report = Vec::new();
 5244        let (new_tree, to_stop) = {
 5245            let mut rebase = local.lsp_tree.rebase();
 5246            let buffers = buffer_store
 5247                .read(cx)
 5248                .buffers()
 5249                .filter_map(|buffer| {
 5250                    let raw_buffer = buffer.read(cx);
 5251                    if !local
 5252                        .registered_buffers
 5253                        .contains_key(&raw_buffer.remote_id())
 5254                    {
 5255                        return None;
 5256                    }
 5257                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5258                    let language = raw_buffer.language().cloned()?;
 5259                    Some((file, language, raw_buffer.remote_id()))
 5260                })
 5261                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5262            for (file, language, buffer_id) in buffers {
 5263                let worktree_id = file.worktree_id(cx);
 5264                let Some(worktree) = local
 5265                    .worktree_store
 5266                    .read(cx)
 5267                    .worktree_for_id(worktree_id, cx)
 5268                else {
 5269                    continue;
 5270                };
 5271
 5272                if let Some((_, apply)) = local.reuse_existing_language_server(
 5273                    rebase.server_tree(),
 5274                    &worktree,
 5275                    &language.name(),
 5276                    cx,
 5277                ) {
 5278                    (apply)(rebase.server_tree());
 5279                } else if let Some(lsp_delegate) = adapters
 5280                    .entry(worktree_id)
 5281                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5282                    .clone()
 5283                {
 5284                    let delegate =
 5285                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5286                    let path = file
 5287                        .path()
 5288                        .parent()
 5289                        .map(Arc::from)
 5290                        .unwrap_or_else(|| file.path().clone());
 5291                    let worktree_path = ProjectPath { worktree_id, path };
 5292                    let abs_path = file.abs_path(cx);
 5293                    let nodes = rebase
 5294                        .walk(
 5295                            worktree_path,
 5296                            language.name(),
 5297                            language.manifest(),
 5298                            delegate.clone(),
 5299                            cx,
 5300                        )
 5301                        .collect::<Vec<_>>();
 5302                    for node in nodes {
 5303                        let server_id = node.server_id_or_init(|disposition| {
 5304                            let path = &disposition.path;
 5305                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5306                            let key = LanguageServerSeed {
 5307                                worktree_id,
 5308                                name: disposition.server_name.clone(),
 5309                                settings: LanguageServerSeedSettings {
 5310                                    binary: disposition.settings.binary.clone(),
 5311                                    initialization_options: disposition
 5312                                        .settings
 5313                                        .initialization_options
 5314                                        .clone(),
 5315                                },
 5316                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5317                                    path.worktree_id,
 5318                                    &path.path,
 5319                                    language.name(),
 5320                                ),
 5321                            };
 5322                            local.language_server_ids.remove(&key);
 5323
 5324                            let server_id = local.get_or_insert_language_server(
 5325                                &worktree,
 5326                                lsp_delegate.clone(),
 5327                                disposition,
 5328                                &language.name(),
 5329                                cx,
 5330                            );
 5331                            if let Some(state) = local.language_servers.get(&server_id)
 5332                                && let Ok(uri) = uri
 5333                            {
 5334                                state.add_workspace_folder(uri);
 5335                            };
 5336                            server_id
 5337                        });
 5338
 5339                        if let Some(language_server_id) = server_id {
 5340                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5341                                language_server_id,
 5342                                name: node.name(),
 5343                                message:
 5344                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5345                                        proto::RegisteredForBuffer {
 5346                                            buffer_abs_path: abs_path
 5347                                                .to_string_lossy()
 5348                                                .into_owned(),
 5349                                            buffer_id: buffer_id.to_proto(),
 5350                                        },
 5351                                    ),
 5352                            });
 5353                        }
 5354                    }
 5355                } else {
 5356                    continue;
 5357                }
 5358            }
 5359            rebase.finish()
 5360        };
 5361        for message in messages_to_report {
 5362            cx.emit(message);
 5363        }
 5364        local.lsp_tree = new_tree;
 5365        for (id, _) in to_stop {
 5366            self.stop_local_language_server(id, cx).detach();
 5367        }
 5368    }
 5369
 5370    pub fn apply_code_action(
 5371        &self,
 5372        buffer_handle: Entity<Buffer>,
 5373        mut action: CodeAction,
 5374        push_to_history: bool,
 5375        cx: &mut Context<Self>,
 5376    ) -> Task<Result<ProjectTransaction>> {
 5377        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5378            let request = proto::ApplyCodeAction {
 5379                project_id,
 5380                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5381                action: Some(Self::serialize_code_action(&action)),
 5382            };
 5383            let buffer_store = self.buffer_store();
 5384            cx.spawn(async move |_, cx| {
 5385                let response = upstream_client
 5386                    .request(request)
 5387                    .await?
 5388                    .transaction
 5389                    .context("missing transaction")?;
 5390
 5391                buffer_store
 5392                    .update(cx, |buffer_store, cx| {
 5393                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5394                    })
 5395                    .await
 5396            })
 5397        } else if self.mode.is_local() {
 5398            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5399                let request_timeout = ProjectSettings::get_global(cx)
 5400                    .global_lsp_settings
 5401                    .get_request_timeout();
 5402                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5403                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5404            }) else {
 5405                return Task::ready(Ok(ProjectTransaction::default()));
 5406            };
 5407
 5408            cx.spawn(async move |this, cx| {
 5409                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5410                    .await
 5411                    .context("resolving a code action")?;
 5412                if let Some(edit) = action.lsp_action.edit()
 5413                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5414                        return LocalLspStore::deserialize_workspace_edit(
 5415                            this.upgrade().context("no app present")?,
 5416                            edit.clone(),
 5417                            push_to_history,
 5418
 5419                            lang_server.clone(),
 5420                            cx,
 5421                        )
 5422                        .await;
 5423                    }
 5424
 5425                let Some(command) = action.lsp_action.command() else {
 5426                    return Ok(ProjectTransaction::default())
 5427                };
 5428
 5429                let server_capabilities = lang_server.capabilities();
 5430                let available_commands = server_capabilities
 5431                    .execute_command_provider
 5432                    .as_ref()
 5433                    .map(|options| options.commands.as_slice())
 5434                    .unwrap_or_default();
 5435
 5436                if !available_commands.contains(&command.command) {
 5437                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5438                    return Ok(ProjectTransaction::default())
 5439                }
 5440
 5441                let request_timeout = cx.update(|app|
 5442                    ProjectSettings::get_global(app)
 5443                    .global_lsp_settings
 5444                    .get_request_timeout()
 5445                );
 5446
 5447                this.update(cx, |this, _| {
 5448                    this.as_local_mut()
 5449                        .unwrap()
 5450                        .last_workspace_edits_by_language_server
 5451                        .remove(&lang_server.server_id());
 5452                })?;
 5453
 5454                let _result = lang_server
 5455                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5456                        command: command.command.clone(),
 5457                        arguments: command.arguments.clone().unwrap_or_default(),
 5458                        ..lsp::ExecuteCommandParams::default()
 5459                    }, request_timeout)
 5460                    .await.into_response()
 5461                    .context("execute command")?;
 5462
 5463                return this.update(cx, |this, _| {
 5464                    this.as_local_mut()
 5465                        .unwrap()
 5466                        .last_workspace_edits_by_language_server
 5467                        .remove(&lang_server.server_id())
 5468                        .unwrap_or_default()
 5469                });
 5470            })
 5471        } else {
 5472            Task::ready(Err(anyhow!("no upstream client and not local")))
 5473        }
 5474    }
 5475
 5476    pub fn apply_code_action_kind(
 5477        &mut self,
 5478        buffers: HashSet<Entity<Buffer>>,
 5479        kind: CodeActionKind,
 5480        push_to_history: bool,
 5481        cx: &mut Context<Self>,
 5482    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5483        if self.as_local().is_some() {
 5484            cx.spawn(async move |lsp_store, cx| {
 5485                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5486                let result = LocalLspStore::execute_code_action_kind_locally(
 5487                    lsp_store.clone(),
 5488                    buffers,
 5489                    kind,
 5490                    push_to_history,
 5491                    cx,
 5492                )
 5493                .await;
 5494                lsp_store.update(cx, |lsp_store, _| {
 5495                    lsp_store.update_last_formatting_failure(&result);
 5496                })?;
 5497                result
 5498            })
 5499        } else if let Some((client, project_id)) = self.upstream_client() {
 5500            let buffer_store = self.buffer_store();
 5501            cx.spawn(async move |lsp_store, cx| {
 5502                let result = client
 5503                    .request(proto::ApplyCodeActionKind {
 5504                        project_id,
 5505                        kind: kind.as_str().to_owned(),
 5506                        buffer_ids: buffers
 5507                            .iter()
 5508                            .map(|buffer| {
 5509                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5510                            })
 5511                            .collect(),
 5512                    })
 5513                    .await
 5514                    .and_then(|result| result.transaction.context("missing transaction"));
 5515                lsp_store.update(cx, |lsp_store, _| {
 5516                    lsp_store.update_last_formatting_failure(&result);
 5517                })?;
 5518
 5519                let transaction_response = result?;
 5520                buffer_store
 5521                    .update(cx, |buffer_store, cx| {
 5522                        buffer_store.deserialize_project_transaction(
 5523                            transaction_response,
 5524                            push_to_history,
 5525                            cx,
 5526                        )
 5527                    })
 5528                    .await
 5529            })
 5530        } else {
 5531            Task::ready(Ok(ProjectTransaction::default()))
 5532        }
 5533    }
 5534
 5535    pub fn resolved_hint(
 5536        &mut self,
 5537        buffer_id: BufferId,
 5538        id: InlayId,
 5539        cx: &mut Context<Self>,
 5540    ) -> Option<ResolvedHint> {
 5541        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5542
 5543        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5544        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5545        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5546        let (server_id, resolve_data) = match &hint.resolve_state {
 5547            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5548            ResolveState::Resolving => {
 5549                return Some(ResolvedHint::Resolving(
 5550                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5551                ));
 5552            }
 5553            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5554        };
 5555
 5556        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5557        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5558        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5559            id,
 5560            cx.spawn(async move |lsp_store, cx| {
 5561                let resolved_hint = resolve_task.await;
 5562                lsp_store
 5563                    .update(cx, |lsp_store, _| {
 5564                        if let Some(old_inlay_hint) = lsp_store
 5565                            .lsp_data
 5566                            .get_mut(&buffer_id)
 5567                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5568                        {
 5569                            match resolved_hint {
 5570                                Ok(resolved_hint) => {
 5571                                    *old_inlay_hint = resolved_hint;
 5572                                }
 5573                                Err(e) => {
 5574                                    old_inlay_hint.resolve_state =
 5575                                        ResolveState::CanResolve(server_id, resolve_data);
 5576                                    log::error!("Inlay hint resolve failed: {e:#}");
 5577                                }
 5578                            }
 5579                        }
 5580                    })
 5581                    .ok();
 5582            })
 5583            .shared(),
 5584        );
 5585        debug_assert!(
 5586            previous_task.is_none(),
 5587            "Did not change hint's resolve state after spawning its resolve"
 5588        );
 5589        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5590        None
 5591    }
 5592
 5593    pub(crate) fn linked_edits(
 5594        &mut self,
 5595        buffer: &Entity<Buffer>,
 5596        position: Anchor,
 5597        cx: &mut Context<Self>,
 5598    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5599        let snapshot = buffer.read(cx).snapshot();
 5600        let scope = snapshot.language_scope_at(position);
 5601        let Some(server_id) = self
 5602            .as_local()
 5603            .and_then(|local| {
 5604                buffer.update(cx, |buffer, cx| {
 5605                    local
 5606                        .language_servers_for_buffer(buffer, cx)
 5607                        .filter(|(_, server)| {
 5608                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5609                        })
 5610                        .filter(|(adapter, _)| {
 5611                            scope
 5612                                .as_ref()
 5613                                .map(|scope| scope.language_allowed(&adapter.name))
 5614                                .unwrap_or(true)
 5615                        })
 5616                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5617                        .next()
 5618                })
 5619            })
 5620            .or_else(|| {
 5621                self.upstream_client()
 5622                    .is_some()
 5623                    .then_some(LanguageServerToQuery::FirstCapable)
 5624            })
 5625            .filter(|_| {
 5626                maybe!({
 5627                    buffer.read(cx).language_at(position)?;
 5628                    Some(
 5629                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5630                            .linked_edits,
 5631                    )
 5632                }) == Some(true)
 5633            })
 5634        else {
 5635            return Task::ready(Ok(Vec::new()));
 5636        };
 5637
 5638        self.request_lsp(
 5639            buffer.clone(),
 5640            server_id,
 5641            LinkedEditingRange { position },
 5642            cx,
 5643        )
 5644    }
 5645
 5646    fn apply_on_type_formatting(
 5647        &mut self,
 5648        buffer: Entity<Buffer>,
 5649        position: Anchor,
 5650        trigger: String,
 5651        cx: &mut Context<Self>,
 5652    ) -> Task<Result<Option<Transaction>>> {
 5653        if let Some((client, project_id)) = self.upstream_client() {
 5654            if !self.check_if_capable_for_proto_request(
 5655                &buffer,
 5656                |capabilities| {
 5657                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5658                },
 5659                cx,
 5660            ) {
 5661                return Task::ready(Ok(None));
 5662            }
 5663            let request = proto::OnTypeFormatting {
 5664                project_id,
 5665                buffer_id: buffer.read(cx).remote_id().into(),
 5666                position: Some(serialize_anchor(&position)),
 5667                trigger,
 5668                version: serialize_version(&buffer.read(cx).version()),
 5669            };
 5670            cx.background_spawn(async move {
 5671                client
 5672                    .request(request)
 5673                    .await?
 5674                    .transaction
 5675                    .map(language::proto::deserialize_transaction)
 5676                    .transpose()
 5677            })
 5678        } else if let Some(local) = self.as_local_mut() {
 5679            let buffer_id = buffer.read(cx).remote_id();
 5680            local.buffers_being_formatted.insert(buffer_id);
 5681            cx.spawn(async move |this, cx| {
 5682                let _cleanup = defer({
 5683                    let this = this.clone();
 5684                    let mut cx = cx.clone();
 5685                    move || {
 5686                        this.update(&mut cx, |this, _| {
 5687                            if let Some(local) = this.as_local_mut() {
 5688                                local.buffers_being_formatted.remove(&buffer_id);
 5689                            }
 5690                        })
 5691                        .ok();
 5692                    }
 5693                });
 5694
 5695                buffer
 5696                    .update(cx, |buffer, _| {
 5697                        buffer.wait_for_edits(Some(position.timestamp()))
 5698                    })
 5699                    .await?;
 5700                this.update(cx, |this, cx| {
 5701                    let position = position.to_point_utf16(buffer.read(cx));
 5702                    this.on_type_format(buffer, position, trigger, false, cx)
 5703                })?
 5704                .await
 5705            })
 5706        } else {
 5707            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5708        }
 5709    }
 5710
 5711    pub fn on_type_format<T: ToPointUtf16>(
 5712        &mut self,
 5713        buffer: Entity<Buffer>,
 5714        position: T,
 5715        trigger: String,
 5716        push_to_history: bool,
 5717        cx: &mut Context<Self>,
 5718    ) -> Task<Result<Option<Transaction>>> {
 5719        let position = position.to_point_utf16(buffer.read(cx));
 5720        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5721    }
 5722
 5723    fn on_type_format_impl(
 5724        &mut self,
 5725        buffer: Entity<Buffer>,
 5726        position: PointUtf16,
 5727        trigger: String,
 5728        push_to_history: bool,
 5729        cx: &mut Context<Self>,
 5730    ) -> Task<Result<Option<Transaction>>> {
 5731        let options = buffer.update(cx, |buffer, cx| {
 5732            lsp_command::lsp_formatting_options(
 5733                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5734            )
 5735        });
 5736
 5737        cx.spawn(async move |this, cx| {
 5738            if let Some(waiter) =
 5739                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5740            {
 5741                waiter.await?;
 5742            }
 5743            cx.update(|cx| {
 5744                this.update(cx, |this, cx| {
 5745                    this.request_lsp(
 5746                        buffer.clone(),
 5747                        LanguageServerToQuery::FirstCapable,
 5748                        OnTypeFormatting {
 5749                            position,
 5750                            trigger,
 5751                            options,
 5752                            push_to_history,
 5753                        },
 5754                        cx,
 5755                    )
 5756                })
 5757            })?
 5758            .await
 5759        })
 5760    }
 5761
 5762    pub fn definitions(
 5763        &mut self,
 5764        buffer: &Entity<Buffer>,
 5765        position: PointUtf16,
 5766        cx: &mut Context<Self>,
 5767    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5768        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5769            let request = GetDefinitions { position };
 5770            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5771                return Task::ready(Ok(None));
 5772            }
 5773
 5774            let request_timeout = ProjectSettings::get_global(cx)
 5775                .global_lsp_settings
 5776                .get_request_timeout();
 5777
 5778            let request_task = upstream_client.request_lsp(
 5779                project_id,
 5780                None,
 5781                request_timeout,
 5782                cx.background_executor().clone(),
 5783                request.to_proto(project_id, buffer.read(cx)),
 5784            );
 5785            let buffer = buffer.clone();
 5786            cx.spawn(async move |weak_lsp_store, cx| {
 5787                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5788                    return Ok(None);
 5789                };
 5790                let Some(responses) = request_task.await? else {
 5791                    return Ok(None);
 5792                };
 5793                let actions = join_all(responses.payload.into_iter().map(|response| {
 5794                    GetDefinitions { position }.response_from_proto(
 5795                        response.response,
 5796                        lsp_store.clone(),
 5797                        buffer.clone(),
 5798                        cx.clone(),
 5799                    )
 5800                }))
 5801                .await;
 5802
 5803                Ok(Some(
 5804                    actions
 5805                        .into_iter()
 5806                        .collect::<Result<Vec<Vec<_>>>>()?
 5807                        .into_iter()
 5808                        .flatten()
 5809                        .dedup()
 5810                        .collect(),
 5811                ))
 5812            })
 5813        } else {
 5814            let definitions_task = self.request_multiple_lsp_locally(
 5815                buffer,
 5816                Some(position),
 5817                GetDefinitions { position },
 5818                cx,
 5819            );
 5820            cx.background_spawn(async move {
 5821                Ok(Some(
 5822                    definitions_task
 5823                        .await
 5824                        .into_iter()
 5825                        .flat_map(|(_, definitions)| definitions)
 5826                        .dedup()
 5827                        .collect(),
 5828                ))
 5829            })
 5830        }
 5831    }
 5832
 5833    pub fn declarations(
 5834        &mut self,
 5835        buffer: &Entity<Buffer>,
 5836        position: PointUtf16,
 5837        cx: &mut Context<Self>,
 5838    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5839        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5840            let request = GetDeclarations { position };
 5841            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5842                return Task::ready(Ok(None));
 5843            }
 5844            let request_timeout = ProjectSettings::get_global(cx)
 5845                .global_lsp_settings
 5846                .get_request_timeout();
 5847            let request_task = upstream_client.request_lsp(
 5848                project_id,
 5849                None,
 5850                request_timeout,
 5851                cx.background_executor().clone(),
 5852                request.to_proto(project_id, buffer.read(cx)),
 5853            );
 5854            let buffer = buffer.clone();
 5855            cx.spawn(async move |weak_lsp_store, cx| {
 5856                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5857                    return Ok(None);
 5858                };
 5859                let Some(responses) = request_task.await? else {
 5860                    return Ok(None);
 5861                };
 5862                let actions = join_all(responses.payload.into_iter().map(|response| {
 5863                    GetDeclarations { position }.response_from_proto(
 5864                        response.response,
 5865                        lsp_store.clone(),
 5866                        buffer.clone(),
 5867                        cx.clone(),
 5868                    )
 5869                }))
 5870                .await;
 5871
 5872                Ok(Some(
 5873                    actions
 5874                        .into_iter()
 5875                        .collect::<Result<Vec<Vec<_>>>>()?
 5876                        .into_iter()
 5877                        .flatten()
 5878                        .dedup()
 5879                        .collect(),
 5880                ))
 5881            })
 5882        } else {
 5883            let declarations_task = self.request_multiple_lsp_locally(
 5884                buffer,
 5885                Some(position),
 5886                GetDeclarations { position },
 5887                cx,
 5888            );
 5889            cx.background_spawn(async move {
 5890                Ok(Some(
 5891                    declarations_task
 5892                        .await
 5893                        .into_iter()
 5894                        .flat_map(|(_, declarations)| declarations)
 5895                        .dedup()
 5896                        .collect(),
 5897                ))
 5898            })
 5899        }
 5900    }
 5901
 5902    pub fn type_definitions(
 5903        &mut self,
 5904        buffer: &Entity<Buffer>,
 5905        position: PointUtf16,
 5906        cx: &mut Context<Self>,
 5907    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5908        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5909            let request = GetTypeDefinitions { position };
 5910            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5911                return Task::ready(Ok(None));
 5912            }
 5913            let request_timeout = ProjectSettings::get_global(cx)
 5914                .global_lsp_settings
 5915                .get_request_timeout();
 5916            let request_task = upstream_client.request_lsp(
 5917                project_id,
 5918                None,
 5919                request_timeout,
 5920                cx.background_executor().clone(),
 5921                request.to_proto(project_id, buffer.read(cx)),
 5922            );
 5923            let buffer = buffer.clone();
 5924            cx.spawn(async move |weak_lsp_store, cx| {
 5925                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5926                    return Ok(None);
 5927                };
 5928                let Some(responses) = request_task.await? else {
 5929                    return Ok(None);
 5930                };
 5931                let actions = join_all(responses.payload.into_iter().map(|response| {
 5932                    GetTypeDefinitions { position }.response_from_proto(
 5933                        response.response,
 5934                        lsp_store.clone(),
 5935                        buffer.clone(),
 5936                        cx.clone(),
 5937                    )
 5938                }))
 5939                .await;
 5940
 5941                Ok(Some(
 5942                    actions
 5943                        .into_iter()
 5944                        .collect::<Result<Vec<Vec<_>>>>()?
 5945                        .into_iter()
 5946                        .flatten()
 5947                        .dedup()
 5948                        .collect(),
 5949                ))
 5950            })
 5951        } else {
 5952            let type_definitions_task = self.request_multiple_lsp_locally(
 5953                buffer,
 5954                Some(position),
 5955                GetTypeDefinitions { position },
 5956                cx,
 5957            );
 5958            cx.background_spawn(async move {
 5959                Ok(Some(
 5960                    type_definitions_task
 5961                        .await
 5962                        .into_iter()
 5963                        .flat_map(|(_, type_definitions)| type_definitions)
 5964                        .dedup()
 5965                        .collect(),
 5966                ))
 5967            })
 5968        }
 5969    }
 5970
 5971    pub fn implementations(
 5972        &mut self,
 5973        buffer: &Entity<Buffer>,
 5974        position: PointUtf16,
 5975        cx: &mut Context<Self>,
 5976    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5977        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5978            let request = GetImplementations { position };
 5979            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5980                return Task::ready(Ok(None));
 5981            }
 5982
 5983            let request_timeout = ProjectSettings::get_global(cx)
 5984                .global_lsp_settings
 5985                .get_request_timeout();
 5986            let request_task = upstream_client.request_lsp(
 5987                project_id,
 5988                None,
 5989                request_timeout,
 5990                cx.background_executor().clone(),
 5991                request.to_proto(project_id, buffer.read(cx)),
 5992            );
 5993            let buffer = buffer.clone();
 5994            cx.spawn(async move |weak_lsp_store, cx| {
 5995                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5996                    return Ok(None);
 5997                };
 5998                let Some(responses) = request_task.await? else {
 5999                    return Ok(None);
 6000                };
 6001                let actions = join_all(responses.payload.into_iter().map(|response| {
 6002                    GetImplementations { position }.response_from_proto(
 6003                        response.response,
 6004                        lsp_store.clone(),
 6005                        buffer.clone(),
 6006                        cx.clone(),
 6007                    )
 6008                }))
 6009                .await;
 6010
 6011                Ok(Some(
 6012                    actions
 6013                        .into_iter()
 6014                        .collect::<Result<Vec<Vec<_>>>>()?
 6015                        .into_iter()
 6016                        .flatten()
 6017                        .dedup()
 6018                        .collect(),
 6019                ))
 6020            })
 6021        } else {
 6022            let implementations_task = self.request_multiple_lsp_locally(
 6023                buffer,
 6024                Some(position),
 6025                GetImplementations { position },
 6026                cx,
 6027            );
 6028            cx.background_spawn(async move {
 6029                Ok(Some(
 6030                    implementations_task
 6031                        .await
 6032                        .into_iter()
 6033                        .flat_map(|(_, implementations)| implementations)
 6034                        .dedup()
 6035                        .collect(),
 6036                ))
 6037            })
 6038        }
 6039    }
 6040
 6041    pub fn references(
 6042        &mut self,
 6043        buffer: &Entity<Buffer>,
 6044        position: PointUtf16,
 6045        cx: &mut Context<Self>,
 6046    ) -> Task<Result<Option<Vec<Location>>>> {
 6047        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6048            let request = GetReferences { position };
 6049            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6050                return Task::ready(Ok(None));
 6051            }
 6052
 6053            let request_timeout = ProjectSettings::get_global(cx)
 6054                .global_lsp_settings
 6055                .get_request_timeout();
 6056            let request_task = upstream_client.request_lsp(
 6057                project_id,
 6058                None,
 6059                request_timeout,
 6060                cx.background_executor().clone(),
 6061                request.to_proto(project_id, buffer.read(cx)),
 6062            );
 6063            let buffer = buffer.clone();
 6064            cx.spawn(async move |weak_lsp_store, cx| {
 6065                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6066                    return Ok(None);
 6067                };
 6068                let Some(responses) = request_task.await? else {
 6069                    return Ok(None);
 6070                };
 6071
 6072                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6073                    GetReferences { position }.response_from_proto(
 6074                        lsp_response.response,
 6075                        lsp_store.clone(),
 6076                        buffer.clone(),
 6077                        cx.clone(),
 6078                    )
 6079                }))
 6080                .await
 6081                .into_iter()
 6082                .collect::<Result<Vec<Vec<_>>>>()?
 6083                .into_iter()
 6084                .flatten()
 6085                .dedup()
 6086                .collect();
 6087                Ok(Some(locations))
 6088            })
 6089        } else {
 6090            let references_task = self.request_multiple_lsp_locally(
 6091                buffer,
 6092                Some(position),
 6093                GetReferences { position },
 6094                cx,
 6095            );
 6096            cx.background_spawn(async move {
 6097                Ok(Some(
 6098                    references_task
 6099                        .await
 6100                        .into_iter()
 6101                        .flat_map(|(_, references)| references)
 6102                        .dedup()
 6103                        .collect(),
 6104                ))
 6105            })
 6106        }
 6107    }
 6108
 6109    pub fn code_actions(
 6110        &mut self,
 6111        buffer: &Entity<Buffer>,
 6112        range: Range<Anchor>,
 6113        kinds: Option<Vec<CodeActionKind>>,
 6114        cx: &mut Context<Self>,
 6115    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6116        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6117            let request = GetCodeActions {
 6118                range: range.clone(),
 6119                kinds: kinds.clone(),
 6120            };
 6121            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6122                return Task::ready(Ok(None));
 6123            }
 6124            let request_timeout = ProjectSettings::get_global(cx)
 6125                .global_lsp_settings
 6126                .get_request_timeout();
 6127            let request_task = upstream_client.request_lsp(
 6128                project_id,
 6129                None,
 6130                request_timeout,
 6131                cx.background_executor().clone(),
 6132                request.to_proto(project_id, buffer.read(cx)),
 6133            );
 6134            let buffer = buffer.clone();
 6135            cx.spawn(async move |weak_lsp_store, cx| {
 6136                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6137                    return Ok(None);
 6138                };
 6139                let Some(responses) = request_task.await? else {
 6140                    return Ok(None);
 6141                };
 6142                let actions = join_all(responses.payload.into_iter().map(|response| {
 6143                    GetCodeActions {
 6144                        range: range.clone(),
 6145                        kinds: kinds.clone(),
 6146                    }
 6147                    .response_from_proto(
 6148                        response.response,
 6149                        lsp_store.clone(),
 6150                        buffer.clone(),
 6151                        cx.clone(),
 6152                    )
 6153                }))
 6154                .await;
 6155
 6156                Ok(Some(
 6157                    actions
 6158                        .into_iter()
 6159                        .collect::<Result<Vec<Vec<_>>>>()?
 6160                        .into_iter()
 6161                        .flatten()
 6162                        .collect(),
 6163                ))
 6164            })
 6165        } else {
 6166            let all_actions_task = self.request_multiple_lsp_locally(
 6167                buffer,
 6168                Some(range.start),
 6169                GetCodeActions { range, kinds },
 6170                cx,
 6171            );
 6172            cx.background_spawn(async move {
 6173                Ok(Some(
 6174                    all_actions_task
 6175                        .await
 6176                        .into_iter()
 6177                        .flat_map(|(_, actions)| actions)
 6178                        .collect(),
 6179                ))
 6180            })
 6181        }
 6182    }
 6183
 6184    #[inline(never)]
 6185    pub fn completions(
 6186        &self,
 6187        buffer: &Entity<Buffer>,
 6188        position: PointUtf16,
 6189        context: CompletionContext,
 6190        cx: &mut Context<Self>,
 6191    ) -> Task<Result<Vec<CompletionResponse>>> {
 6192        let language_registry = self.languages.clone();
 6193
 6194        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6195            let snapshot = buffer.read(cx).snapshot();
 6196            let offset = position.to_offset(&snapshot);
 6197            let scope = snapshot.language_scope_at(offset);
 6198            let capable_lsps = self.all_capable_for_proto_request(
 6199                buffer,
 6200                |server_name, capabilities| {
 6201                    capabilities.completion_provider.is_some()
 6202                        && scope
 6203                            .as_ref()
 6204                            .map(|scope| scope.language_allowed(server_name))
 6205                            .unwrap_or(true)
 6206                },
 6207                cx,
 6208            );
 6209            if capable_lsps.is_empty() {
 6210                return Task::ready(Ok(Vec::new()));
 6211            }
 6212
 6213            let language = buffer.read(cx).language().cloned();
 6214
 6215            let buffer = buffer.clone();
 6216
 6217            cx.spawn(async move |this, cx| {
 6218                let requests = join_all(
 6219                    capable_lsps
 6220                        .into_iter()
 6221                        .map(|(id, server_name)| {
 6222                            let request = GetCompletions {
 6223                                position,
 6224                                context: context.clone(),
 6225                                server_id: Some(id),
 6226                            };
 6227                            let buffer = buffer.clone();
 6228                            let language = language.clone();
 6229                            let lsp_adapter = language.as_ref().and_then(|language| {
 6230                                let adapters = language_registry.lsp_adapters(&language.name());
 6231                                adapters
 6232                                    .iter()
 6233                                    .find(|adapter| adapter.name() == server_name)
 6234                                    .or_else(|| adapters.first())
 6235                                    .cloned()
 6236                            });
 6237                            let upstream_client = upstream_client.clone();
 6238                            let response = this
 6239                                .update(cx, |this, cx| {
 6240                                    this.send_lsp_proto_request(
 6241                                        buffer,
 6242                                        upstream_client,
 6243                                        project_id,
 6244                                        request,
 6245                                        cx,
 6246                                    )
 6247                                })
 6248                                .log_err();
 6249                            async move {
 6250                                let response = response?.await.log_err()?;
 6251
 6252                                let completions = populate_labels_for_completions(
 6253                                    response.completions,
 6254                                    language,
 6255                                    lsp_adapter,
 6256                                )
 6257                                .await;
 6258
 6259                                Some(CompletionResponse {
 6260                                    completions,
 6261                                    display_options: CompletionDisplayOptions::default(),
 6262                                    is_incomplete: response.is_incomplete,
 6263                                })
 6264                            }
 6265                        })
 6266                        .collect::<Vec<_>>(),
 6267                );
 6268                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6269            })
 6270        } else if let Some(local) = self.as_local() {
 6271            let snapshot = buffer.read(cx).snapshot();
 6272            let offset = position.to_offset(&snapshot);
 6273            let scope = snapshot.language_scope_at(offset);
 6274            let language = snapshot.language().cloned();
 6275            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6276                .completions
 6277                .clone();
 6278            if !completion_settings.lsp {
 6279                return Task::ready(Ok(Vec::new()));
 6280            }
 6281
 6282            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6283                local
 6284                    .language_servers_for_buffer(buffer, cx)
 6285                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6286                    .filter(|(adapter, _)| {
 6287                        scope
 6288                            .as_ref()
 6289                            .map(|scope| scope.language_allowed(&adapter.name))
 6290                            .unwrap_or(true)
 6291                    })
 6292                    .map(|(_, server)| server.server_id())
 6293                    .collect()
 6294            });
 6295
 6296            let buffer = buffer.clone();
 6297            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6298            let lsp_timeout = if lsp_timeout > 0 {
 6299                Some(Duration::from_millis(lsp_timeout))
 6300            } else {
 6301                None
 6302            };
 6303            cx.spawn(async move |this,  cx| {
 6304                let mut tasks = Vec::with_capacity(server_ids.len());
 6305                this.update(cx, |lsp_store, cx| {
 6306                    for server_id in server_ids {
 6307                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6308                        let lsp_timeout = lsp_timeout
 6309                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6310                        let mut timeout = cx.background_spawn(async move {
 6311                            match lsp_timeout {
 6312                                Some(lsp_timeout) => {
 6313                                    lsp_timeout.await;
 6314                                    true
 6315                                },
 6316                                None => false,
 6317                            }
 6318                        }).fuse();
 6319                        let mut lsp_request = lsp_store.request_lsp(
 6320                            buffer.clone(),
 6321                            LanguageServerToQuery::Other(server_id),
 6322                            GetCompletions {
 6323                                position,
 6324                                context: context.clone(),
 6325                                server_id: Some(server_id),
 6326                            },
 6327                            cx,
 6328                        ).fuse();
 6329                        let new_task = cx.background_spawn(async move {
 6330                            select_biased! {
 6331                                response = lsp_request => anyhow::Ok(Some(response?)),
 6332                                timeout_happened = timeout => {
 6333                                    if timeout_happened {
 6334                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6335                                        Ok(None)
 6336                                    } else {
 6337                                        let completions = lsp_request.await?;
 6338                                        Ok(Some(completions))
 6339                                    }
 6340                                },
 6341                            }
 6342                        });
 6343                        tasks.push((lsp_adapter, new_task));
 6344                    }
 6345                })?;
 6346
 6347                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6348                    let completion_response = task.await.ok()??;
 6349                    let completions = populate_labels_for_completions(
 6350                            completion_response.completions,
 6351                            language.clone(),
 6352                            lsp_adapter,
 6353                        )
 6354                        .await;
 6355                    Some(CompletionResponse {
 6356                        completions,
 6357                        display_options: CompletionDisplayOptions::default(),
 6358                        is_incomplete: completion_response.is_incomplete,
 6359                    })
 6360                });
 6361
 6362                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6363
 6364                Ok(responses.into_iter().flatten().collect())
 6365            })
 6366        } else {
 6367            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6368        }
 6369    }
 6370
 6371    pub fn resolve_completions(
 6372        &self,
 6373        buffer: Entity<Buffer>,
 6374        completion_indices: Vec<usize>,
 6375        completions: Rc<RefCell<Box<[Completion]>>>,
 6376        cx: &mut Context<Self>,
 6377    ) -> Task<Result<bool>> {
 6378        let client = self.upstream_client();
 6379        let buffer_id = buffer.read(cx).remote_id();
 6380        let buffer_snapshot = buffer.read(cx).snapshot();
 6381
 6382        if !self.check_if_capable_for_proto_request(
 6383            &buffer,
 6384            GetCompletions::can_resolve_completions,
 6385            cx,
 6386        ) {
 6387            return Task::ready(Ok(false));
 6388        }
 6389        cx.spawn(async move |lsp_store, cx| {
 6390            let request_timeout = cx.update(|app| {
 6391                ProjectSettings::get_global(app)
 6392                    .global_lsp_settings
 6393                    .get_request_timeout()
 6394            });
 6395
 6396            let mut did_resolve = false;
 6397            if let Some((client, project_id)) = client {
 6398                for completion_index in completion_indices {
 6399                    let server_id = {
 6400                        let completion = &completions.borrow()[completion_index];
 6401                        completion.source.server_id()
 6402                    };
 6403                    if let Some(server_id) = server_id {
 6404                        if Self::resolve_completion_remote(
 6405                            project_id,
 6406                            server_id,
 6407                            buffer_id,
 6408                            completions.clone(),
 6409                            completion_index,
 6410                            client.clone(),
 6411                        )
 6412                        .await
 6413                        .log_err()
 6414                        .is_some()
 6415                        {
 6416                            did_resolve = true;
 6417                        }
 6418                    } else {
 6419                        resolve_word_completion(
 6420                            &buffer_snapshot,
 6421                            &mut completions.borrow_mut()[completion_index],
 6422                        );
 6423                    }
 6424                }
 6425            } else {
 6426                for completion_index in completion_indices {
 6427                    let server_id = {
 6428                        let completion = &completions.borrow()[completion_index];
 6429                        completion.source.server_id()
 6430                    };
 6431                    if let Some(server_id) = server_id {
 6432                        let server_and_adapter = lsp_store
 6433                            .read_with(cx, |lsp_store, _| {
 6434                                let server = lsp_store.language_server_for_id(server_id)?;
 6435                                let adapter =
 6436                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6437                                Some((server, adapter))
 6438                            })
 6439                            .ok()
 6440                            .flatten();
 6441                        let Some((server, adapter)) = server_and_adapter else {
 6442                            continue;
 6443                        };
 6444
 6445                        let resolved = Self::resolve_completion_local(
 6446                            server,
 6447                            completions.clone(),
 6448                            completion_index,
 6449                            request_timeout,
 6450                        )
 6451                        .await
 6452                        .log_err()
 6453                        .is_some();
 6454                        if resolved {
 6455                            Self::regenerate_completion_labels(
 6456                                adapter,
 6457                                &buffer_snapshot,
 6458                                completions.clone(),
 6459                                completion_index,
 6460                            )
 6461                            .await
 6462                            .log_err();
 6463                            did_resolve = true;
 6464                        }
 6465                    } else {
 6466                        resolve_word_completion(
 6467                            &buffer_snapshot,
 6468                            &mut completions.borrow_mut()[completion_index],
 6469                        );
 6470                    }
 6471                }
 6472            }
 6473
 6474            Ok(did_resolve)
 6475        })
 6476    }
 6477
 6478    async fn resolve_completion_local(
 6479        server: Arc<lsp::LanguageServer>,
 6480        completions: Rc<RefCell<Box<[Completion]>>>,
 6481        completion_index: usize,
 6482        request_timeout: Duration,
 6483    ) -> Result<()> {
 6484        let server_id = server.server_id();
 6485        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6486            return Ok(());
 6487        }
 6488
 6489        let request = {
 6490            let completion = &completions.borrow()[completion_index];
 6491            match &completion.source {
 6492                CompletionSource::Lsp {
 6493                    lsp_completion,
 6494                    resolved,
 6495                    server_id: completion_server_id,
 6496                    ..
 6497                } => {
 6498                    if *resolved {
 6499                        return Ok(());
 6500                    }
 6501                    anyhow::ensure!(
 6502                        server_id == *completion_server_id,
 6503                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6504                    );
 6505                    server.request::<lsp::request::ResolveCompletionItem>(
 6506                        *lsp_completion.clone(),
 6507                        request_timeout,
 6508                    )
 6509                }
 6510                CompletionSource::BufferWord { .. }
 6511                | CompletionSource::Dap { .. }
 6512                | CompletionSource::Custom => {
 6513                    return Ok(());
 6514                }
 6515            }
 6516        };
 6517        let resolved_completion = request
 6518            .await
 6519            .into_response()
 6520            .context("resolve completion")?;
 6521
 6522        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6523        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6524
 6525        let mut completions = completions.borrow_mut();
 6526        let completion = &mut completions[completion_index];
 6527        if let CompletionSource::Lsp {
 6528            lsp_completion,
 6529            resolved,
 6530            server_id: completion_server_id,
 6531            ..
 6532        } = &mut completion.source
 6533        {
 6534            if *resolved {
 6535                return Ok(());
 6536            }
 6537            anyhow::ensure!(
 6538                server_id == *completion_server_id,
 6539                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6540            );
 6541            **lsp_completion = resolved_completion;
 6542            *resolved = true;
 6543        }
 6544        Ok(())
 6545    }
 6546
 6547    async fn regenerate_completion_labels(
 6548        adapter: Arc<CachedLspAdapter>,
 6549        snapshot: &BufferSnapshot,
 6550        completions: Rc<RefCell<Box<[Completion]>>>,
 6551        completion_index: usize,
 6552    ) -> Result<()> {
 6553        let completion_item = completions.borrow()[completion_index]
 6554            .source
 6555            .lsp_completion(true)
 6556            .map(Cow::into_owned);
 6557        if let Some(lsp_documentation) = completion_item
 6558            .as_ref()
 6559            .and_then(|completion_item| completion_item.documentation.clone())
 6560        {
 6561            let mut completions = completions.borrow_mut();
 6562            let completion = &mut completions[completion_index];
 6563            completion.documentation = Some(lsp_documentation.into());
 6564        } else {
 6565            let mut completions = completions.borrow_mut();
 6566            let completion = &mut completions[completion_index];
 6567            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6568        }
 6569
 6570        let mut new_label = match completion_item {
 6571            Some(completion_item) => {
 6572                // Some language servers always return `detail` lazily via resolve, regardless of
 6573                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6574                // See: https://github.com/yioneko/vtsls/issues/213
 6575                let language = snapshot.language();
 6576                match language {
 6577                    Some(language) => {
 6578                        adapter
 6579                            .labels_for_completions(
 6580                                std::slice::from_ref(&completion_item),
 6581                                language,
 6582                            )
 6583                            .await?
 6584                    }
 6585                    None => Vec::new(),
 6586                }
 6587                .pop()
 6588                .flatten()
 6589                .unwrap_or_else(|| {
 6590                    CodeLabel::fallback_for_completion(
 6591                        &completion_item,
 6592                        language.map(|language| language.as_ref()),
 6593                    )
 6594                })
 6595            }
 6596            None => CodeLabel::plain(
 6597                completions.borrow()[completion_index].new_text.clone(),
 6598                None,
 6599            ),
 6600        };
 6601        ensure_uniform_list_compatible_label(&mut new_label);
 6602
 6603        let mut completions = completions.borrow_mut();
 6604        let completion = &mut completions[completion_index];
 6605        if completion.label.filter_text() == new_label.filter_text() {
 6606            completion.label = new_label;
 6607        } else {
 6608            log::error!(
 6609                "Resolved completion changed display label from {} to {}. \
 6610                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6611                completion.label.text(),
 6612                new_label.text(),
 6613                completion.label.filter_text(),
 6614                new_label.filter_text()
 6615            );
 6616        }
 6617
 6618        Ok(())
 6619    }
 6620
 6621    async fn resolve_completion_remote(
 6622        project_id: u64,
 6623        server_id: LanguageServerId,
 6624        buffer_id: BufferId,
 6625        completions: Rc<RefCell<Box<[Completion]>>>,
 6626        completion_index: usize,
 6627        client: AnyProtoClient,
 6628    ) -> Result<()> {
 6629        let lsp_completion = {
 6630            let completion = &completions.borrow()[completion_index];
 6631            match &completion.source {
 6632                CompletionSource::Lsp {
 6633                    lsp_completion,
 6634                    resolved,
 6635                    server_id: completion_server_id,
 6636                    ..
 6637                } => {
 6638                    anyhow::ensure!(
 6639                        server_id == *completion_server_id,
 6640                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6641                    );
 6642                    if *resolved {
 6643                        return Ok(());
 6644                    }
 6645                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6646                }
 6647                CompletionSource::Custom
 6648                | CompletionSource::Dap { .. }
 6649                | CompletionSource::BufferWord { .. } => {
 6650                    return Ok(());
 6651                }
 6652            }
 6653        };
 6654        let request = proto::ResolveCompletionDocumentation {
 6655            project_id,
 6656            language_server_id: server_id.0 as u64,
 6657            lsp_completion,
 6658            buffer_id: buffer_id.into(),
 6659        };
 6660
 6661        let response = client
 6662            .request(request)
 6663            .await
 6664            .context("completion documentation resolve proto request")?;
 6665        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6666
 6667        let documentation = if response.documentation.is_empty() {
 6668            CompletionDocumentation::Undocumented
 6669        } else if response.documentation_is_markdown {
 6670            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6671        } else if response.documentation.lines().count() <= 1 {
 6672            CompletionDocumentation::SingleLine(response.documentation.into())
 6673        } else {
 6674            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6675        };
 6676
 6677        let mut completions = completions.borrow_mut();
 6678        let completion = &mut completions[completion_index];
 6679        completion.documentation = Some(documentation);
 6680        if let CompletionSource::Lsp {
 6681            insert_range,
 6682            lsp_completion,
 6683            resolved,
 6684            server_id: completion_server_id,
 6685            lsp_defaults: _,
 6686        } = &mut completion.source
 6687        {
 6688            let completion_insert_range = response
 6689                .old_insert_start
 6690                .and_then(deserialize_anchor)
 6691                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6692            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6693
 6694            if *resolved {
 6695                return Ok(());
 6696            }
 6697            anyhow::ensure!(
 6698                server_id == *completion_server_id,
 6699                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6700            );
 6701            **lsp_completion = resolved_lsp_completion;
 6702            *resolved = true;
 6703        }
 6704
 6705        let replace_range = response
 6706            .old_replace_start
 6707            .and_then(deserialize_anchor)
 6708            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6709        if let Some((old_replace_start, old_replace_end)) = replace_range
 6710            && !response.new_text.is_empty()
 6711        {
 6712            completion.new_text = response.new_text;
 6713            completion.replace_range = old_replace_start..old_replace_end;
 6714        }
 6715
 6716        Ok(())
 6717    }
 6718
 6719    pub fn apply_additional_edits_for_completion(
 6720        &self,
 6721        buffer_handle: Entity<Buffer>,
 6722        completions: Rc<RefCell<Box<[Completion]>>>,
 6723        completion_index: usize,
 6724        push_to_history: bool,
 6725        all_commit_ranges: Vec<Range<language::Anchor>>,
 6726        cx: &mut Context<Self>,
 6727    ) -> Task<Result<Option<Transaction>>> {
 6728        if let Some((client, project_id)) = self.upstream_client() {
 6729            let buffer = buffer_handle.read(cx);
 6730            let buffer_id = buffer.remote_id();
 6731            cx.spawn(async move |_, cx| {
 6732                let request = {
 6733                    let completion = completions.borrow()[completion_index].clone();
 6734                    proto::ApplyCompletionAdditionalEdits {
 6735                        project_id,
 6736                        buffer_id: buffer_id.into(),
 6737                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6738                            replace_range: completion.replace_range,
 6739                            new_text: completion.new_text,
 6740                            source: completion.source,
 6741                        })),
 6742                        all_commit_ranges: all_commit_ranges
 6743                            .iter()
 6744                            .cloned()
 6745                            .map(language::proto::serialize_anchor_range)
 6746                            .collect(),
 6747                    }
 6748                };
 6749
 6750                let Some(transaction) = client.request(request).await?.transaction else {
 6751                    return Ok(None);
 6752                };
 6753
 6754                let transaction = language::proto::deserialize_transaction(transaction)?;
 6755                buffer_handle
 6756                    .update(cx, |buffer, _| {
 6757                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6758                    })
 6759                    .await?;
 6760                if push_to_history {
 6761                    buffer_handle.update(cx, |buffer, _| {
 6762                        buffer.push_transaction(transaction.clone(), Instant::now());
 6763                        buffer.finalize_last_transaction();
 6764                    });
 6765                }
 6766                Ok(Some(transaction))
 6767            })
 6768        } else {
 6769            let request_timeout = ProjectSettings::get_global(cx)
 6770                .global_lsp_settings
 6771                .get_request_timeout();
 6772
 6773            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6774                let completion = &completions.borrow()[completion_index];
 6775                let server_id = completion.source.server_id()?;
 6776                Some(
 6777                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6778                        .1
 6779                        .clone(),
 6780                )
 6781            }) else {
 6782                return Task::ready(Ok(None));
 6783            };
 6784
 6785            cx.spawn(async move |this, cx| {
 6786                Self::resolve_completion_local(
 6787                    server.clone(),
 6788                    completions.clone(),
 6789                    completion_index,
 6790                    request_timeout,
 6791                )
 6792                .await
 6793                .context("resolving completion")?;
 6794                let completion = completions.borrow()[completion_index].clone();
 6795                let additional_text_edits = completion
 6796                    .source
 6797                    .lsp_completion(true)
 6798                    .as_ref()
 6799                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6800                if let Some(edits) = additional_text_edits {
 6801                    let edits = this
 6802                        .update(cx, |this, cx| {
 6803                            this.as_local_mut().unwrap().edits_from_lsp(
 6804                                &buffer_handle,
 6805                                edits,
 6806                                server.server_id(),
 6807                                None,
 6808                                cx,
 6809                            )
 6810                        })?
 6811                        .await?;
 6812
 6813                    buffer_handle.update(cx, |buffer, cx| {
 6814                        buffer.finalize_last_transaction();
 6815                        buffer.start_transaction();
 6816
 6817                        for (range, text) in edits {
 6818                            let primary = &completion.replace_range;
 6819
 6820                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6821                            // and the primary completion is just an insertion (empty range), then this is likely
 6822                            // an auto-import scenario and should not be considered overlapping
 6823                            // https://github.com/zed-industries/zed/issues/26136
 6824                            let is_file_start_auto_import = {
 6825                                let snapshot = buffer.snapshot();
 6826                                let primary_start_point = primary.start.to_point(&snapshot);
 6827                                let range_start_point = range.start.to_point(&snapshot);
 6828
 6829                                let result = primary_start_point.row == 0
 6830                                    && primary_start_point.column == 0
 6831                                    && range_start_point.row == 0
 6832                                    && range_start_point.column == 0;
 6833
 6834                                result
 6835                            };
 6836
 6837                            let has_overlap = if is_file_start_auto_import {
 6838                                false
 6839                            } else {
 6840                                all_commit_ranges.iter().any(|commit_range| {
 6841                                    let start_within =
 6842                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6843                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6844                                    let end_within =
 6845                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6846                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6847                                    start_within || end_within
 6848                                })
 6849                            };
 6850
 6851                            //Skip additional edits which overlap with the primary completion edit
 6852                            //https://github.com/zed-industries/zed/pull/1871
 6853                            if !has_overlap {
 6854                                buffer.edit([(range, text)], None, cx);
 6855                            }
 6856                        }
 6857
 6858                        let transaction = if buffer.end_transaction(cx).is_some() {
 6859                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6860                            if !push_to_history {
 6861                                buffer.forget_transaction(transaction.id);
 6862                            }
 6863                            Some(transaction)
 6864                        } else {
 6865                            None
 6866                        };
 6867                        Ok(transaction)
 6868                    })
 6869                } else {
 6870                    Ok(None)
 6871                }
 6872            })
 6873        }
 6874    }
 6875
 6876    pub fn pull_diagnostics(
 6877        &mut self,
 6878        buffer: Entity<Buffer>,
 6879        cx: &mut Context<Self>,
 6880    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6881        let buffer_id = buffer.read(cx).remote_id();
 6882
 6883        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6884            let mut suitable_capabilities = None;
 6885            // Are we capable for proto request?
 6886            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6887                &buffer,
 6888                |capabilities| {
 6889                    if let Some(caps) = &capabilities.diagnostic_provider {
 6890                        suitable_capabilities = Some(caps.clone());
 6891                        true
 6892                    } else {
 6893                        false
 6894                    }
 6895                },
 6896                cx,
 6897            );
 6898            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6899            let Some(dynamic_caps) = suitable_capabilities else {
 6900                return Task::ready(Ok(None));
 6901            };
 6902            assert!(any_server_has_diagnostics_provider);
 6903
 6904            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6905            let request = GetDocumentDiagnostics {
 6906                previous_result_id: None,
 6907                identifier,
 6908                registration_id: None,
 6909            };
 6910            let request_timeout = ProjectSettings::get_global(cx)
 6911                .global_lsp_settings
 6912                .get_request_timeout();
 6913            let request_task = client.request_lsp(
 6914                upstream_project_id,
 6915                None,
 6916                request_timeout,
 6917                cx.background_executor().clone(),
 6918                request.to_proto(upstream_project_id, buffer.read(cx)),
 6919            );
 6920            cx.background_spawn(async move {
 6921                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6922                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6923                // Do not attempt to further process the dummy responses here.
 6924                let _response = request_task.await?;
 6925                Ok(None)
 6926            })
 6927        } else {
 6928            let servers = buffer.update(cx, |buffer, cx| {
 6929                self.running_language_servers_for_local_buffer(buffer, cx)
 6930                    .map(|(_, server)| server.clone())
 6931                    .collect::<Vec<_>>()
 6932            });
 6933
 6934            let pull_diagnostics = servers
 6935                .into_iter()
 6936                .flat_map(|server| {
 6937                    let result = maybe!({
 6938                        let local = self.as_local()?;
 6939                        let server_id = server.server_id();
 6940                        let providers_with_identifiers = local
 6941                            .language_server_dynamic_registrations
 6942                            .get(&server_id)
 6943                            .into_iter()
 6944                            .flat_map(|registrations| registrations.diagnostics.clone())
 6945                            .collect::<Vec<_>>();
 6946                        Some(
 6947                            providers_with_identifiers
 6948                                .into_iter()
 6949                                .map(|(registration_id, dynamic_caps)| {
 6950                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6951                                    let registration_id = registration_id.map(SharedString::from);
 6952                                    let result_id = self.result_id_for_buffer_pull(
 6953                                        server_id,
 6954                                        buffer_id,
 6955                                        &registration_id,
 6956                                        cx,
 6957                                    );
 6958                                    self.request_lsp(
 6959                                        buffer.clone(),
 6960                                        LanguageServerToQuery::Other(server_id),
 6961                                        GetDocumentDiagnostics {
 6962                                            previous_result_id: result_id,
 6963                                            registration_id,
 6964                                            identifier,
 6965                                        },
 6966                                        cx,
 6967                                    )
 6968                                })
 6969                                .collect::<Vec<_>>(),
 6970                        )
 6971                    });
 6972
 6973                    result.unwrap_or_default()
 6974                })
 6975                .collect::<Vec<_>>();
 6976
 6977            cx.background_spawn(async move {
 6978                let mut responses = Vec::new();
 6979                for diagnostics in join_all(pull_diagnostics).await {
 6980                    responses.extend(diagnostics?);
 6981                }
 6982                Ok(Some(responses))
 6983            })
 6984        }
 6985    }
 6986
 6987    pub fn applicable_inlay_chunks(
 6988        &mut self,
 6989        buffer: &Entity<Buffer>,
 6990        ranges: &[Range<text::Anchor>],
 6991        cx: &mut Context<Self>,
 6992    ) -> Vec<Range<BufferRow>> {
 6993        let buffer_snapshot = buffer.read(cx).snapshot();
 6994        let ranges = ranges
 6995            .iter()
 6996            .map(|range| range.to_point(&buffer_snapshot))
 6997            .collect::<Vec<_>>();
 6998
 6999        self.latest_lsp_data(buffer, cx)
 7000            .inlay_hints
 7001            .applicable_chunks(ranges.as_slice())
 7002            .map(|chunk| chunk.row_range())
 7003            .collect()
 7004    }
 7005
 7006    pub fn invalidate_inlay_hints<'a>(
 7007        &'a mut self,
 7008        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7009    ) {
 7010        for buffer_id in for_buffers {
 7011            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7012                lsp_data.inlay_hints.clear();
 7013            }
 7014        }
 7015    }
 7016
 7017    pub fn inlay_hints(
 7018        &mut self,
 7019        invalidate: InvalidationStrategy,
 7020        buffer: Entity<Buffer>,
 7021        ranges: Vec<Range<text::Anchor>>,
 7022        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7023        cx: &mut Context<Self>,
 7024    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7025        let next_hint_id = self.next_hint_id.clone();
 7026        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7027        let query_version = lsp_data.buffer_version.clone();
 7028        let mut lsp_refresh_requested = false;
 7029        let for_server = if let InvalidationStrategy::RefreshRequested {
 7030            server_id,
 7031            request_id,
 7032        } = invalidate
 7033        {
 7034            let invalidated = lsp_data
 7035                .inlay_hints
 7036                .invalidate_for_server_refresh(server_id, request_id);
 7037            lsp_refresh_requested = invalidated;
 7038            Some(server_id)
 7039        } else {
 7040            None
 7041        };
 7042        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7043        let known_chunks = known_chunks
 7044            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7045            .map(|(_, known_chunks)| known_chunks)
 7046            .unwrap_or_default();
 7047
 7048        let buffer_snapshot = buffer.read(cx).snapshot();
 7049        let ranges = ranges
 7050            .iter()
 7051            .map(|range| range.to_point(&buffer_snapshot))
 7052            .collect::<Vec<_>>();
 7053
 7054        let mut hint_fetch_tasks = Vec::new();
 7055        let mut cached_inlay_hints = None;
 7056        let mut ranges_to_query = None;
 7057        let applicable_chunks = existing_inlay_hints
 7058            .applicable_chunks(ranges.as_slice())
 7059            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7060            .collect::<Vec<_>>();
 7061        if applicable_chunks.is_empty() {
 7062            return HashMap::default();
 7063        }
 7064
 7065        for row_chunk in applicable_chunks {
 7066            match (
 7067                existing_inlay_hints
 7068                    .cached_hints(&row_chunk)
 7069                    .filter(|_| !lsp_refresh_requested)
 7070                    .cloned(),
 7071                existing_inlay_hints
 7072                    .fetched_hints(&row_chunk)
 7073                    .as_ref()
 7074                    .filter(|_| !lsp_refresh_requested)
 7075                    .cloned(),
 7076            ) {
 7077                (None, None) => {
 7078                    let chunk_range = row_chunk.anchor_range();
 7079                    ranges_to_query
 7080                        .get_or_insert_with(Vec::new)
 7081                        .push((row_chunk, chunk_range));
 7082                }
 7083                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7084                (Some(cached_hints), None) => {
 7085                    for (server_id, cached_hints) in cached_hints {
 7086                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7087                            cached_inlay_hints
 7088                                .get_or_insert_with(HashMap::default)
 7089                                .entry(row_chunk.row_range())
 7090                                .or_insert_with(HashMap::default)
 7091                                .entry(server_id)
 7092                                .or_insert_with(Vec::new)
 7093                                .extend(cached_hints);
 7094                        }
 7095                    }
 7096                }
 7097                (Some(cached_hints), Some(fetched_hints)) => {
 7098                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7099                    for (server_id, cached_hints) in cached_hints {
 7100                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7101                            cached_inlay_hints
 7102                                .get_or_insert_with(HashMap::default)
 7103                                .entry(row_chunk.row_range())
 7104                                .or_insert_with(HashMap::default)
 7105                                .entry(server_id)
 7106                                .or_insert_with(Vec::new)
 7107                                .extend(cached_hints);
 7108                        }
 7109                    }
 7110                }
 7111            }
 7112        }
 7113
 7114        if hint_fetch_tasks.is_empty()
 7115            && ranges_to_query
 7116                .as_ref()
 7117                .is_none_or(|ranges| ranges.is_empty())
 7118            && let Some(cached_inlay_hints) = cached_inlay_hints
 7119        {
 7120            cached_inlay_hints
 7121                .into_iter()
 7122                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7123                .collect()
 7124        } else {
 7125            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7126                // When a server refresh was requested, other servers' cached hints
 7127                // are unaffected by the refresh and must be included in the result.
 7128                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7129                // removes all visible hints but only adds back the requesting
 7130                // server's new hints, permanently losing other servers' hints.
 7131                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7132                    lsp_data
 7133                        .inlay_hints
 7134                        .cached_hints(&chunk)
 7135                        .cloned()
 7136                        .unwrap_or_default()
 7137                } else {
 7138                    HashMap::default()
 7139                };
 7140
 7141                let next_hint_id = next_hint_id.clone();
 7142                let buffer = buffer.clone();
 7143                let query_version = query_version.clone();
 7144                let new_inlay_hints = cx
 7145                    .spawn(async move |lsp_store, cx| {
 7146                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7147                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7148                        })?;
 7149                        new_fetch_task
 7150                            .await
 7151                            .and_then(|new_hints_by_server| {
 7152                                lsp_store.update(cx, |lsp_store, cx| {
 7153                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7154                                    let update_cache = lsp_data.buffer_version == query_version;
 7155                                    if new_hints_by_server.is_empty() {
 7156                                        if update_cache {
 7157                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7158                                        }
 7159                                        other_servers_cached
 7160                                    } else {
 7161                                        let mut result = other_servers_cached;
 7162                                        for (server_id, new_hints) in new_hints_by_server {
 7163                                            let new_hints = new_hints
 7164                                                .into_iter()
 7165                                                .map(|new_hint| {
 7166                                                    (
 7167                                                        InlayId::Hint(next_hint_id.fetch_add(
 7168                                                            1,
 7169                                                            atomic::Ordering::AcqRel,
 7170                                                        )),
 7171                                                        new_hint,
 7172                                                    )
 7173                                                })
 7174                                                .collect::<Vec<_>>();
 7175                                            if update_cache {
 7176                                                lsp_data.inlay_hints.insert_new_hints(
 7177                                                    chunk,
 7178                                                    server_id,
 7179                                                    new_hints.clone(),
 7180                                                );
 7181                                            }
 7182                                            result.insert(server_id, new_hints);
 7183                                        }
 7184                                        result
 7185                                    }
 7186                                })
 7187                            })
 7188                            .map_err(Arc::new)
 7189                    })
 7190                    .shared();
 7191
 7192                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7193                *fetch_task = Some(new_inlay_hints.clone());
 7194                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7195            }
 7196
 7197            cached_inlay_hints
 7198                .unwrap_or_default()
 7199                .into_iter()
 7200                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7201                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7202                    (
 7203                        chunk.row_range(),
 7204                        cx.spawn(async move |_, _| {
 7205                            hints_fetch.await.map_err(|e| {
 7206                                if e.error_code() != ErrorCode::Internal {
 7207                                    anyhow!(e.error_code())
 7208                                } else {
 7209                                    anyhow!("{e:#}")
 7210                                }
 7211                            })
 7212                        }),
 7213                    )
 7214                }))
 7215                .collect()
 7216        }
 7217    }
 7218
 7219    fn fetch_inlay_hints(
 7220        &mut self,
 7221        for_server: Option<LanguageServerId>,
 7222        buffer: &Entity<Buffer>,
 7223        range: Range<Anchor>,
 7224        cx: &mut Context<Self>,
 7225    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7226        let request = InlayHints {
 7227            range: range.clone(),
 7228        };
 7229        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7230            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7231                return Task::ready(Ok(HashMap::default()));
 7232            }
 7233            let request_timeout = ProjectSettings::get_global(cx)
 7234                .global_lsp_settings
 7235                .get_request_timeout();
 7236            let request_task = upstream_client.request_lsp(
 7237                project_id,
 7238                for_server.map(|id| id.to_proto()),
 7239                request_timeout,
 7240                cx.background_executor().clone(),
 7241                request.to_proto(project_id, buffer.read(cx)),
 7242            );
 7243            let buffer = buffer.clone();
 7244            cx.spawn(async move |weak_lsp_store, cx| {
 7245                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7246                    return Ok(HashMap::default());
 7247                };
 7248                let Some(responses) = request_task.await? else {
 7249                    return Ok(HashMap::default());
 7250                };
 7251
 7252                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7253                    let lsp_store = lsp_store.clone();
 7254                    let buffer = buffer.clone();
 7255                    let cx = cx.clone();
 7256                    let request = request.clone();
 7257                    async move {
 7258                        (
 7259                            LanguageServerId::from_proto(response.server_id),
 7260                            request
 7261                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7262                                .await,
 7263                        )
 7264                    }
 7265                }))
 7266                .await;
 7267
 7268                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7269                let mut has_errors = false;
 7270                let inlay_hints = inlay_hints
 7271                    .into_iter()
 7272                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7273                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7274                        Err(e) => {
 7275                            has_errors = true;
 7276                            log::error!("{e:#}");
 7277                            None
 7278                        }
 7279                    })
 7280                    .map(|(server_id, mut new_hints)| {
 7281                        new_hints.retain(|hint| {
 7282                            hint.position.is_valid(&buffer_snapshot)
 7283                                && range.start.is_valid(&buffer_snapshot)
 7284                                && range.end.is_valid(&buffer_snapshot)
 7285                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7286                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7287                        });
 7288                        (server_id, new_hints)
 7289                    })
 7290                    .collect::<HashMap<_, _>>();
 7291                anyhow::ensure!(
 7292                    !has_errors || !inlay_hints.is_empty(),
 7293                    "Failed to fetch inlay hints"
 7294                );
 7295                Ok(inlay_hints)
 7296            })
 7297        } else {
 7298            let inlay_hints_task = match for_server {
 7299                Some(server_id) => {
 7300                    let server_task = self.request_lsp(
 7301                        buffer.clone(),
 7302                        LanguageServerToQuery::Other(server_id),
 7303                        request,
 7304                        cx,
 7305                    );
 7306                    cx.background_spawn(async move {
 7307                        let mut responses = Vec::new();
 7308                        match server_task.await {
 7309                            Ok(response) => responses.push((server_id, response)),
 7310                            // rust-analyzer likes to error with this when its still loading up
 7311                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7312                            Err(e) => log::error!(
 7313                                "Error handling response for inlay hints request: {e:#}"
 7314                            ),
 7315                        }
 7316                        responses
 7317                    })
 7318                }
 7319                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7320            };
 7321            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7322            cx.background_spawn(async move {
 7323                Ok(inlay_hints_task
 7324                    .await
 7325                    .into_iter()
 7326                    .map(|(server_id, mut new_hints)| {
 7327                        new_hints.retain(|hint| {
 7328                            hint.position.is_valid(&buffer_snapshot)
 7329                                && range.start.is_valid(&buffer_snapshot)
 7330                                && range.end.is_valid(&buffer_snapshot)
 7331                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7332                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7333                        });
 7334                        (server_id, new_hints)
 7335                    })
 7336                    .collect())
 7337            })
 7338        }
 7339    }
 7340
 7341    fn diagnostic_registration_exists(
 7342        &self,
 7343        server_id: LanguageServerId,
 7344        registration_id: &Option<SharedString>,
 7345    ) -> bool {
 7346        let Some(local) = self.as_local() else {
 7347            return false;
 7348        };
 7349        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7350        else {
 7351            return false;
 7352        };
 7353        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7354        registrations.diagnostics.contains_key(&registration_key)
 7355    }
 7356
 7357    pub fn pull_diagnostics_for_buffer(
 7358        &mut self,
 7359        buffer: Entity<Buffer>,
 7360        cx: &mut Context<Self>,
 7361    ) -> Task<anyhow::Result<()>> {
 7362        let diagnostics = self.pull_diagnostics(buffer, cx);
 7363        cx.spawn(async move |lsp_store, cx| {
 7364            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7365                return Ok(());
 7366            };
 7367            lsp_store.update(cx, |lsp_store, cx| {
 7368                if lsp_store.as_local().is_none() {
 7369                    return;
 7370                }
 7371
 7372                let mut unchanged_buffers = HashMap::default();
 7373                let server_diagnostics_updates = diagnostics
 7374                    .into_iter()
 7375                    .filter_map(|diagnostics_set| match diagnostics_set {
 7376                        LspPullDiagnostics::Response {
 7377                            server_id,
 7378                            uri,
 7379                            diagnostics,
 7380                            registration_id,
 7381                        } => Some((server_id, uri, diagnostics, registration_id)),
 7382                        LspPullDiagnostics::Default => None,
 7383                    })
 7384                    .filter(|(server_id, _, _, registration_id)| {
 7385                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7386                    })
 7387                    .fold(
 7388                        HashMap::default(),
 7389                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7390                            let (result_id, diagnostics) = match diagnostics {
 7391                                PulledDiagnostics::Unchanged { result_id } => {
 7392                                    unchanged_buffers
 7393                                        .entry(new_registration_id.clone())
 7394                                        .or_insert_with(HashSet::default)
 7395                                        .insert(uri.clone());
 7396                                    (Some(result_id), Vec::new())
 7397                                }
 7398                                PulledDiagnostics::Changed {
 7399                                    result_id,
 7400                                    diagnostics,
 7401                                } => (result_id, diagnostics),
 7402                            };
 7403                            let disk_based_sources = Cow::Owned(
 7404                                lsp_store
 7405                                    .language_server_adapter_for_id(server_id)
 7406                                    .as_ref()
 7407                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7408                                    .unwrap_or(&[])
 7409                                    .to_vec(),
 7410                            );
 7411                            acc.entry(server_id)
 7412                                .or_insert_with(HashMap::default)
 7413                                .entry(new_registration_id.clone())
 7414                                .or_insert_with(Vec::new)
 7415                                .push(DocumentDiagnosticsUpdate {
 7416                                    server_id,
 7417                                    diagnostics: lsp::PublishDiagnosticsParams {
 7418                                        uri,
 7419                                        diagnostics,
 7420                                        version: None,
 7421                                    },
 7422                                    result_id: result_id.map(SharedString::new),
 7423                                    disk_based_sources,
 7424                                    registration_id: new_registration_id,
 7425                                });
 7426                            acc
 7427                        },
 7428                    );
 7429
 7430                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7431                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7432                        lsp_store
 7433                            .merge_lsp_diagnostics(
 7434                                DiagnosticSourceKind::Pulled,
 7435                                diagnostic_updates,
 7436                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7437                                    DiagnosticSourceKind::Pulled => {
 7438                                        old_diagnostic.registration_id != registration_id
 7439                                            || unchanged_buffers
 7440                                                .get(&old_diagnostic.registration_id)
 7441                                                .is_some_and(|unchanged_buffers| {
 7442                                                    unchanged_buffers.contains(&document_uri)
 7443                                                })
 7444                                    }
 7445                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7446                                        true
 7447                                    }
 7448                                },
 7449                                cx,
 7450                            )
 7451                            .log_err();
 7452                    }
 7453                }
 7454            })
 7455        })
 7456    }
 7457
 7458    pub fn signature_help<T: ToPointUtf16>(
 7459        &mut self,
 7460        buffer: &Entity<Buffer>,
 7461        position: T,
 7462        cx: &mut Context<Self>,
 7463    ) -> Task<Option<Vec<SignatureHelp>>> {
 7464        let position = position.to_point_utf16(buffer.read(cx));
 7465
 7466        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7467            let request = GetSignatureHelp { position };
 7468            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7469                return Task::ready(None);
 7470            }
 7471            let request_timeout = ProjectSettings::get_global(cx)
 7472                .global_lsp_settings
 7473                .get_request_timeout();
 7474            let request_task = client.request_lsp(
 7475                upstream_project_id,
 7476                None,
 7477                request_timeout,
 7478                cx.background_executor().clone(),
 7479                request.to_proto(upstream_project_id, buffer.read(cx)),
 7480            );
 7481            let buffer = buffer.clone();
 7482            cx.spawn(async move |weak_lsp_store, cx| {
 7483                let lsp_store = weak_lsp_store.upgrade()?;
 7484                let signatures = join_all(
 7485                    request_task
 7486                        .await
 7487                        .log_err()
 7488                        .flatten()
 7489                        .map(|response| response.payload)
 7490                        .unwrap_or_default()
 7491                        .into_iter()
 7492                        .map(|response| {
 7493                            let response = GetSignatureHelp { position }.response_from_proto(
 7494                                response.response,
 7495                                lsp_store.clone(),
 7496                                buffer.clone(),
 7497                                cx.clone(),
 7498                            );
 7499                            async move { response.await.log_err().flatten() }
 7500                        }),
 7501                )
 7502                .await
 7503                .into_iter()
 7504                .flatten()
 7505                .collect();
 7506                Some(signatures)
 7507            })
 7508        } else {
 7509            let all_actions_task = self.request_multiple_lsp_locally(
 7510                buffer,
 7511                Some(position),
 7512                GetSignatureHelp { position },
 7513                cx,
 7514            );
 7515            cx.background_spawn(async move {
 7516                Some(
 7517                    all_actions_task
 7518                        .await
 7519                        .into_iter()
 7520                        .flat_map(|(_, actions)| actions)
 7521                        .collect::<Vec<_>>(),
 7522                )
 7523            })
 7524        }
 7525    }
 7526
 7527    pub fn hover(
 7528        &mut self,
 7529        buffer: &Entity<Buffer>,
 7530        position: PointUtf16,
 7531        cx: &mut Context<Self>,
 7532    ) -> Task<Option<Vec<Hover>>> {
 7533        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7534            let request = GetHover { position };
 7535            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7536                return Task::ready(None);
 7537            }
 7538            let request_timeout = ProjectSettings::get_global(cx)
 7539                .global_lsp_settings
 7540                .get_request_timeout();
 7541            let request_task = client.request_lsp(
 7542                upstream_project_id,
 7543                None,
 7544                request_timeout,
 7545                cx.background_executor().clone(),
 7546                request.to_proto(upstream_project_id, buffer.read(cx)),
 7547            );
 7548            let buffer = buffer.clone();
 7549            cx.spawn(async move |weak_lsp_store, cx| {
 7550                let lsp_store = weak_lsp_store.upgrade()?;
 7551                let hovers = join_all(
 7552                    request_task
 7553                        .await
 7554                        .log_err()
 7555                        .flatten()
 7556                        .map(|response| response.payload)
 7557                        .unwrap_or_default()
 7558                        .into_iter()
 7559                        .map(|response| {
 7560                            let response = GetHover { position }.response_from_proto(
 7561                                response.response,
 7562                                lsp_store.clone(),
 7563                                buffer.clone(),
 7564                                cx.clone(),
 7565                            );
 7566                            async move {
 7567                                response
 7568                                    .await
 7569                                    .log_err()
 7570                                    .flatten()
 7571                                    .and_then(remove_empty_hover_blocks)
 7572                            }
 7573                        }),
 7574                )
 7575                .await
 7576                .into_iter()
 7577                .flatten()
 7578                .collect();
 7579                Some(hovers)
 7580            })
 7581        } else {
 7582            let all_actions_task = self.request_multiple_lsp_locally(
 7583                buffer,
 7584                Some(position),
 7585                GetHover { position },
 7586                cx,
 7587            );
 7588            cx.background_spawn(async move {
 7589                Some(
 7590                    all_actions_task
 7591                        .await
 7592                        .into_iter()
 7593                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7594                        .collect::<Vec<Hover>>(),
 7595                )
 7596            })
 7597        }
 7598    }
 7599
 7600    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7601        let language_registry = self.languages.clone();
 7602
 7603        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7604            let request = upstream_client.request(proto::GetProjectSymbols {
 7605                project_id: *project_id,
 7606                query: query.to_string(),
 7607            });
 7608            cx.foreground_executor().spawn(async move {
 7609                let response = request.await?;
 7610                let mut symbols = Vec::new();
 7611                let core_symbols = response
 7612                    .symbols
 7613                    .into_iter()
 7614                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7615                    .collect::<Vec<_>>();
 7616                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7617                    .await;
 7618                Ok(symbols)
 7619            })
 7620        } else if let Some(local) = self.as_local() {
 7621            struct WorkspaceSymbolsResult {
 7622                server_id: LanguageServerId,
 7623                lsp_adapter: Arc<CachedLspAdapter>,
 7624                worktree: WeakEntity<Worktree>,
 7625                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7626            }
 7627
 7628            let mut requests = Vec::new();
 7629            let mut requested_servers = BTreeSet::new();
 7630            let request_timeout = ProjectSettings::get_global(cx)
 7631                .global_lsp_settings
 7632                .get_request_timeout();
 7633
 7634            for (seed, state) in local.language_server_ids.iter() {
 7635                let Some(worktree_handle) = self
 7636                    .worktree_store
 7637                    .read(cx)
 7638                    .worktree_for_id(seed.worktree_id, cx)
 7639                else {
 7640                    continue;
 7641                };
 7642
 7643                let worktree = worktree_handle.read(cx);
 7644                if !worktree.is_visible() {
 7645                    continue;
 7646                }
 7647
 7648                if !requested_servers.insert(state.id) {
 7649                    continue;
 7650                }
 7651
 7652                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7653                    Some(LanguageServerState::Running {
 7654                        adapter, server, ..
 7655                    }) => (adapter.clone(), server),
 7656
 7657                    _ => continue,
 7658                };
 7659
 7660                let supports_workspace_symbol_request =
 7661                    match server.capabilities().workspace_symbol_provider {
 7662                        Some(OneOf::Left(supported)) => supported,
 7663                        Some(OneOf::Right(_)) => true,
 7664                        None => false,
 7665                    };
 7666
 7667                if !supports_workspace_symbol_request {
 7668                    continue;
 7669                }
 7670
 7671                let worktree_handle = worktree_handle.clone();
 7672                let server_id = server.server_id();
 7673                requests.push(
 7674                    server
 7675                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7676                            lsp::WorkspaceSymbolParams {
 7677                                query: query.to_string(),
 7678                                ..Default::default()
 7679                            },
 7680                            request_timeout,
 7681                        )
 7682                        .map(move |response| {
 7683                            let lsp_symbols = response
 7684                                .into_response()
 7685                                .context("workspace symbols request")
 7686                                .log_err()
 7687                                .flatten()
 7688                                .map(|symbol_response| match symbol_response {
 7689                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7690                                        flat_responses
 7691                                            .into_iter()
 7692                                            .map(|lsp_symbol| {
 7693                                                (
 7694                                                    lsp_symbol.name,
 7695                                                    lsp_symbol.kind,
 7696                                                    lsp_symbol.location,
 7697                                                    lsp_symbol.container_name,
 7698                                                )
 7699                                            })
 7700                                            .collect::<Vec<_>>()
 7701                                    }
 7702                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7703                                        nested_responses
 7704                                            .into_iter()
 7705                                            .filter_map(|lsp_symbol| {
 7706                                                let location = match lsp_symbol.location {
 7707                                                    OneOf::Left(location) => location,
 7708                                                    OneOf::Right(_) => {
 7709                                                        log::error!(
 7710                                                            "Unexpected: client capabilities \
 7711                                                            forbid symbol resolutions in \
 7712                                                            workspace.symbol.resolveSupport"
 7713                                                        );
 7714                                                        return None;
 7715                                                    }
 7716                                                };
 7717                                                Some((
 7718                                                    lsp_symbol.name,
 7719                                                    lsp_symbol.kind,
 7720                                                    location,
 7721                                                    lsp_symbol.container_name,
 7722                                                ))
 7723                                            })
 7724                                            .collect::<Vec<_>>()
 7725                                    }
 7726                                })
 7727                                .unwrap_or_default();
 7728
 7729                            WorkspaceSymbolsResult {
 7730                                server_id,
 7731                                lsp_adapter,
 7732                                worktree: worktree_handle.downgrade(),
 7733                                lsp_symbols,
 7734                            }
 7735                        }),
 7736                );
 7737            }
 7738
 7739            cx.spawn(async move |this, cx| {
 7740                let responses = futures::future::join_all(requests).await;
 7741                let this = match this.upgrade() {
 7742                    Some(this) => this,
 7743                    None => return Ok(Vec::new()),
 7744                };
 7745
 7746                let mut symbols = Vec::new();
 7747                for result in responses {
 7748                    let core_symbols = this.update(cx, |this, cx| {
 7749                        result
 7750                            .lsp_symbols
 7751                            .into_iter()
 7752                            .filter_map(
 7753                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7754                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7755                                    let source_worktree = result.worktree.upgrade()?;
 7756                                    let source_worktree_id = source_worktree.read(cx).id();
 7757
 7758                                    let path = if let Some((tree, rel_path)) =
 7759                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7760                                    {
 7761                                        let worktree_id = tree.read(cx).id();
 7762                                        SymbolLocation::InProject(ProjectPath {
 7763                                            worktree_id,
 7764                                            path: rel_path,
 7765                                        })
 7766                                    } else {
 7767                                        SymbolLocation::OutsideProject {
 7768                                            signature: this.symbol_signature(&abs_path),
 7769                                            abs_path: abs_path.into(),
 7770                                        }
 7771                                    };
 7772
 7773                                    Some(CoreSymbol {
 7774                                        source_language_server_id: result.server_id,
 7775                                        language_server_name: result.lsp_adapter.name.clone(),
 7776                                        source_worktree_id,
 7777                                        path,
 7778                                        kind: symbol_kind,
 7779                                        name: collapse_newlines(&symbol_name, ""),
 7780                                        range: range_from_lsp(symbol_location.range),
 7781                                        container_name: container_name
 7782                                            .map(|c| collapse_newlines(&c, "")),
 7783                                    })
 7784                                },
 7785                            )
 7786                            .collect::<Vec<_>>()
 7787                    });
 7788
 7789                    populate_labels_for_symbols(
 7790                        core_symbols,
 7791                        &language_registry,
 7792                        Some(result.lsp_adapter),
 7793                        &mut symbols,
 7794                    )
 7795                    .await;
 7796                }
 7797
 7798                Ok(symbols)
 7799            })
 7800        } else {
 7801            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7802        }
 7803    }
 7804
 7805    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7806        let mut summary = DiagnosticSummary::default();
 7807        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7808            summary.error_count += path_summary.error_count;
 7809            summary.warning_count += path_summary.warning_count;
 7810        }
 7811        summary
 7812    }
 7813
 7814    /// Returns the diagnostic summary for a specific project path.
 7815    pub fn diagnostic_summary_for_path(
 7816        &self,
 7817        project_path: &ProjectPath,
 7818        _: &App,
 7819    ) -> DiagnosticSummary {
 7820        if let Some(summaries) = self
 7821            .diagnostic_summaries
 7822            .get(&project_path.worktree_id)
 7823            .and_then(|map| map.get(&project_path.path))
 7824        {
 7825            let (error_count, warning_count) = summaries.iter().fold(
 7826                (0, 0),
 7827                |(error_count, warning_count), (_language_server_id, summary)| {
 7828                    (
 7829                        error_count + summary.error_count,
 7830                        warning_count + summary.warning_count,
 7831                    )
 7832                },
 7833            );
 7834
 7835            DiagnosticSummary {
 7836                error_count,
 7837                warning_count,
 7838            }
 7839        } else {
 7840            DiagnosticSummary::default()
 7841        }
 7842    }
 7843
 7844    pub fn diagnostic_summaries<'a>(
 7845        &'a self,
 7846        include_ignored: bool,
 7847        cx: &'a App,
 7848    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7849        self.worktree_store
 7850            .read(cx)
 7851            .visible_worktrees(cx)
 7852            .filter_map(|worktree| {
 7853                let worktree = worktree.read(cx);
 7854                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7855            })
 7856            .flat_map(move |(worktree, summaries)| {
 7857                let worktree_id = worktree.id();
 7858                summaries
 7859                    .iter()
 7860                    .filter(move |(path, _)| {
 7861                        include_ignored
 7862                            || worktree
 7863                                .entry_for_path(path.as_ref())
 7864                                .is_some_and(|entry| !entry.is_ignored)
 7865                    })
 7866                    .flat_map(move |(path, summaries)| {
 7867                        summaries.iter().map(move |(server_id, summary)| {
 7868                            (
 7869                                ProjectPath {
 7870                                    worktree_id,
 7871                                    path: path.clone(),
 7872                                },
 7873                                *server_id,
 7874                                *summary,
 7875                            )
 7876                        })
 7877                    })
 7878            })
 7879    }
 7880
 7881    pub fn on_buffer_edited(
 7882        &mut self,
 7883        buffer: Entity<Buffer>,
 7884        cx: &mut Context<Self>,
 7885    ) -> Option<()> {
 7886        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7887            Some(
 7888                self.as_local()?
 7889                    .language_servers_for_buffer(buffer, cx)
 7890                    .map(|i| i.1.clone())
 7891                    .collect(),
 7892            )
 7893        })?;
 7894
 7895        let buffer = buffer.read(cx);
 7896        let file = File::from_dyn(buffer.file())?;
 7897        let abs_path = file.as_local()?.abs_path(cx);
 7898        let uri = lsp::Uri::from_file_path(&abs_path)
 7899            .ok()
 7900            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7901            .log_err()?;
 7902        let next_snapshot = buffer.text_snapshot();
 7903        for language_server in language_servers {
 7904            let language_server = language_server.clone();
 7905
 7906            let buffer_snapshots = self
 7907                .as_local_mut()?
 7908                .buffer_snapshots
 7909                .get_mut(&buffer.remote_id())
 7910                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7911            let previous_snapshot = buffer_snapshots.last()?;
 7912
 7913            let build_incremental_change = || {
 7914                buffer
 7915                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7916                        previous_snapshot.snapshot.version(),
 7917                    )
 7918                    .map(|edit| {
 7919                        let edit_start = edit.new.start.0;
 7920                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7921                        let new_text = next_snapshot
 7922                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7923                            .collect();
 7924                        lsp::TextDocumentContentChangeEvent {
 7925                            range: Some(lsp::Range::new(
 7926                                point_to_lsp(edit_start),
 7927                                point_to_lsp(edit_end),
 7928                            )),
 7929                            range_length: None,
 7930                            text: new_text,
 7931                        }
 7932                    })
 7933                    .collect()
 7934            };
 7935
 7936            let document_sync_kind = language_server
 7937                .capabilities()
 7938                .text_document_sync
 7939                .as_ref()
 7940                .and_then(|sync| match sync {
 7941                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7942                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7943                });
 7944
 7945            let content_changes: Vec<_> = match document_sync_kind {
 7946                Some(lsp::TextDocumentSyncKind::FULL) => {
 7947                    vec![lsp::TextDocumentContentChangeEvent {
 7948                        range: None,
 7949                        range_length: None,
 7950                        text: next_snapshot.text(),
 7951                    }]
 7952                }
 7953                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7954                _ => {
 7955                    #[cfg(any(test, feature = "test-support"))]
 7956                    {
 7957                        build_incremental_change()
 7958                    }
 7959
 7960                    #[cfg(not(any(test, feature = "test-support")))]
 7961                    {
 7962                        continue;
 7963                    }
 7964                }
 7965            };
 7966
 7967            let next_version = previous_snapshot.version + 1;
 7968            buffer_snapshots.push(LspBufferSnapshot {
 7969                version: next_version,
 7970                snapshot: next_snapshot.clone(),
 7971            });
 7972
 7973            language_server
 7974                .notify::<lsp::notification::DidChangeTextDocument>(
 7975                    lsp::DidChangeTextDocumentParams {
 7976                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7977                            uri.clone(),
 7978                            next_version,
 7979                        ),
 7980                        content_changes,
 7981                    },
 7982                )
 7983                .ok();
 7984            self.pull_workspace_diagnostics(language_server.server_id());
 7985        }
 7986
 7987        None
 7988    }
 7989
 7990    pub fn on_buffer_saved(
 7991        &mut self,
 7992        buffer: Entity<Buffer>,
 7993        cx: &mut Context<Self>,
 7994    ) -> Option<()> {
 7995        let file = File::from_dyn(buffer.read(cx).file())?;
 7996        let worktree_id = file.worktree_id(cx);
 7997        let abs_path = file.as_local()?.abs_path(cx);
 7998        let text_document = lsp::TextDocumentIdentifier {
 7999            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8000        };
 8001        let local = self.as_local()?;
 8002
 8003        for server in local.language_servers_for_worktree(worktree_id) {
 8004            if let Some(include_text) = include_text(server.as_ref()) {
 8005                let text = if include_text {
 8006                    Some(buffer.read(cx).text())
 8007                } else {
 8008                    None
 8009                };
 8010                server
 8011                    .notify::<lsp::notification::DidSaveTextDocument>(
 8012                        lsp::DidSaveTextDocumentParams {
 8013                            text_document: text_document.clone(),
 8014                            text,
 8015                        },
 8016                    )
 8017                    .ok();
 8018            }
 8019        }
 8020
 8021        let language_servers = buffer.update(cx, |buffer, cx| {
 8022            local.language_server_ids_for_buffer(buffer, cx)
 8023        });
 8024        for language_server_id in language_servers {
 8025            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8026        }
 8027
 8028        None
 8029    }
 8030
 8031    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8032        maybe!(async move {
 8033            let mut refreshed_servers = HashSet::default();
 8034            let servers = lsp_store
 8035                .update(cx, |lsp_store, cx| {
 8036                    let local = lsp_store.as_local()?;
 8037
 8038                    let servers = local
 8039                        .language_server_ids
 8040                        .iter()
 8041                        .filter_map(|(seed, state)| {
 8042                            let worktree = lsp_store
 8043                                .worktree_store
 8044                                .read(cx)
 8045                                .worktree_for_id(seed.worktree_id, cx);
 8046                            let delegate: Arc<dyn LspAdapterDelegate> =
 8047                                worktree.map(|worktree| {
 8048                                    LocalLspAdapterDelegate::new(
 8049                                        local.languages.clone(),
 8050                                        &local.environment,
 8051                                        cx.weak_entity(),
 8052                                        &worktree,
 8053                                        local.http_client.clone(),
 8054                                        local.fs.clone(),
 8055                                        cx,
 8056                                    )
 8057                                })?;
 8058                            let server_id = state.id;
 8059
 8060                            let states = local.language_servers.get(&server_id)?;
 8061
 8062                            match states {
 8063                                LanguageServerState::Starting { .. } => None,
 8064                                LanguageServerState::Running {
 8065                                    adapter, server, ..
 8066                                } => {
 8067                                    let adapter = adapter.clone();
 8068                                    let server = server.clone();
 8069                                    refreshed_servers.insert(server.name());
 8070                                    let toolchain = seed.toolchain.clone();
 8071                                    Some(cx.spawn(async move |_, cx| {
 8072                                        let settings =
 8073                                            LocalLspStore::workspace_configuration_for_adapter(
 8074                                                adapter.adapter.clone(),
 8075                                                &delegate,
 8076                                                toolchain,
 8077                                                None,
 8078                                                cx,
 8079                                            )
 8080                                            .await
 8081                                            .ok()?;
 8082                                        server
 8083                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8084                                                lsp::DidChangeConfigurationParams { settings },
 8085                                            )
 8086                                            .ok()?;
 8087                                        Some(())
 8088                                    }))
 8089                                }
 8090                            }
 8091                        })
 8092                        .collect::<Vec<_>>();
 8093
 8094                    Some(servers)
 8095                })
 8096                .ok()
 8097                .flatten()?;
 8098
 8099            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8100            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8101            // to stop and unregister its language server wrapper.
 8102            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8103            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8104            let _: Vec<Option<()>> = join_all(servers).await;
 8105
 8106            Some(())
 8107        })
 8108        .await;
 8109    }
 8110
 8111    fn maintain_workspace_config(
 8112        external_refresh_requests: watch::Receiver<()>,
 8113        cx: &mut Context<Self>,
 8114    ) -> Task<Result<()>> {
 8115        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8116        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8117
 8118        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8119            *settings_changed_tx.borrow_mut() = ();
 8120        });
 8121
 8122        let mut joint_future =
 8123            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8124        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8125        // - 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).
 8126        // - 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.
 8127        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8128        // - 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,
 8129        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8130        cx.spawn(async move |this, cx| {
 8131            while let Some(()) = joint_future.next().await {
 8132                this.update(cx, |this, cx| {
 8133                    this.refresh_server_tree(cx);
 8134                })
 8135                .ok();
 8136
 8137                Self::refresh_workspace_configurations(&this, cx).await;
 8138            }
 8139
 8140            drop(settings_observation);
 8141            anyhow::Ok(())
 8142        })
 8143    }
 8144
 8145    pub fn running_language_servers_for_local_buffer<'a>(
 8146        &'a self,
 8147        buffer: &Buffer,
 8148        cx: &mut App,
 8149    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8150        let local = self.as_local();
 8151        let language_server_ids = local
 8152            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8153            .unwrap_or_default();
 8154
 8155        language_server_ids
 8156            .into_iter()
 8157            .filter_map(
 8158                move |server_id| match local?.language_servers.get(&server_id)? {
 8159                    LanguageServerState::Running {
 8160                        adapter, server, ..
 8161                    } => Some((adapter, server)),
 8162                    _ => None,
 8163                },
 8164            )
 8165    }
 8166
 8167    pub fn language_servers_for_local_buffer(
 8168        &self,
 8169        buffer: &Buffer,
 8170        cx: &mut App,
 8171    ) -> Vec<LanguageServerId> {
 8172        let local = self.as_local();
 8173        local
 8174            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8175            .unwrap_or_default()
 8176    }
 8177
 8178    pub fn language_server_for_local_buffer<'a>(
 8179        &'a self,
 8180        buffer: &'a Buffer,
 8181        server_id: LanguageServerId,
 8182        cx: &'a mut App,
 8183    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8184        self.as_local()?
 8185            .language_servers_for_buffer(buffer, cx)
 8186            .find(|(_, s)| s.server_id() == server_id)
 8187    }
 8188
 8189    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8190        self.diagnostic_summaries.remove(&id_to_remove);
 8191        if let Some(local) = self.as_local_mut() {
 8192            let to_remove = local.remove_worktree(id_to_remove, cx);
 8193            for server in to_remove {
 8194                self.language_server_statuses.remove(&server);
 8195            }
 8196        }
 8197    }
 8198
 8199    fn invalidate_diagnostic_summaries_for_removed_entries(
 8200        &mut self,
 8201        worktree_id: WorktreeId,
 8202        changes: &UpdatedEntriesSet,
 8203        cx: &mut Context<Self>,
 8204    ) {
 8205        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8206            return;
 8207        };
 8208
 8209        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8210        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8211        let downstream = self.downstream_client.clone();
 8212
 8213        for (path, _, _) in changes
 8214            .iter()
 8215            .filter(|(_, _, change)| *change == PathChange::Removed)
 8216        {
 8217            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8218                for (server_id, _) in &summaries_by_server_id {
 8219                    cleared_server_ids.insert(*server_id);
 8220                    if let Some((client, project_id)) = &downstream {
 8221                        client
 8222                            .send(proto::UpdateDiagnosticSummary {
 8223                                project_id: *project_id,
 8224                                worktree_id: worktree_id.to_proto(),
 8225                                summary: Some(proto::DiagnosticSummary {
 8226                                    path: path.as_ref().to_proto(),
 8227                                    language_server_id: server_id.0 as u64,
 8228                                    error_count: 0,
 8229                                    warning_count: 0,
 8230                                }),
 8231                                more_summaries: Vec::new(),
 8232                            })
 8233                            .ok();
 8234                    }
 8235                }
 8236                cleared_paths.push(ProjectPath {
 8237                    worktree_id,
 8238                    path: path.clone(),
 8239                });
 8240            }
 8241        }
 8242
 8243        if !cleared_paths.is_empty() {
 8244            for server_id in cleared_server_ids {
 8245                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8246                    server_id,
 8247                    paths: cleared_paths.clone(),
 8248                });
 8249            }
 8250        }
 8251    }
 8252
 8253    pub fn shared(
 8254        &mut self,
 8255        project_id: u64,
 8256        downstream_client: AnyProtoClient,
 8257        _: &mut Context<Self>,
 8258    ) {
 8259        self.downstream_client = Some((downstream_client.clone(), project_id));
 8260
 8261        for (server_id, status) in &self.language_server_statuses {
 8262            if let Some(server) = self.language_server_for_id(*server_id) {
 8263                downstream_client
 8264                    .send(proto::StartLanguageServer {
 8265                        project_id,
 8266                        server: Some(proto::LanguageServer {
 8267                            id: server_id.to_proto(),
 8268                            name: status.name.to_string(),
 8269                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8270                        }),
 8271                        capabilities: serde_json::to_string(&server.capabilities())
 8272                            .expect("serializing server LSP capabilities"),
 8273                    })
 8274                    .log_err();
 8275            }
 8276        }
 8277    }
 8278
 8279    pub fn disconnected_from_host(&mut self) {
 8280        self.downstream_client.take();
 8281    }
 8282
 8283    pub fn disconnected_from_ssh_remote(&mut self) {
 8284        if let LspStoreMode::Remote(RemoteLspStore {
 8285            upstream_client, ..
 8286        }) = &mut self.mode
 8287        {
 8288            upstream_client.take();
 8289        }
 8290    }
 8291
 8292    pub(crate) fn set_language_server_statuses_from_proto(
 8293        &mut self,
 8294        project: WeakEntity<Project>,
 8295        language_servers: Vec<proto::LanguageServer>,
 8296        server_capabilities: Vec<String>,
 8297        cx: &mut Context<Self>,
 8298    ) {
 8299        let lsp_logs = cx
 8300            .try_global::<GlobalLogStore>()
 8301            .map(|lsp_store| lsp_store.0.clone());
 8302
 8303        self.language_server_statuses = language_servers
 8304            .into_iter()
 8305            .zip(server_capabilities)
 8306            .map(|(server, server_capabilities)| {
 8307                let server_id = LanguageServerId(server.id as usize);
 8308                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8309                    self.lsp_server_capabilities
 8310                        .insert(server_id, server_capabilities);
 8311                }
 8312
 8313                let name = LanguageServerName::from_proto(server.name);
 8314                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8315
 8316                if let Some(lsp_logs) = &lsp_logs {
 8317                    lsp_logs.update(cx, |lsp_logs, cx| {
 8318                        lsp_logs.add_language_server(
 8319                            // Only remote clients get their language servers set from proto
 8320                            LanguageServerKind::Remote {
 8321                                project: project.clone(),
 8322                            },
 8323                            server_id,
 8324                            Some(name.clone()),
 8325                            worktree,
 8326                            None,
 8327                            cx,
 8328                        );
 8329                    });
 8330                }
 8331
 8332                (
 8333                    server_id,
 8334                    LanguageServerStatus {
 8335                        name,
 8336                        server_version: None,
 8337                        server_readable_version: None,
 8338                        pending_work: Default::default(),
 8339                        has_pending_diagnostic_updates: false,
 8340                        progress_tokens: Default::default(),
 8341                        worktree,
 8342                        binary: None,
 8343                        configuration: None,
 8344                        workspace_folders: BTreeSet::new(),
 8345                        process_id: None,
 8346                    },
 8347                )
 8348            })
 8349            .collect();
 8350    }
 8351
 8352    #[cfg(feature = "test-support")]
 8353    pub fn update_diagnostic_entries(
 8354        &mut self,
 8355        server_id: LanguageServerId,
 8356        abs_path: PathBuf,
 8357        result_id: Option<SharedString>,
 8358        version: Option<i32>,
 8359        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8360        cx: &mut Context<Self>,
 8361    ) -> anyhow::Result<()> {
 8362        self.merge_diagnostic_entries(
 8363            vec![DocumentDiagnosticsUpdate {
 8364                diagnostics: DocumentDiagnostics {
 8365                    diagnostics,
 8366                    document_abs_path: abs_path,
 8367                    version,
 8368                },
 8369                result_id,
 8370                server_id,
 8371                disk_based_sources: Cow::Borrowed(&[]),
 8372                registration_id: None,
 8373            }],
 8374            |_, _, _| false,
 8375            cx,
 8376        )?;
 8377        Ok(())
 8378    }
 8379
 8380    pub fn merge_diagnostic_entries<'a>(
 8381        &mut self,
 8382        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8383        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8384        cx: &mut Context<Self>,
 8385    ) -> anyhow::Result<()> {
 8386        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8387        let mut updated_diagnostics_paths = HashMap::default();
 8388        for mut update in diagnostic_updates {
 8389            let abs_path = &update.diagnostics.document_abs_path;
 8390            let server_id = update.server_id;
 8391            let Some((worktree, relative_path)) =
 8392                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8393            else {
 8394                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8395                return Ok(());
 8396            };
 8397
 8398            let worktree_id = worktree.read(cx).id();
 8399            let project_path = ProjectPath {
 8400                worktree_id,
 8401                path: relative_path,
 8402            };
 8403
 8404            let document_uri = lsp::Uri::from_file_path(abs_path)
 8405                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8406            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8407                let snapshot = buffer_handle.read(cx).snapshot();
 8408                let buffer = buffer_handle.read(cx);
 8409                let reused_diagnostics = buffer
 8410                    .buffer_diagnostics(Some(server_id))
 8411                    .iter()
 8412                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8413                    .map(|v| {
 8414                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8415                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8416                        DiagnosticEntry {
 8417                            range: start..end,
 8418                            diagnostic: v.diagnostic.clone(),
 8419                        }
 8420                    })
 8421                    .collect::<Vec<_>>();
 8422
 8423                self.as_local_mut()
 8424                    .context("cannot merge diagnostics on a remote LspStore")?
 8425                    .update_buffer_diagnostics(
 8426                        &buffer_handle,
 8427                        server_id,
 8428                        Some(update.registration_id),
 8429                        update.result_id,
 8430                        update.diagnostics.version,
 8431                        update.diagnostics.diagnostics.clone(),
 8432                        reused_diagnostics.clone(),
 8433                        cx,
 8434                    )?;
 8435
 8436                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8437            } else if let Some(local) = self.as_local() {
 8438                let reused_diagnostics = local
 8439                    .diagnostics
 8440                    .get(&worktree_id)
 8441                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8442                    .and_then(|diagnostics_by_server_id| {
 8443                        diagnostics_by_server_id
 8444                            .binary_search_by_key(&server_id, |e| e.0)
 8445                            .ok()
 8446                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8447                    })
 8448                    .into_iter()
 8449                    .flatten()
 8450                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8451
 8452                update
 8453                    .diagnostics
 8454                    .diagnostics
 8455                    .extend(reused_diagnostics.cloned());
 8456            }
 8457
 8458            let updated = worktree.update(cx, |worktree, cx| {
 8459                self.update_worktree_diagnostics(
 8460                    worktree.id(),
 8461                    server_id,
 8462                    project_path.path.clone(),
 8463                    update.diagnostics.diagnostics,
 8464                    cx,
 8465                )
 8466            })?;
 8467            match updated {
 8468                ControlFlow::Continue(new_summary) => {
 8469                    if let Some((project_id, new_summary)) = new_summary {
 8470                        match &mut diagnostics_summary {
 8471                            Some(diagnostics_summary) => {
 8472                                diagnostics_summary
 8473                                    .more_summaries
 8474                                    .push(proto::DiagnosticSummary {
 8475                                        path: project_path.path.as_ref().to_proto(),
 8476                                        language_server_id: server_id.0 as u64,
 8477                                        error_count: new_summary.error_count,
 8478                                        warning_count: new_summary.warning_count,
 8479                                    })
 8480                            }
 8481                            None => {
 8482                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8483                                    project_id,
 8484                                    worktree_id: worktree_id.to_proto(),
 8485                                    summary: Some(proto::DiagnosticSummary {
 8486                                        path: project_path.path.as_ref().to_proto(),
 8487                                        language_server_id: server_id.0 as u64,
 8488                                        error_count: new_summary.error_count,
 8489                                        warning_count: new_summary.warning_count,
 8490                                    }),
 8491                                    more_summaries: Vec::new(),
 8492                                })
 8493                            }
 8494                        }
 8495                    }
 8496                    updated_diagnostics_paths
 8497                        .entry(server_id)
 8498                        .or_insert_with(Vec::new)
 8499                        .push(project_path);
 8500                }
 8501                ControlFlow::Break(()) => {}
 8502            }
 8503        }
 8504
 8505        if let Some((diagnostics_summary, (downstream_client, _))) =
 8506            diagnostics_summary.zip(self.downstream_client.as_ref())
 8507        {
 8508            downstream_client.send(diagnostics_summary).log_err();
 8509        }
 8510        for (server_id, paths) in updated_diagnostics_paths {
 8511            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8512        }
 8513        Ok(())
 8514    }
 8515
 8516    fn update_worktree_diagnostics(
 8517        &mut self,
 8518        worktree_id: WorktreeId,
 8519        server_id: LanguageServerId,
 8520        path_in_worktree: Arc<RelPath>,
 8521        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8522        _: &mut Context<Worktree>,
 8523    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8524        let local = match &mut self.mode {
 8525            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8526            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8527        };
 8528
 8529        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8530        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8531        let summaries_by_server_id = summaries_for_tree
 8532            .entry(path_in_worktree.clone())
 8533            .or_default();
 8534
 8535        let old_summary = summaries_by_server_id
 8536            .remove(&server_id)
 8537            .unwrap_or_default();
 8538
 8539        let new_summary = DiagnosticSummary::new(&diagnostics);
 8540        if diagnostics.is_empty() {
 8541            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8542            {
 8543                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8544                    diagnostics_by_server_id.remove(ix);
 8545                }
 8546                if diagnostics_by_server_id.is_empty() {
 8547                    diagnostics_for_tree.remove(&path_in_worktree);
 8548                }
 8549            }
 8550        } else {
 8551            summaries_by_server_id.insert(server_id, new_summary);
 8552            let diagnostics_by_server_id = diagnostics_for_tree
 8553                .entry(path_in_worktree.clone())
 8554                .or_default();
 8555            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8556                Ok(ix) => {
 8557                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8558                }
 8559                Err(ix) => {
 8560                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8561                }
 8562            }
 8563        }
 8564
 8565        if !old_summary.is_empty() || !new_summary.is_empty() {
 8566            if let Some((_, project_id)) = &self.downstream_client {
 8567                Ok(ControlFlow::Continue(Some((
 8568                    *project_id,
 8569                    proto::DiagnosticSummary {
 8570                        path: path_in_worktree.to_proto(),
 8571                        language_server_id: server_id.0 as u64,
 8572                        error_count: new_summary.error_count as u32,
 8573                        warning_count: new_summary.warning_count as u32,
 8574                    },
 8575                ))))
 8576            } else {
 8577                Ok(ControlFlow::Continue(None))
 8578            }
 8579        } else {
 8580            Ok(ControlFlow::Break(()))
 8581        }
 8582    }
 8583
 8584    pub fn open_buffer_for_symbol(
 8585        &mut self,
 8586        symbol: &Symbol,
 8587        cx: &mut Context<Self>,
 8588    ) -> Task<Result<Entity<Buffer>>> {
 8589        if let Some((client, project_id)) = self.upstream_client() {
 8590            let request = client.request(proto::OpenBufferForSymbol {
 8591                project_id,
 8592                symbol: Some(Self::serialize_symbol(symbol)),
 8593            });
 8594            cx.spawn(async move |this, cx| {
 8595                let response = request.await?;
 8596                let buffer_id = BufferId::new(response.buffer_id)?;
 8597                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8598                    .await
 8599            })
 8600        } else if let Some(local) = self.as_local() {
 8601            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8602                seed.worktree_id == symbol.source_worktree_id
 8603                    && state.id == symbol.source_language_server_id
 8604                    && symbol.language_server_name == seed.name
 8605            });
 8606            if !is_valid {
 8607                return Task::ready(Err(anyhow!(
 8608                    "language server for worktree and language not found"
 8609                )));
 8610            };
 8611
 8612            let symbol_abs_path = match &symbol.path {
 8613                SymbolLocation::InProject(project_path) => self
 8614                    .worktree_store
 8615                    .read(cx)
 8616                    .absolutize(&project_path, cx)
 8617                    .context("no such worktree"),
 8618                SymbolLocation::OutsideProject {
 8619                    abs_path,
 8620                    signature: _,
 8621                } => Ok(abs_path.to_path_buf()),
 8622            };
 8623            let symbol_abs_path = match symbol_abs_path {
 8624                Ok(abs_path) => abs_path,
 8625                Err(err) => return Task::ready(Err(err)),
 8626            };
 8627            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8628                uri
 8629            } else {
 8630                return Task::ready(Err(anyhow!("invalid symbol path")));
 8631            };
 8632
 8633            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8634        } else {
 8635            Task::ready(Err(anyhow!("no upstream client or local store")))
 8636        }
 8637    }
 8638
 8639    pub(crate) fn open_local_buffer_via_lsp(
 8640        &mut self,
 8641        abs_path: lsp::Uri,
 8642        language_server_id: LanguageServerId,
 8643        cx: &mut Context<Self>,
 8644    ) -> Task<Result<Entity<Buffer>>> {
 8645        let path_style = self.worktree_store.read(cx).path_style();
 8646        cx.spawn(async move |lsp_store, cx| {
 8647            // Escape percent-encoded string.
 8648            let current_scheme = abs_path.scheme().to_owned();
 8649            // Uri is immutable, so we can't modify the scheme
 8650
 8651            let abs_path = abs_path
 8652                .to_file_path_ext(path_style)
 8653                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8654            let p = abs_path.clone();
 8655            let yarn_worktree = lsp_store
 8656                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8657                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8658                        cx.spawn(async move |this, cx| {
 8659                            let t = this
 8660                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8661                                .ok()?;
 8662                            t.await
 8663                        })
 8664                    }),
 8665                    None => Task::ready(None),
 8666                })?
 8667                .await;
 8668            let (worktree_root_target, known_relative_path) =
 8669                if let Some((zip_root, relative_path)) = yarn_worktree {
 8670                    (zip_root, Some(relative_path))
 8671                } else {
 8672                    (Arc::<Path>::from(abs_path.as_path()), None)
 8673                };
 8674            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8675                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8676                    worktree_store.find_worktree(&worktree_root_target, cx)
 8677                })
 8678            })?;
 8679            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8680                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8681                (result.0, relative_path, None)
 8682            } else {
 8683                let worktree = lsp_store
 8684                    .update(cx, |lsp_store, cx| {
 8685                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8686                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8687                        })
 8688                    })?
 8689                    .await?;
 8690                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8691                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8692                    lsp_store
 8693                        .update(cx, |lsp_store, cx| {
 8694                            if let Some(local) = lsp_store.as_local_mut() {
 8695                                local.register_language_server_for_invisible_worktree(
 8696                                    &worktree,
 8697                                    language_server_id,
 8698                                    cx,
 8699                                )
 8700                            }
 8701                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8702                                Some(status) => status.worktree,
 8703                                None => None,
 8704                            }
 8705                        })
 8706                        .ok()
 8707                        .flatten()
 8708                        .zip(Some(worktree_root.clone()))
 8709                } else {
 8710                    None
 8711                };
 8712                let relative_path = if let Some(known_path) = known_relative_path {
 8713                    known_path
 8714                } else {
 8715                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8716                        .into_arc()
 8717                };
 8718                (worktree, relative_path, source_ws)
 8719            };
 8720            let project_path = ProjectPath {
 8721                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8722                path: relative_path,
 8723            };
 8724            let buffer = lsp_store
 8725                .update(cx, |lsp_store, cx| {
 8726                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8727                        buffer_store.open_buffer(project_path, cx)
 8728                    })
 8729                })?
 8730                .await?;
 8731            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8732            if let Some((source_ws, worktree_root)) = source_ws {
 8733                buffer.update(cx, |buffer, cx| {
 8734                    let settings = WorktreeSettings::get(
 8735                        Some(
 8736                            (&ProjectPath {
 8737                                worktree_id: source_ws,
 8738                                path: Arc::from(RelPath::empty()),
 8739                            })
 8740                                .into(),
 8741                        ),
 8742                        cx,
 8743                    );
 8744                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8745                    if is_read_only {
 8746                        buffer.set_capability(Capability::ReadOnly, cx);
 8747                    }
 8748                });
 8749            }
 8750            Ok(buffer)
 8751        })
 8752    }
 8753
 8754    fn local_lsp_servers_for_buffer(
 8755        &self,
 8756        buffer: &Entity<Buffer>,
 8757        cx: &mut Context<Self>,
 8758    ) -> Vec<LanguageServerId> {
 8759        let Some(local) = self.as_local() else {
 8760            return Vec::new();
 8761        };
 8762
 8763        let snapshot = buffer.read(cx).snapshot();
 8764
 8765        buffer.update(cx, |buffer, cx| {
 8766            local
 8767                .language_servers_for_buffer(buffer, cx)
 8768                .map(|(_, server)| server.server_id())
 8769                .filter(|server_id| {
 8770                    self.as_local().is_none_or(|local| {
 8771                        local
 8772                            .buffers_opened_in_servers
 8773                            .get(&snapshot.remote_id())
 8774                            .is_some_and(|servers| servers.contains(server_id))
 8775                    })
 8776                })
 8777                .collect()
 8778        })
 8779    }
 8780
 8781    fn request_multiple_lsp_locally<P, R>(
 8782        &mut self,
 8783        buffer: &Entity<Buffer>,
 8784        position: Option<P>,
 8785        request: R,
 8786        cx: &mut Context<Self>,
 8787    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8788    where
 8789        P: ToOffset,
 8790        R: LspCommand + Clone,
 8791        <R::LspRequest as lsp::request::Request>::Result: Send,
 8792        <R::LspRequest as lsp::request::Request>::Params: Send,
 8793    {
 8794        let Some(local) = self.as_local() else {
 8795            return Task::ready(Vec::new());
 8796        };
 8797
 8798        let snapshot = buffer.read(cx).snapshot();
 8799        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8800
 8801        let server_ids = buffer.update(cx, |buffer, cx| {
 8802            local
 8803                .language_servers_for_buffer(buffer, cx)
 8804                .filter(|(adapter, _)| {
 8805                    scope
 8806                        .as_ref()
 8807                        .map(|scope| scope.language_allowed(&adapter.name))
 8808                        .unwrap_or(true)
 8809                })
 8810                .map(|(_, server)| server.server_id())
 8811                .filter(|server_id| {
 8812                    self.as_local().is_none_or(|local| {
 8813                        local
 8814                            .buffers_opened_in_servers
 8815                            .get(&snapshot.remote_id())
 8816                            .is_some_and(|servers| servers.contains(server_id))
 8817                    })
 8818                })
 8819                .collect::<Vec<_>>()
 8820        });
 8821
 8822        let mut response_results = server_ids
 8823            .into_iter()
 8824            .map(|server_id| {
 8825                let task = self.request_lsp(
 8826                    buffer.clone(),
 8827                    LanguageServerToQuery::Other(server_id),
 8828                    request.clone(),
 8829                    cx,
 8830                );
 8831                async move { (server_id, task.await) }
 8832            })
 8833            .collect::<FuturesUnordered<_>>();
 8834
 8835        cx.background_spawn(async move {
 8836            let mut responses = Vec::with_capacity(response_results.len());
 8837            while let Some((server_id, response_result)) = response_results.next().await {
 8838                match response_result {
 8839                    Ok(response) => responses.push((server_id, response)),
 8840                    // rust-analyzer likes to error with this when its still loading up
 8841                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8842                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8843                }
 8844            }
 8845            responses
 8846        })
 8847    }
 8848
 8849    async fn handle_lsp_get_completions(
 8850        this: Entity<Self>,
 8851        envelope: TypedEnvelope<proto::GetCompletions>,
 8852        mut cx: AsyncApp,
 8853    ) -> Result<proto::GetCompletionsResponse> {
 8854        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8855
 8856        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8857        let buffer_handle = this.update(&mut cx, |this, cx| {
 8858            this.buffer_store.read(cx).get_existing(buffer_id)
 8859        })?;
 8860        let request = GetCompletions::from_proto(
 8861            envelope.payload,
 8862            this.clone(),
 8863            buffer_handle.clone(),
 8864            cx.clone(),
 8865        )
 8866        .await?;
 8867
 8868        let server_to_query = match request.server_id {
 8869            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8870            None => LanguageServerToQuery::FirstCapable,
 8871        };
 8872
 8873        let response = this
 8874            .update(&mut cx, |this, cx| {
 8875                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8876            })
 8877            .await?;
 8878        this.update(&mut cx, |this, cx| {
 8879            Ok(GetCompletions::response_to_proto(
 8880                response,
 8881                this,
 8882                sender_id,
 8883                &buffer_handle.read(cx).version(),
 8884                cx,
 8885            ))
 8886        })
 8887    }
 8888
 8889    async fn handle_lsp_command<T: LspCommand>(
 8890        this: Entity<Self>,
 8891        envelope: TypedEnvelope<T::ProtoRequest>,
 8892        mut cx: AsyncApp,
 8893    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8894    where
 8895        <T::LspRequest as lsp::request::Request>::Params: Send,
 8896        <T::LspRequest as lsp::request::Request>::Result: Send,
 8897    {
 8898        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8899        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8900        let buffer_handle = this.update(&mut cx, |this, cx| {
 8901            this.buffer_store.read(cx).get_existing(buffer_id)
 8902        })?;
 8903        let request = T::from_proto(
 8904            envelope.payload,
 8905            this.clone(),
 8906            buffer_handle.clone(),
 8907            cx.clone(),
 8908        )
 8909        .await?;
 8910        let response = this
 8911            .update(&mut cx, |this, cx| {
 8912                this.request_lsp(
 8913                    buffer_handle.clone(),
 8914                    LanguageServerToQuery::FirstCapable,
 8915                    request,
 8916                    cx,
 8917                )
 8918            })
 8919            .await?;
 8920        this.update(&mut cx, |this, cx| {
 8921            Ok(T::response_to_proto(
 8922                response,
 8923                this,
 8924                sender_id,
 8925                &buffer_handle.read(cx).version(),
 8926                cx,
 8927            ))
 8928        })
 8929    }
 8930
 8931    async fn handle_lsp_query(
 8932        lsp_store: Entity<Self>,
 8933        envelope: TypedEnvelope<proto::LspQuery>,
 8934        mut cx: AsyncApp,
 8935    ) -> Result<proto::Ack> {
 8936        use proto::lsp_query::Request;
 8937        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8938        let lsp_query = envelope.payload;
 8939        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8940        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8941        match lsp_query.request.context("invalid LSP query request")? {
 8942            Request::GetReferences(get_references) => {
 8943                let position = get_references.position.clone().and_then(deserialize_anchor);
 8944                Self::query_lsp_locally::<GetReferences>(
 8945                    lsp_store,
 8946                    server_id,
 8947                    sender_id,
 8948                    lsp_request_id,
 8949                    get_references,
 8950                    position,
 8951                    &mut cx,
 8952                )
 8953                .await?;
 8954            }
 8955            Request::GetDocumentColor(get_document_color) => {
 8956                Self::query_lsp_locally::<GetDocumentColor>(
 8957                    lsp_store,
 8958                    server_id,
 8959                    sender_id,
 8960                    lsp_request_id,
 8961                    get_document_color,
 8962                    None,
 8963                    &mut cx,
 8964                )
 8965                .await?;
 8966            }
 8967            Request::GetFoldingRanges(get_folding_ranges) => {
 8968                Self::query_lsp_locally::<GetFoldingRanges>(
 8969                    lsp_store,
 8970                    server_id,
 8971                    sender_id,
 8972                    lsp_request_id,
 8973                    get_folding_ranges,
 8974                    None,
 8975                    &mut cx,
 8976                )
 8977                .await?;
 8978            }
 8979            Request::GetDocumentSymbols(get_document_symbols) => {
 8980                Self::query_lsp_locally::<GetDocumentSymbols>(
 8981                    lsp_store,
 8982                    server_id,
 8983                    sender_id,
 8984                    lsp_request_id,
 8985                    get_document_symbols,
 8986                    None,
 8987                    &mut cx,
 8988                )
 8989                .await?;
 8990            }
 8991            Request::GetHover(get_hover) => {
 8992                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8993                Self::query_lsp_locally::<GetHover>(
 8994                    lsp_store,
 8995                    server_id,
 8996                    sender_id,
 8997                    lsp_request_id,
 8998                    get_hover,
 8999                    position,
 9000                    &mut cx,
 9001                )
 9002                .await?;
 9003            }
 9004            Request::GetCodeActions(get_code_actions) => {
 9005                Self::query_lsp_locally::<GetCodeActions>(
 9006                    lsp_store,
 9007                    server_id,
 9008                    sender_id,
 9009                    lsp_request_id,
 9010                    get_code_actions,
 9011                    None,
 9012                    &mut cx,
 9013                )
 9014                .await?;
 9015            }
 9016            Request::GetSignatureHelp(get_signature_help) => {
 9017                let position = get_signature_help
 9018                    .position
 9019                    .clone()
 9020                    .and_then(deserialize_anchor);
 9021                Self::query_lsp_locally::<GetSignatureHelp>(
 9022                    lsp_store,
 9023                    server_id,
 9024                    sender_id,
 9025                    lsp_request_id,
 9026                    get_signature_help,
 9027                    position,
 9028                    &mut cx,
 9029                )
 9030                .await?;
 9031            }
 9032            Request::GetCodeLens(get_code_lens) => {
 9033                Self::query_lsp_locally::<GetCodeLens>(
 9034                    lsp_store,
 9035                    server_id,
 9036                    sender_id,
 9037                    lsp_request_id,
 9038                    get_code_lens,
 9039                    None,
 9040                    &mut cx,
 9041                )
 9042                .await?;
 9043            }
 9044            Request::GetDefinition(get_definition) => {
 9045                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9046                Self::query_lsp_locally::<GetDefinitions>(
 9047                    lsp_store,
 9048                    server_id,
 9049                    sender_id,
 9050                    lsp_request_id,
 9051                    get_definition,
 9052                    position,
 9053                    &mut cx,
 9054                )
 9055                .await?;
 9056            }
 9057            Request::GetDeclaration(get_declaration) => {
 9058                let position = get_declaration
 9059                    .position
 9060                    .clone()
 9061                    .and_then(deserialize_anchor);
 9062                Self::query_lsp_locally::<GetDeclarations>(
 9063                    lsp_store,
 9064                    server_id,
 9065                    sender_id,
 9066                    lsp_request_id,
 9067                    get_declaration,
 9068                    position,
 9069                    &mut cx,
 9070                )
 9071                .await?;
 9072            }
 9073            Request::GetTypeDefinition(get_type_definition) => {
 9074                let position = get_type_definition
 9075                    .position
 9076                    .clone()
 9077                    .and_then(deserialize_anchor);
 9078                Self::query_lsp_locally::<GetTypeDefinitions>(
 9079                    lsp_store,
 9080                    server_id,
 9081                    sender_id,
 9082                    lsp_request_id,
 9083                    get_type_definition,
 9084                    position,
 9085                    &mut cx,
 9086                )
 9087                .await?;
 9088            }
 9089            Request::GetImplementation(get_implementation) => {
 9090                let position = get_implementation
 9091                    .position
 9092                    .clone()
 9093                    .and_then(deserialize_anchor);
 9094                Self::query_lsp_locally::<GetImplementations>(
 9095                    lsp_store,
 9096                    server_id,
 9097                    sender_id,
 9098                    lsp_request_id,
 9099                    get_implementation,
 9100                    position,
 9101                    &mut cx,
 9102                )
 9103                .await?;
 9104            }
 9105            Request::InlayHints(inlay_hints) => {
 9106                let query_start = inlay_hints
 9107                    .start
 9108                    .clone()
 9109                    .and_then(deserialize_anchor)
 9110                    .context("invalid inlay hints range start")?;
 9111                let query_end = inlay_hints
 9112                    .end
 9113                    .clone()
 9114                    .and_then(deserialize_anchor)
 9115                    .context("invalid inlay hints range end")?;
 9116                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9117                    &lsp_store,
 9118                    server_id,
 9119                    lsp_request_id,
 9120                    &inlay_hints,
 9121                    query_start..query_end,
 9122                    &mut cx,
 9123                )
 9124                .await
 9125                .context("preparing inlay hints request")?;
 9126                Self::query_lsp_locally::<InlayHints>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    inlay_hints,
 9132                    None,
 9133                    &mut cx,
 9134                )
 9135                .await
 9136                .context("querying for inlay hints")?
 9137            }
 9138            //////////////////////////////
 9139            // Below are LSP queries that need to fetch more data,
 9140            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9141            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9142                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9143                    &lsp_store,
 9144                    &get_document_diagnostics,
 9145                    &mut cx,
 9146                )
 9147                .await?;
 9148                lsp_store.update(&mut cx, |lsp_store, cx| {
 9149                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9150                    let key = LspKey {
 9151                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9152                        server_queried: server_id,
 9153                    };
 9154                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9155                    ) {
 9156                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9157                            lsp_requests.clear();
 9158                        };
 9159                    }
 9160
 9161                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9162                        lsp_request_id,
 9163                        cx.spawn(async move |lsp_store, cx| {
 9164                            let diagnostics_pull = lsp_store
 9165                                .update(cx, |lsp_store, cx| {
 9166                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9167                                })
 9168                                .ok();
 9169                            if let Some(diagnostics_pull) = diagnostics_pull {
 9170                                match diagnostics_pull.await {
 9171                                    Ok(()) => {}
 9172                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9173                                };
 9174                            }
 9175                        }),
 9176                    );
 9177                });
 9178            }
 9179            Request::SemanticTokens(semantic_tokens) => {
 9180                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9181                    &lsp_store,
 9182                    &semantic_tokens,
 9183                    &mut cx,
 9184                )
 9185                .await?;
 9186                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9187                lsp_store.update(&mut cx, |lsp_store, cx| {
 9188                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9189                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9190                        let key = LspKey {
 9191                            request_type: TypeId::of::<SemanticTokensFull>(),
 9192                            server_queried: server_id,
 9193                        };
 9194                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9195                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9196                                lsp_requests.clear();
 9197                            };
 9198                        }
 9199
 9200                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9201                            lsp_request_id,
 9202                            cx.spawn(async move |lsp_store, cx| {
 9203                                let tokens_fetch = lsp_store
 9204                                    .update(cx, |lsp_store, cx| {
 9205                                        lsp_store
 9206                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9207                                    })
 9208                                    .ok();
 9209                                if let Some(tokens_fetch) = tokens_fetch {
 9210                                    let new_tokens = tokens_fetch.await;
 9211                                    if let Some(new_tokens) = new_tokens {
 9212                                        lsp_store
 9213                                            .update(cx, |lsp_store, cx| {
 9214                                                let response = new_tokens
 9215                                                    .into_iter()
 9216                                                    .map(|(server_id, response)| {
 9217                                                        (
 9218                                                            server_id.to_proto(),
 9219                                                            SemanticTokensFull::response_to_proto(
 9220                                                                response,
 9221                                                                lsp_store,
 9222                                                                sender_id,
 9223                                                                &buffer_version,
 9224                                                                cx,
 9225                                                            ),
 9226                                                        )
 9227                                                    })
 9228                                                    .collect::<HashMap<_, _>>();
 9229                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9230                                                    project_id,
 9231                                                    lsp_request_id,
 9232                                                    response,
 9233                                                ) {
 9234                                                    Ok(()) => {}
 9235                                                    Err(e) => {
 9236                                                        log::error!(
 9237                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9238                                                        )
 9239                                                    }
 9240                                                }
 9241                                            })
 9242                                            .ok();
 9243                                    }
 9244                                }
 9245                            }),
 9246                        );
 9247                    }
 9248                });
 9249            }
 9250        }
 9251        Ok(proto::Ack {})
 9252    }
 9253
 9254    async fn handle_lsp_query_response(
 9255        lsp_store: Entity<Self>,
 9256        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9257        cx: AsyncApp,
 9258    ) -> Result<()> {
 9259        lsp_store.read_with(&cx, |lsp_store, _| {
 9260            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9261                upstream_client.handle_lsp_response(envelope.clone());
 9262            }
 9263        });
 9264        Ok(())
 9265    }
 9266
 9267    async fn handle_apply_code_action(
 9268        this: Entity<Self>,
 9269        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9270        mut cx: AsyncApp,
 9271    ) -> Result<proto::ApplyCodeActionResponse> {
 9272        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9273        let action =
 9274            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9275        let apply_code_action = this.update(&mut cx, |this, cx| {
 9276            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9277            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9278            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9279        })?;
 9280
 9281        let project_transaction = apply_code_action.await?;
 9282        let project_transaction = this.update(&mut cx, |this, cx| {
 9283            this.buffer_store.update(cx, |buffer_store, cx| {
 9284                buffer_store.serialize_project_transaction_for_peer(
 9285                    project_transaction,
 9286                    sender_id,
 9287                    cx,
 9288                )
 9289            })
 9290        });
 9291        Ok(proto::ApplyCodeActionResponse {
 9292            transaction: Some(project_transaction),
 9293        })
 9294    }
 9295
 9296    async fn handle_register_buffer_with_language_servers(
 9297        this: Entity<Self>,
 9298        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9299        mut cx: AsyncApp,
 9300    ) -> Result<proto::Ack> {
 9301        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9302        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9303        this.update(&mut cx, |this, cx| {
 9304            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9305                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9306                    project_id: upstream_project_id,
 9307                    buffer_id: buffer_id.to_proto(),
 9308                    only_servers: envelope.payload.only_servers,
 9309                });
 9310            }
 9311
 9312            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9313                anyhow::bail!("buffer is not open");
 9314            };
 9315
 9316            let handle = this.register_buffer_with_language_servers(
 9317                &buffer,
 9318                envelope
 9319                    .payload
 9320                    .only_servers
 9321                    .into_iter()
 9322                    .filter_map(|selector| {
 9323                        Some(match selector.selector? {
 9324                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9325                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9326                            }
 9327                            proto::language_server_selector::Selector::Name(name) => {
 9328                                LanguageServerSelector::Name(LanguageServerName(
 9329                                    SharedString::from(name),
 9330                                ))
 9331                            }
 9332                        })
 9333                    })
 9334                    .collect(),
 9335                false,
 9336                cx,
 9337            );
 9338            // Pull diagnostics for the buffer even if it was already registered.
 9339            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9340            // but it's unclear if we need it.
 9341            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9342                .detach();
 9343            this.buffer_store().update(cx, |buffer_store, _| {
 9344                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9345            });
 9346
 9347            Ok(())
 9348        })?;
 9349        Ok(proto::Ack {})
 9350    }
 9351
 9352    async fn handle_rename_project_entry(
 9353        this: Entity<Self>,
 9354        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9355        mut cx: AsyncApp,
 9356    ) -> Result<proto::ProjectEntryResponse> {
 9357        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9358        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9359        let new_path =
 9360            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9361
 9362        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9363            .update(&mut cx, |this, cx| {
 9364                let (worktree, entry) = this
 9365                    .worktree_store
 9366                    .read(cx)
 9367                    .worktree_and_entry_for_id(entry_id, cx)?;
 9368                let new_worktree = this
 9369                    .worktree_store
 9370                    .read(cx)
 9371                    .worktree_for_id(new_worktree_id, cx)?;
 9372                Some((
 9373                    this.worktree_store.clone(),
 9374                    worktree,
 9375                    new_worktree,
 9376                    entry.clone(),
 9377                ))
 9378            })
 9379            .context("worktree not found")?;
 9380        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9381            (worktree.absolutize(&old_entry.path), worktree.id())
 9382        });
 9383        let new_abs_path =
 9384            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9385
 9386        let _transaction = Self::will_rename_entry(
 9387            this.downgrade(),
 9388            old_worktree_id,
 9389            &old_abs_path,
 9390            &new_abs_path,
 9391            old_entry.is_dir(),
 9392            cx.clone(),
 9393        )
 9394        .await;
 9395        let response = WorktreeStore::handle_rename_project_entry(
 9396            worktree_store,
 9397            envelope.payload,
 9398            cx.clone(),
 9399        )
 9400        .await;
 9401        this.read_with(&cx, |this, _| {
 9402            this.did_rename_entry(
 9403                old_worktree_id,
 9404                &old_abs_path,
 9405                &new_abs_path,
 9406                old_entry.is_dir(),
 9407            );
 9408        });
 9409        response
 9410    }
 9411
 9412    async fn handle_update_diagnostic_summary(
 9413        this: Entity<Self>,
 9414        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9415        mut cx: AsyncApp,
 9416    ) -> Result<()> {
 9417        this.update(&mut cx, |lsp_store, cx| {
 9418            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9419            let mut updated_diagnostics_paths = HashMap::default();
 9420            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9421            for message_summary in envelope
 9422                .payload
 9423                .summary
 9424                .into_iter()
 9425                .chain(envelope.payload.more_summaries)
 9426            {
 9427                let project_path = ProjectPath {
 9428                    worktree_id,
 9429                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9430                };
 9431                let path = project_path.path.clone();
 9432                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9433                let summary = DiagnosticSummary {
 9434                    error_count: message_summary.error_count as usize,
 9435                    warning_count: message_summary.warning_count as usize,
 9436                };
 9437
 9438                if summary.is_empty() {
 9439                    if let Some(worktree_summaries) =
 9440                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9441                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9442                    {
 9443                        summaries.remove(&server_id);
 9444                        if summaries.is_empty() {
 9445                            worktree_summaries.remove(&path);
 9446                        }
 9447                    }
 9448                } else {
 9449                    lsp_store
 9450                        .diagnostic_summaries
 9451                        .entry(worktree_id)
 9452                        .or_default()
 9453                        .entry(path)
 9454                        .or_default()
 9455                        .insert(server_id, summary);
 9456                }
 9457
 9458                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9459                    match &mut diagnostics_summary {
 9460                        Some(diagnostics_summary) => {
 9461                            diagnostics_summary
 9462                                .more_summaries
 9463                                .push(proto::DiagnosticSummary {
 9464                                    path: project_path.path.as_ref().to_proto(),
 9465                                    language_server_id: server_id.0 as u64,
 9466                                    error_count: summary.error_count as u32,
 9467                                    warning_count: summary.warning_count as u32,
 9468                                })
 9469                        }
 9470                        None => {
 9471                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9472                                project_id: *project_id,
 9473                                worktree_id: worktree_id.to_proto(),
 9474                                summary: Some(proto::DiagnosticSummary {
 9475                                    path: project_path.path.as_ref().to_proto(),
 9476                                    language_server_id: server_id.0 as u64,
 9477                                    error_count: summary.error_count as u32,
 9478                                    warning_count: summary.warning_count as u32,
 9479                                }),
 9480                                more_summaries: Vec::new(),
 9481                            })
 9482                        }
 9483                    }
 9484                }
 9485                updated_diagnostics_paths
 9486                    .entry(server_id)
 9487                    .or_insert_with(Vec::new)
 9488                    .push(project_path);
 9489            }
 9490
 9491            if let Some((diagnostics_summary, (downstream_client, _))) =
 9492                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9493            {
 9494                downstream_client.send(diagnostics_summary).log_err();
 9495            }
 9496            for (server_id, paths) in updated_diagnostics_paths {
 9497                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9498            }
 9499            Ok(())
 9500        })
 9501    }
 9502
 9503    async fn handle_start_language_server(
 9504        lsp_store: Entity<Self>,
 9505        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9506        mut cx: AsyncApp,
 9507    ) -> Result<()> {
 9508        let server = envelope.payload.server.context("invalid server")?;
 9509        let server_capabilities =
 9510            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9511                .with_context(|| {
 9512                    format!(
 9513                        "incorrect server capabilities {}",
 9514                        envelope.payload.capabilities
 9515                    )
 9516                })?;
 9517        lsp_store.update(&mut cx, |lsp_store, cx| {
 9518            let server_id = LanguageServerId(server.id as usize);
 9519            let server_name = LanguageServerName::from_proto(server.name.clone());
 9520            lsp_store
 9521                .lsp_server_capabilities
 9522                .insert(server_id, server_capabilities);
 9523            lsp_store.language_server_statuses.insert(
 9524                server_id,
 9525                LanguageServerStatus {
 9526                    name: server_name.clone(),
 9527                    server_version: None,
 9528                    server_readable_version: None,
 9529                    pending_work: Default::default(),
 9530                    has_pending_diagnostic_updates: false,
 9531                    progress_tokens: Default::default(),
 9532                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9533                    binary: None,
 9534                    configuration: None,
 9535                    workspace_folders: BTreeSet::new(),
 9536                    process_id: None,
 9537                },
 9538            );
 9539            cx.emit(LspStoreEvent::LanguageServerAdded(
 9540                server_id,
 9541                server_name,
 9542                server.worktree_id.map(WorktreeId::from_proto),
 9543            ));
 9544            cx.notify();
 9545        });
 9546        Ok(())
 9547    }
 9548
 9549    async fn handle_update_language_server(
 9550        lsp_store: Entity<Self>,
 9551        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9552        mut cx: AsyncApp,
 9553    ) -> Result<()> {
 9554        lsp_store.update(&mut cx, |lsp_store, cx| {
 9555            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9556
 9557            match envelope.payload.variant.context("invalid variant")? {
 9558                proto::update_language_server::Variant::WorkStart(payload) => {
 9559                    lsp_store.on_lsp_work_start(
 9560                        language_server_id,
 9561                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9562                            .context("invalid progress token value")?,
 9563                        LanguageServerProgress {
 9564                            title: payload.title,
 9565                            is_disk_based_diagnostics_progress: false,
 9566                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9567                            message: payload.message,
 9568                            percentage: payload.percentage.map(|p| p as usize),
 9569                            last_update_at: cx.background_executor().now(),
 9570                        },
 9571                        cx,
 9572                    );
 9573                }
 9574                proto::update_language_server::Variant::WorkProgress(payload) => {
 9575                    lsp_store.on_lsp_work_progress(
 9576                        language_server_id,
 9577                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9578                            .context("invalid progress token value")?,
 9579                        LanguageServerProgress {
 9580                            title: None,
 9581                            is_disk_based_diagnostics_progress: false,
 9582                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9583                            message: payload.message,
 9584                            percentage: payload.percentage.map(|p| p as usize),
 9585                            last_update_at: cx.background_executor().now(),
 9586                        },
 9587                        cx,
 9588                    );
 9589                }
 9590
 9591                proto::update_language_server::Variant::WorkEnd(payload) => {
 9592                    lsp_store.on_lsp_work_end(
 9593                        language_server_id,
 9594                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9595                            .context("invalid progress token value")?,
 9596                        cx,
 9597                    );
 9598                }
 9599
 9600                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9601                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9602                }
 9603
 9604                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9605                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9606                }
 9607
 9608                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9609                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9610                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9611                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9612                        language_server_id,
 9613                        name: envelope
 9614                            .payload
 9615                            .server_name
 9616                            .map(SharedString::new)
 9617                            .map(LanguageServerName),
 9618                        message: non_lsp,
 9619                    });
 9620                }
 9621            }
 9622
 9623            Ok(())
 9624        })
 9625    }
 9626
 9627    async fn handle_language_server_log(
 9628        this: Entity<Self>,
 9629        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9630        mut cx: AsyncApp,
 9631    ) -> Result<()> {
 9632        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9633        let log_type = envelope
 9634            .payload
 9635            .log_type
 9636            .map(LanguageServerLogType::from_proto)
 9637            .context("invalid language server log type")?;
 9638
 9639        let message = envelope.payload.message;
 9640
 9641        this.update(&mut cx, |_, cx| {
 9642            cx.emit(LspStoreEvent::LanguageServerLog(
 9643                language_server_id,
 9644                log_type,
 9645                message,
 9646            ));
 9647        });
 9648        Ok(())
 9649    }
 9650
 9651    async fn handle_lsp_ext_cancel_flycheck(
 9652        lsp_store: Entity<Self>,
 9653        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9654        cx: AsyncApp,
 9655    ) -> Result<proto::Ack> {
 9656        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9657        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9658            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9659                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9660            } else {
 9661                None
 9662            }
 9663        });
 9664        if let Some(task) = task {
 9665            task.context("handling lsp ext cancel flycheck")?;
 9666        }
 9667
 9668        Ok(proto::Ack {})
 9669    }
 9670
 9671    async fn handle_lsp_ext_run_flycheck(
 9672        lsp_store: Entity<Self>,
 9673        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9674        mut cx: AsyncApp,
 9675    ) -> Result<proto::Ack> {
 9676        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9677        lsp_store.update(&mut cx, |lsp_store, cx| {
 9678            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9679                let text_document = if envelope.payload.current_file_only {
 9680                    let buffer_id = envelope
 9681                        .payload
 9682                        .buffer_id
 9683                        .map(|id| BufferId::new(id))
 9684                        .transpose()?;
 9685                    buffer_id
 9686                        .and_then(|buffer_id| {
 9687                            lsp_store
 9688                                .buffer_store()
 9689                                .read(cx)
 9690                                .get(buffer_id)
 9691                                .and_then(|buffer| {
 9692                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9693                                })
 9694                                .map(|path| make_text_document_identifier(&path))
 9695                        })
 9696                        .transpose()?
 9697                } else {
 9698                    None
 9699                };
 9700                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9701                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9702                )?;
 9703            }
 9704            anyhow::Ok(())
 9705        })?;
 9706
 9707        Ok(proto::Ack {})
 9708    }
 9709
 9710    async fn handle_lsp_ext_clear_flycheck(
 9711        lsp_store: Entity<Self>,
 9712        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9713        cx: AsyncApp,
 9714    ) -> Result<proto::Ack> {
 9715        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9716        lsp_store.read_with(&cx, |lsp_store, _| {
 9717            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9718                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9719            } else {
 9720                None
 9721            }
 9722        });
 9723
 9724        Ok(proto::Ack {})
 9725    }
 9726
 9727    pub fn disk_based_diagnostics_started(
 9728        &mut self,
 9729        language_server_id: LanguageServerId,
 9730        cx: &mut Context<Self>,
 9731    ) {
 9732        if let Some(language_server_status) =
 9733            self.language_server_statuses.get_mut(&language_server_id)
 9734        {
 9735            language_server_status.has_pending_diagnostic_updates = true;
 9736        }
 9737
 9738        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9739        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9740            language_server_id,
 9741            name: self
 9742                .language_server_adapter_for_id(language_server_id)
 9743                .map(|adapter| adapter.name()),
 9744            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9745                Default::default(),
 9746            ),
 9747        })
 9748    }
 9749
 9750    pub fn disk_based_diagnostics_finished(
 9751        &mut self,
 9752        language_server_id: LanguageServerId,
 9753        cx: &mut Context<Self>,
 9754    ) {
 9755        if let Some(language_server_status) =
 9756            self.language_server_statuses.get_mut(&language_server_id)
 9757        {
 9758            language_server_status.has_pending_diagnostic_updates = false;
 9759        }
 9760
 9761        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9762        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9763            language_server_id,
 9764            name: self
 9765                .language_server_adapter_for_id(language_server_id)
 9766                .map(|adapter| adapter.name()),
 9767            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9768                Default::default(),
 9769            ),
 9770        })
 9771    }
 9772
 9773    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9774    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9775    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9776    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9777    // the language server might take some time to publish diagnostics.
 9778    fn simulate_disk_based_diagnostics_events_if_needed(
 9779        &mut self,
 9780        language_server_id: LanguageServerId,
 9781        cx: &mut Context<Self>,
 9782    ) {
 9783        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9784
 9785        let Some(LanguageServerState::Running {
 9786            simulate_disk_based_diagnostics_completion,
 9787            adapter,
 9788            ..
 9789        }) = self
 9790            .as_local_mut()
 9791            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9792        else {
 9793            return;
 9794        };
 9795
 9796        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9797            return;
 9798        }
 9799
 9800        let prev_task =
 9801            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9802                cx.background_executor()
 9803                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9804                    .await;
 9805
 9806                this.update(cx, |this, cx| {
 9807                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9808
 9809                    if let Some(LanguageServerState::Running {
 9810                        simulate_disk_based_diagnostics_completion,
 9811                        ..
 9812                    }) = this.as_local_mut().and_then(|local_store| {
 9813                        local_store.language_servers.get_mut(&language_server_id)
 9814                    }) {
 9815                        *simulate_disk_based_diagnostics_completion = None;
 9816                    }
 9817                })
 9818                .ok();
 9819            }));
 9820
 9821        if prev_task.is_none() {
 9822            self.disk_based_diagnostics_started(language_server_id, cx);
 9823        }
 9824    }
 9825
 9826    pub fn language_server_statuses(
 9827        &self,
 9828    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9829        self.language_server_statuses
 9830            .iter()
 9831            .map(|(key, value)| (*key, value))
 9832    }
 9833
 9834    pub(super) fn did_rename_entry(
 9835        &self,
 9836        worktree_id: WorktreeId,
 9837        old_path: &Path,
 9838        new_path: &Path,
 9839        is_dir: bool,
 9840    ) {
 9841        maybe!({
 9842            let local_store = self.as_local()?;
 9843
 9844            let old_uri = lsp::Uri::from_file_path(old_path)
 9845                .ok()
 9846                .map(|uri| uri.to_string())?;
 9847            let new_uri = lsp::Uri::from_file_path(new_path)
 9848                .ok()
 9849                .map(|uri| uri.to_string())?;
 9850
 9851            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9852                let Some(filter) = local_store
 9853                    .language_server_paths_watched_for_rename
 9854                    .get(&language_server.server_id())
 9855                else {
 9856                    continue;
 9857                };
 9858
 9859                if filter.should_send_did_rename(&old_uri, is_dir) {
 9860                    language_server
 9861                        .notify::<DidRenameFiles>(RenameFilesParams {
 9862                            files: vec![FileRename {
 9863                                old_uri: old_uri.clone(),
 9864                                new_uri: new_uri.clone(),
 9865                            }],
 9866                        })
 9867                        .ok();
 9868                }
 9869            }
 9870            Some(())
 9871        });
 9872    }
 9873
 9874    pub(super) fn will_rename_entry(
 9875        this: WeakEntity<Self>,
 9876        worktree_id: WorktreeId,
 9877        old_path: &Path,
 9878        new_path: &Path,
 9879        is_dir: bool,
 9880        cx: AsyncApp,
 9881    ) -> Task<ProjectTransaction> {
 9882        let old_uri = lsp::Uri::from_file_path(old_path)
 9883            .ok()
 9884            .map(|uri| uri.to_string());
 9885        let new_uri = lsp::Uri::from_file_path(new_path)
 9886            .ok()
 9887            .map(|uri| uri.to_string());
 9888        cx.spawn(async move |cx| {
 9889            let mut tasks = vec![];
 9890            this.update(cx, |this, cx| {
 9891                let local_store = this.as_local()?;
 9892                let old_uri = old_uri?;
 9893                let new_uri = new_uri?;
 9894                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9895                    let Some(filter) = local_store
 9896                        .language_server_paths_watched_for_rename
 9897                        .get(&language_server.server_id())
 9898                    else {
 9899                        continue;
 9900                    };
 9901
 9902                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9903                        continue;
 9904                    }
 9905                    let request_timeout = ProjectSettings::get_global(cx)
 9906                        .global_lsp_settings
 9907                        .get_request_timeout();
 9908
 9909                    let apply_edit = cx.spawn({
 9910                        let old_uri = old_uri.clone();
 9911                        let new_uri = new_uri.clone();
 9912                        let language_server = language_server.clone();
 9913                        async move |this, cx| {
 9914                            let edit = language_server
 9915                                .request::<WillRenameFiles>(
 9916                                    RenameFilesParams {
 9917                                        files: vec![FileRename { old_uri, new_uri }],
 9918                                    },
 9919                                    request_timeout,
 9920                                )
 9921                                .await
 9922                                .into_response()
 9923                                .context("will rename files")
 9924                                .log_err()
 9925                                .flatten()?;
 9926
 9927                            LocalLspStore::deserialize_workspace_edit(
 9928                                this.upgrade()?,
 9929                                edit,
 9930                                false,
 9931                                language_server.clone(),
 9932                                cx,
 9933                            )
 9934                            .await
 9935                            .ok()
 9936                        }
 9937                    });
 9938                    tasks.push(apply_edit);
 9939                }
 9940                Some(())
 9941            })
 9942            .ok()
 9943            .flatten();
 9944            let mut merged_transaction = ProjectTransaction::default();
 9945            for task in tasks {
 9946                // Await on tasks sequentially so that the order of application of edits is deterministic
 9947                // (at least with regards to the order of registration of language servers)
 9948                if let Some(transaction) = task.await {
 9949                    for (buffer, buffer_transaction) in transaction.0 {
 9950                        merged_transaction.0.insert(buffer, buffer_transaction);
 9951                    }
 9952                }
 9953            }
 9954            merged_transaction
 9955        })
 9956    }
 9957
 9958    fn lsp_notify_abs_paths_changed(
 9959        &mut self,
 9960        server_id: LanguageServerId,
 9961        changes: Vec<PathEvent>,
 9962    ) {
 9963        maybe!({
 9964            let server = self.language_server_for_id(server_id)?;
 9965            let changes = changes
 9966                .into_iter()
 9967                .filter_map(|event| {
 9968                    let typ = match event.kind? {
 9969                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9970                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9971                        PathEventKind::Changed | PathEventKind::Rescan => {
 9972                            lsp::FileChangeType::CHANGED
 9973                        }
 9974                    };
 9975                    Some(lsp::FileEvent {
 9976                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9977                        typ,
 9978                    })
 9979                })
 9980                .collect::<Vec<_>>();
 9981            if !changes.is_empty() {
 9982                server
 9983                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9984                        lsp::DidChangeWatchedFilesParams { changes },
 9985                    )
 9986                    .ok();
 9987            }
 9988            Some(())
 9989        });
 9990    }
 9991
 9992    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9993        self.as_local()?.language_server_for_id(id)
 9994    }
 9995
 9996    fn on_lsp_progress(
 9997        &mut self,
 9998        progress_params: lsp::ProgressParams,
 9999        language_server_id: LanguageServerId,
10000        disk_based_diagnostics_progress_token: Option<String>,
10001        cx: &mut Context<Self>,
10002    ) {
10003        match progress_params.value {
10004            lsp::ProgressParamsValue::WorkDone(progress) => {
10005                self.handle_work_done_progress(
10006                    progress,
10007                    language_server_id,
10008                    disk_based_diagnostics_progress_token,
10009                    ProgressToken::from_lsp(progress_params.token),
10010                    cx,
10011                );
10012            }
10013            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10014                let registration_id = match progress_params.token {
10015                    lsp::NumberOrString::Number(_) => None,
10016                    lsp::NumberOrString::String(token) => token
10017                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10018                        .map(|(_, id)| id.to_owned()),
10019                };
10020                if let Some(LanguageServerState::Running {
10021                    workspace_diagnostics_refresh_tasks,
10022                    ..
10023                }) = self
10024                    .as_local_mut()
10025                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10026                    && let Some(workspace_diagnostics) =
10027                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10028                {
10029                    workspace_diagnostics.progress_tx.try_send(()).ok();
10030                    self.apply_workspace_diagnostic_report(
10031                        language_server_id,
10032                        report,
10033                        registration_id.map(SharedString::from),
10034                        cx,
10035                    )
10036                }
10037            }
10038        }
10039    }
10040
10041    fn handle_work_done_progress(
10042        &mut self,
10043        progress: lsp::WorkDoneProgress,
10044        language_server_id: LanguageServerId,
10045        disk_based_diagnostics_progress_token: Option<String>,
10046        token: ProgressToken,
10047        cx: &mut Context<Self>,
10048    ) {
10049        let language_server_status =
10050            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10051                status
10052            } else {
10053                return;
10054            };
10055
10056        if !language_server_status.progress_tokens.contains(&token) {
10057            return;
10058        }
10059
10060        let is_disk_based_diagnostics_progress =
10061            if let (Some(disk_based_token), ProgressToken::String(token)) =
10062                (&disk_based_diagnostics_progress_token, &token)
10063            {
10064                token.starts_with(disk_based_token)
10065            } else {
10066                false
10067            };
10068
10069        match progress {
10070            lsp::WorkDoneProgress::Begin(report) => {
10071                if is_disk_based_diagnostics_progress {
10072                    self.disk_based_diagnostics_started(language_server_id, cx);
10073                }
10074                self.on_lsp_work_start(
10075                    language_server_id,
10076                    token.clone(),
10077                    LanguageServerProgress {
10078                        title: Some(report.title),
10079                        is_disk_based_diagnostics_progress,
10080                        is_cancellable: report.cancellable.unwrap_or(false),
10081                        message: report.message.clone(),
10082                        percentage: report.percentage.map(|p| p as usize),
10083                        last_update_at: cx.background_executor().now(),
10084                    },
10085                    cx,
10086                );
10087            }
10088            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10089                language_server_id,
10090                token,
10091                LanguageServerProgress {
10092                    title: None,
10093                    is_disk_based_diagnostics_progress,
10094                    is_cancellable: report.cancellable.unwrap_or(false),
10095                    message: report.message,
10096                    percentage: report.percentage.map(|p| p as usize),
10097                    last_update_at: cx.background_executor().now(),
10098                },
10099                cx,
10100            ),
10101            lsp::WorkDoneProgress::End(_) => {
10102                language_server_status.progress_tokens.remove(&token);
10103                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10104                if is_disk_based_diagnostics_progress {
10105                    self.disk_based_diagnostics_finished(language_server_id, cx);
10106                }
10107            }
10108        }
10109    }
10110
10111    fn on_lsp_work_start(
10112        &mut self,
10113        language_server_id: LanguageServerId,
10114        token: ProgressToken,
10115        progress: LanguageServerProgress,
10116        cx: &mut Context<Self>,
10117    ) {
10118        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10119            status.pending_work.insert(token.clone(), progress.clone());
10120            cx.notify();
10121        }
10122        cx.emit(LspStoreEvent::LanguageServerUpdate {
10123            language_server_id,
10124            name: self
10125                .language_server_adapter_for_id(language_server_id)
10126                .map(|adapter| adapter.name()),
10127            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10128                token: Some(token.to_proto()),
10129                title: progress.title,
10130                message: progress.message,
10131                percentage: progress.percentage.map(|p| p as u32),
10132                is_cancellable: Some(progress.is_cancellable),
10133            }),
10134        })
10135    }
10136
10137    fn on_lsp_work_progress(
10138        &mut self,
10139        language_server_id: LanguageServerId,
10140        token: ProgressToken,
10141        progress: LanguageServerProgress,
10142        cx: &mut Context<Self>,
10143    ) {
10144        let mut did_update = false;
10145        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10146            match status.pending_work.entry(token.clone()) {
10147                btree_map::Entry::Vacant(entry) => {
10148                    entry.insert(progress.clone());
10149                    did_update = true;
10150                }
10151                btree_map::Entry::Occupied(mut entry) => {
10152                    let entry = entry.get_mut();
10153                    if (progress.last_update_at - entry.last_update_at)
10154                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10155                    {
10156                        entry.last_update_at = progress.last_update_at;
10157                        if progress.message.is_some() {
10158                            entry.message = progress.message.clone();
10159                        }
10160                        if progress.percentage.is_some() {
10161                            entry.percentage = progress.percentage;
10162                        }
10163                        if progress.is_cancellable != entry.is_cancellable {
10164                            entry.is_cancellable = progress.is_cancellable;
10165                        }
10166                        did_update = true;
10167                    }
10168                }
10169            }
10170        }
10171
10172        if did_update {
10173            cx.emit(LspStoreEvent::LanguageServerUpdate {
10174                language_server_id,
10175                name: self
10176                    .language_server_adapter_for_id(language_server_id)
10177                    .map(|adapter| adapter.name()),
10178                message: proto::update_language_server::Variant::WorkProgress(
10179                    proto::LspWorkProgress {
10180                        token: Some(token.to_proto()),
10181                        message: progress.message,
10182                        percentage: progress.percentage.map(|p| p as u32),
10183                        is_cancellable: Some(progress.is_cancellable),
10184                    },
10185                ),
10186            })
10187        }
10188    }
10189
10190    fn on_lsp_work_end(
10191        &mut self,
10192        language_server_id: LanguageServerId,
10193        token: ProgressToken,
10194        cx: &mut Context<Self>,
10195    ) {
10196        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10197            if let Some(work) = status.pending_work.remove(&token)
10198                && !work.is_disk_based_diagnostics_progress
10199            {
10200                cx.emit(LspStoreEvent::RefreshInlayHints {
10201                    server_id: language_server_id,
10202                    request_id: None,
10203                });
10204            }
10205            cx.notify();
10206        }
10207
10208        cx.emit(LspStoreEvent::LanguageServerUpdate {
10209            language_server_id,
10210            name: self
10211                .language_server_adapter_for_id(language_server_id)
10212                .map(|adapter| adapter.name()),
10213            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10214                token: Some(token.to_proto()),
10215            }),
10216        })
10217    }
10218
10219    pub async fn handle_resolve_completion_documentation(
10220        this: Entity<Self>,
10221        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10222        mut cx: AsyncApp,
10223    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10224        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10225
10226        let completion = this
10227            .read_with(&cx, |this, cx| {
10228                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10229                let server = this
10230                    .language_server_for_id(id)
10231                    .with_context(|| format!("No language server {id}"))?;
10232
10233                let request_timeout = ProjectSettings::get_global(cx)
10234                    .global_lsp_settings
10235                    .get_request_timeout();
10236
10237                anyhow::Ok(cx.background_spawn(async move {
10238                    let can_resolve = server
10239                        .capabilities()
10240                        .completion_provider
10241                        .as_ref()
10242                        .and_then(|options| options.resolve_provider)
10243                        .unwrap_or(false);
10244                    if can_resolve {
10245                        server
10246                            .request::<lsp::request::ResolveCompletionItem>(
10247                                lsp_completion,
10248                                request_timeout,
10249                            )
10250                            .await
10251                            .into_response()
10252                            .context("resolve completion item")
10253                    } else {
10254                        anyhow::Ok(lsp_completion)
10255                    }
10256                }))
10257            })?
10258            .await?;
10259
10260        let mut documentation_is_markdown = false;
10261        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10262        let documentation = match completion.documentation {
10263            Some(lsp::Documentation::String(text)) => text,
10264
10265            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10266                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10267                value
10268            }
10269
10270            _ => String::new(),
10271        };
10272
10273        // If we have a new buffer_id, that means we're talking to a new client
10274        // and want to check for new text_edits in the completion too.
10275        let mut old_replace_start = None;
10276        let mut old_replace_end = None;
10277        let mut old_insert_start = None;
10278        let mut old_insert_end = None;
10279        let mut new_text = String::default();
10280        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10281            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10282                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10283                anyhow::Ok(buffer.read(cx).snapshot())
10284            })?;
10285
10286            if let Some(text_edit) = completion.text_edit.as_ref() {
10287                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10288
10289                if let Some(mut edit) = edit {
10290                    LineEnding::normalize(&mut edit.new_text);
10291
10292                    new_text = edit.new_text;
10293                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10294                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10295                    if let Some(insert_range) = edit.insert_range {
10296                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10297                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10298                    }
10299                }
10300            }
10301        }
10302
10303        Ok(proto::ResolveCompletionDocumentationResponse {
10304            documentation,
10305            documentation_is_markdown,
10306            old_replace_start,
10307            old_replace_end,
10308            new_text,
10309            lsp_completion,
10310            old_insert_start,
10311            old_insert_end,
10312        })
10313    }
10314
10315    async fn handle_on_type_formatting(
10316        this: Entity<Self>,
10317        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10318        mut cx: AsyncApp,
10319    ) -> Result<proto::OnTypeFormattingResponse> {
10320        let on_type_formatting = this.update(&mut cx, |this, cx| {
10321            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10322            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10323            let position = envelope
10324                .payload
10325                .position
10326                .and_then(deserialize_anchor)
10327                .context("invalid position")?;
10328            anyhow::Ok(this.apply_on_type_formatting(
10329                buffer,
10330                position,
10331                envelope.payload.trigger.clone(),
10332                cx,
10333            ))
10334        })?;
10335
10336        let transaction = on_type_formatting
10337            .await?
10338            .as_ref()
10339            .map(language::proto::serialize_transaction);
10340        Ok(proto::OnTypeFormattingResponse { transaction })
10341    }
10342
10343    async fn handle_pull_workspace_diagnostics(
10344        lsp_store: Entity<Self>,
10345        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10346        mut cx: AsyncApp,
10347    ) -> Result<proto::Ack> {
10348        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10349        lsp_store.update(&mut cx, |lsp_store, _| {
10350            lsp_store.pull_workspace_diagnostics(server_id);
10351        });
10352        Ok(proto::Ack {})
10353    }
10354
10355    async fn handle_open_buffer_for_symbol(
10356        this: Entity<Self>,
10357        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10358        mut cx: AsyncApp,
10359    ) -> Result<proto::OpenBufferForSymbolResponse> {
10360        let peer_id = envelope.original_sender_id().unwrap_or_default();
10361        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10362        let symbol = Self::deserialize_symbol(symbol)?;
10363        this.read_with(&cx, |this, _| {
10364            if let SymbolLocation::OutsideProject {
10365                abs_path,
10366                signature,
10367            } = &symbol.path
10368            {
10369                let new_signature = this.symbol_signature(&abs_path);
10370                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10371            }
10372            Ok(())
10373        })?;
10374        let buffer = this
10375            .update(&mut cx, |this, cx| {
10376                this.open_buffer_for_symbol(
10377                    &Symbol {
10378                        language_server_name: symbol.language_server_name,
10379                        source_worktree_id: symbol.source_worktree_id,
10380                        source_language_server_id: symbol.source_language_server_id,
10381                        path: symbol.path,
10382                        name: symbol.name,
10383                        kind: symbol.kind,
10384                        range: symbol.range,
10385                        label: CodeLabel::default(),
10386                        container_name: symbol.container_name,
10387                    },
10388                    cx,
10389                )
10390            })
10391            .await?;
10392
10393        this.update(&mut cx, |this, cx| {
10394            let is_private = buffer
10395                .read(cx)
10396                .file()
10397                .map(|f| f.is_private())
10398                .unwrap_or_default();
10399            if is_private {
10400                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10401            } else {
10402                this.buffer_store
10403                    .update(cx, |buffer_store, cx| {
10404                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10405                    })
10406                    .detach_and_log_err(cx);
10407                let buffer_id = buffer.read(cx).remote_id().to_proto();
10408                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10409            }
10410        })
10411    }
10412
10413    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10414        let mut hasher = Sha256::new();
10415        hasher.update(abs_path.to_string_lossy().as_bytes());
10416        hasher.update(self.nonce.to_be_bytes());
10417        hasher.finalize().as_slice().try_into().unwrap()
10418    }
10419
10420    pub async fn handle_get_project_symbols(
10421        this: Entity<Self>,
10422        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10423        mut cx: AsyncApp,
10424    ) -> Result<proto::GetProjectSymbolsResponse> {
10425        let symbols = this
10426            .update(&mut cx, |this, cx| {
10427                this.symbols(&envelope.payload.query, cx)
10428            })
10429            .await?;
10430
10431        Ok(proto::GetProjectSymbolsResponse {
10432            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10433        })
10434    }
10435
10436    pub async fn handle_restart_language_servers(
10437        this: Entity<Self>,
10438        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10439        mut cx: AsyncApp,
10440    ) -> Result<proto::Ack> {
10441        this.update(&mut cx, |lsp_store, cx| {
10442            let buffers =
10443                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10444            lsp_store.restart_language_servers_for_buffers(
10445                buffers,
10446                envelope
10447                    .payload
10448                    .only_servers
10449                    .into_iter()
10450                    .filter_map(|selector| {
10451                        Some(match selector.selector? {
10452                            proto::language_server_selector::Selector::ServerId(server_id) => {
10453                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10454                            }
10455                            proto::language_server_selector::Selector::Name(name) => {
10456                                LanguageServerSelector::Name(LanguageServerName(
10457                                    SharedString::from(name),
10458                                ))
10459                            }
10460                        })
10461                    })
10462                    .collect(),
10463                cx,
10464            );
10465        });
10466
10467        Ok(proto::Ack {})
10468    }
10469
10470    pub async fn handle_stop_language_servers(
10471        lsp_store: Entity<Self>,
10472        envelope: TypedEnvelope<proto::StopLanguageServers>,
10473        mut cx: AsyncApp,
10474    ) -> Result<proto::Ack> {
10475        lsp_store.update(&mut cx, |lsp_store, cx| {
10476            if envelope.payload.all
10477                && envelope.payload.also_servers.is_empty()
10478                && envelope.payload.buffer_ids.is_empty()
10479            {
10480                lsp_store.stop_all_language_servers(cx);
10481            } else {
10482                let buffers =
10483                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10484                lsp_store
10485                    .stop_language_servers_for_buffers(
10486                        buffers,
10487                        envelope
10488                            .payload
10489                            .also_servers
10490                            .into_iter()
10491                            .filter_map(|selector| {
10492                                Some(match selector.selector? {
10493                                    proto::language_server_selector::Selector::ServerId(
10494                                        server_id,
10495                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10496                                        server_id,
10497                                    )),
10498                                    proto::language_server_selector::Selector::Name(name) => {
10499                                        LanguageServerSelector::Name(LanguageServerName(
10500                                            SharedString::from(name),
10501                                        ))
10502                                    }
10503                                })
10504                            })
10505                            .collect(),
10506                        cx,
10507                    )
10508                    .detach_and_log_err(cx);
10509            }
10510        });
10511
10512        Ok(proto::Ack {})
10513    }
10514
10515    pub async fn handle_cancel_language_server_work(
10516        lsp_store: Entity<Self>,
10517        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10518        mut cx: AsyncApp,
10519    ) -> Result<proto::Ack> {
10520        lsp_store.update(&mut cx, |lsp_store, cx| {
10521            if let Some(work) = envelope.payload.work {
10522                match work {
10523                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10524                        let buffers =
10525                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10526                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10527                    }
10528                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10529                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10530                        let token = work
10531                            .token
10532                            .map(|token| {
10533                                ProgressToken::from_proto(token)
10534                                    .context("invalid work progress token")
10535                            })
10536                            .transpose()?;
10537                        lsp_store.cancel_language_server_work(server_id, token, cx);
10538                    }
10539                }
10540            }
10541            anyhow::Ok(())
10542        })?;
10543
10544        Ok(proto::Ack {})
10545    }
10546
10547    fn buffer_ids_to_buffers(
10548        &mut self,
10549        buffer_ids: impl Iterator<Item = u64>,
10550        cx: &mut Context<Self>,
10551    ) -> Vec<Entity<Buffer>> {
10552        buffer_ids
10553            .into_iter()
10554            .flat_map(|buffer_id| {
10555                self.buffer_store
10556                    .read(cx)
10557                    .get(BufferId::new(buffer_id).log_err()?)
10558            })
10559            .collect::<Vec<_>>()
10560    }
10561
10562    async fn handle_apply_additional_edits_for_completion(
10563        this: Entity<Self>,
10564        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10565        mut cx: AsyncApp,
10566    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10567        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10568            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10569            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10570            let completion = Self::deserialize_completion(
10571                envelope.payload.completion.context("invalid completion")?,
10572            )?;
10573            let all_commit_ranges = envelope
10574                .payload
10575                .all_commit_ranges
10576                .into_iter()
10577                .map(language::proto::deserialize_anchor_range)
10578                .collect::<Result<Vec<_>, _>>()?;
10579            anyhow::Ok((buffer, completion, all_commit_ranges))
10580        })?;
10581
10582        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10583            this.apply_additional_edits_for_completion(
10584                buffer,
10585                Rc::new(RefCell::new(Box::new([Completion {
10586                    replace_range: completion.replace_range,
10587                    new_text: completion.new_text,
10588                    source: completion.source,
10589                    documentation: None,
10590                    label: CodeLabel::default(),
10591                    match_start: None,
10592                    snippet_deduplication_key: None,
10593                    insert_text_mode: None,
10594                    icon_path: None,
10595                    confirm: None,
10596                }]))),
10597                0,
10598                false,
10599                all_commit_ranges,
10600                cx,
10601            )
10602        });
10603
10604        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10605            transaction: apply_additional_edits
10606                .await?
10607                .as_ref()
10608                .map(language::proto::serialize_transaction),
10609        })
10610    }
10611
10612    pub fn last_formatting_failure(&self) -> Option<&str> {
10613        self.last_formatting_failure.as_deref()
10614    }
10615
10616    pub fn reset_last_formatting_failure(&mut self) {
10617        self.last_formatting_failure = None;
10618    }
10619
10620    pub fn environment_for_buffer(
10621        &self,
10622        buffer: &Entity<Buffer>,
10623        cx: &mut Context<Self>,
10624    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10625        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10626            environment.update(cx, |env, cx| {
10627                env.buffer_environment(buffer, &self.worktree_store, cx)
10628            })
10629        } else {
10630            Task::ready(None).shared()
10631        }
10632    }
10633
10634    pub fn format(
10635        &mut self,
10636        buffers: HashSet<Entity<Buffer>>,
10637        target: LspFormatTarget,
10638        push_to_history: bool,
10639        trigger: FormatTrigger,
10640        cx: &mut Context<Self>,
10641    ) -> Task<anyhow::Result<ProjectTransaction>> {
10642        let logger = zlog::scoped!("format");
10643        if self.as_local().is_some() {
10644            zlog::trace!(logger => "Formatting locally");
10645            let logger = zlog::scoped!(logger => "local");
10646            let buffers = buffers
10647                .into_iter()
10648                .map(|buffer_handle| {
10649                    let buffer = buffer_handle.read(cx);
10650                    let buffer_abs_path = File::from_dyn(buffer.file())
10651                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10652
10653                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10654                })
10655                .collect::<Vec<_>>();
10656
10657            cx.spawn(async move |lsp_store, cx| {
10658                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10659
10660                for (handle, abs_path, id) in buffers {
10661                    let env = lsp_store
10662                        .update(cx, |lsp_store, cx| {
10663                            lsp_store.environment_for_buffer(&handle, cx)
10664                        })?
10665                        .await;
10666
10667                    let ranges = match &target {
10668                        LspFormatTarget::Buffers => None,
10669                        LspFormatTarget::Ranges(ranges) => {
10670                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10671                        }
10672                    };
10673
10674                    formattable_buffers.push(FormattableBuffer {
10675                        handle,
10676                        abs_path,
10677                        env,
10678                        ranges,
10679                    });
10680                }
10681                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10682
10683                let format_timer = zlog::time!(logger => "Formatting buffers");
10684                let result = LocalLspStore::format_locally(
10685                    lsp_store.clone(),
10686                    formattable_buffers,
10687                    push_to_history,
10688                    trigger,
10689                    logger,
10690                    cx,
10691                )
10692                .await;
10693                format_timer.end();
10694
10695                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10696
10697                lsp_store.update(cx, |lsp_store, _| {
10698                    lsp_store.update_last_formatting_failure(&result);
10699                })?;
10700
10701                result
10702            })
10703        } else if let Some((client, project_id)) = self.upstream_client() {
10704            zlog::trace!(logger => "Formatting remotely");
10705            let logger = zlog::scoped!(logger => "remote");
10706
10707            let buffer_ranges = match &target {
10708                LspFormatTarget::Buffers => Vec::new(),
10709                LspFormatTarget::Ranges(ranges) => ranges
10710                    .iter()
10711                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10712                        buffer_id: buffer_id.to_proto(),
10713                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10714                    })
10715                    .collect(),
10716            };
10717
10718            let buffer_store = self.buffer_store();
10719            cx.spawn(async move |lsp_store, cx| {
10720                zlog::trace!(logger => "Sending remote format request");
10721                let request_timer = zlog::time!(logger => "remote format request");
10722                let result = client
10723                    .request(proto::FormatBuffers {
10724                        project_id,
10725                        trigger: trigger as i32,
10726                        buffer_ids: buffers
10727                            .iter()
10728                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10729                            .collect(),
10730                        buffer_ranges,
10731                    })
10732                    .await
10733                    .and_then(|result| result.transaction.context("missing transaction"));
10734                request_timer.end();
10735
10736                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10737
10738                lsp_store.update(cx, |lsp_store, _| {
10739                    lsp_store.update_last_formatting_failure(&result);
10740                })?;
10741
10742                let transaction_response = result?;
10743                let _timer = zlog::time!(logger => "deserializing project transaction");
10744                buffer_store
10745                    .update(cx, |buffer_store, cx| {
10746                        buffer_store.deserialize_project_transaction(
10747                            transaction_response,
10748                            push_to_history,
10749                            cx,
10750                        )
10751                    })
10752                    .await
10753            })
10754        } else {
10755            zlog::trace!(logger => "Not formatting");
10756            Task::ready(Ok(ProjectTransaction::default()))
10757        }
10758    }
10759
10760    async fn handle_format_buffers(
10761        this: Entity<Self>,
10762        envelope: TypedEnvelope<proto::FormatBuffers>,
10763        mut cx: AsyncApp,
10764    ) -> Result<proto::FormatBuffersResponse> {
10765        let sender_id = envelope.original_sender_id().unwrap_or_default();
10766        let format = this.update(&mut cx, |this, cx| {
10767            let mut buffers = HashSet::default();
10768            for buffer_id in &envelope.payload.buffer_ids {
10769                let buffer_id = BufferId::new(*buffer_id)?;
10770                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10771            }
10772
10773            let target = if envelope.payload.buffer_ranges.is_empty() {
10774                LspFormatTarget::Buffers
10775            } else {
10776                let mut ranges_map = BTreeMap::new();
10777                for buffer_range in &envelope.payload.buffer_ranges {
10778                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10779                    let ranges: Result<Vec<_>> = buffer_range
10780                        .ranges
10781                        .iter()
10782                        .map(|range| {
10783                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10784                        })
10785                        .collect();
10786                    ranges_map.insert(buffer_id, ranges?);
10787                }
10788                LspFormatTarget::Ranges(ranges_map)
10789            };
10790
10791            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10792            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10793        })?;
10794
10795        let project_transaction = format.await?;
10796        let project_transaction = this.update(&mut cx, |this, cx| {
10797            this.buffer_store.update(cx, |buffer_store, cx| {
10798                buffer_store.serialize_project_transaction_for_peer(
10799                    project_transaction,
10800                    sender_id,
10801                    cx,
10802                )
10803            })
10804        });
10805        Ok(proto::FormatBuffersResponse {
10806            transaction: Some(project_transaction),
10807        })
10808    }
10809
10810    async fn handle_apply_code_action_kind(
10811        this: Entity<Self>,
10812        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10813        mut cx: AsyncApp,
10814    ) -> Result<proto::ApplyCodeActionKindResponse> {
10815        let sender_id = envelope.original_sender_id().unwrap_or_default();
10816        let format = this.update(&mut cx, |this, cx| {
10817            let mut buffers = HashSet::default();
10818            for buffer_id in &envelope.payload.buffer_ids {
10819                let buffer_id = BufferId::new(*buffer_id)?;
10820                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10821            }
10822            let kind = match envelope.payload.kind.as_str() {
10823                "" => CodeActionKind::EMPTY,
10824                "quickfix" => CodeActionKind::QUICKFIX,
10825                "refactor" => CodeActionKind::REFACTOR,
10826                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10827                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10828                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10829                "source" => CodeActionKind::SOURCE,
10830                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10831                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10832                _ => anyhow::bail!(
10833                    "Invalid code action kind {}",
10834                    envelope.payload.kind.as_str()
10835                ),
10836            };
10837            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10838        })?;
10839
10840        let project_transaction = format.await?;
10841        let project_transaction = this.update(&mut cx, |this, cx| {
10842            this.buffer_store.update(cx, |buffer_store, cx| {
10843                buffer_store.serialize_project_transaction_for_peer(
10844                    project_transaction,
10845                    sender_id,
10846                    cx,
10847                )
10848            })
10849        });
10850        Ok(proto::ApplyCodeActionKindResponse {
10851            transaction: Some(project_transaction),
10852        })
10853    }
10854
10855    async fn shutdown_language_server(
10856        server_state: Option<LanguageServerState>,
10857        name: LanguageServerName,
10858        cx: &mut AsyncApp,
10859    ) {
10860        let server = match server_state {
10861            Some(LanguageServerState::Starting { startup, .. }) => {
10862                let mut timer = cx
10863                    .background_executor()
10864                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10865                    .fuse();
10866
10867                select! {
10868                    server = startup.fuse() => server,
10869                    () = timer => {
10870                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10871                        None
10872                    },
10873                }
10874            }
10875
10876            Some(LanguageServerState::Running { server, .. }) => Some(server),
10877
10878            None => None,
10879        };
10880
10881        let Some(server) = server else { return };
10882        if let Some(shutdown) = server.shutdown() {
10883            shutdown.await;
10884        }
10885    }
10886
10887    // Returns a list of all of the worktrees which no longer have a language server and the root path
10888    // for the stopped server
10889    fn stop_local_language_server(
10890        &mut self,
10891        server_id: LanguageServerId,
10892        cx: &mut Context<Self>,
10893    ) -> Task<()> {
10894        let local = match &mut self.mode {
10895            LspStoreMode::Local(local) => local,
10896            _ => {
10897                return Task::ready(());
10898            }
10899        };
10900
10901        // Remove this server ID from all entries in the given worktree.
10902        local
10903            .language_server_ids
10904            .retain(|_, state| state.id != server_id);
10905        self.buffer_store.update(cx, |buffer_store, cx| {
10906            for buffer in buffer_store.buffers() {
10907                buffer.update(cx, |buffer, cx| {
10908                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10909                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10910                });
10911            }
10912        });
10913
10914        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10915        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10916            summaries.retain(|path, summaries_by_server_id| {
10917                if summaries_by_server_id.remove(&server_id).is_some() {
10918                    if let Some((client, project_id)) = self.downstream_client.clone() {
10919                        client
10920                            .send(proto::UpdateDiagnosticSummary {
10921                                project_id,
10922                                worktree_id: worktree_id.to_proto(),
10923                                summary: Some(proto::DiagnosticSummary {
10924                                    path: path.as_ref().to_proto(),
10925                                    language_server_id: server_id.0 as u64,
10926                                    error_count: 0,
10927                                    warning_count: 0,
10928                                }),
10929                                more_summaries: Vec::new(),
10930                            })
10931                            .log_err();
10932                    }
10933                    cleared_paths.push(ProjectPath {
10934                        worktree_id: *worktree_id,
10935                        path: path.clone(),
10936                    });
10937                    !summaries_by_server_id.is_empty()
10938                } else {
10939                    true
10940                }
10941            });
10942        }
10943        if !cleared_paths.is_empty() {
10944            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10945                server_id,
10946                paths: cleared_paths,
10947            });
10948        }
10949
10950        let local = self.as_local_mut().unwrap();
10951        for diagnostics in local.diagnostics.values_mut() {
10952            diagnostics.retain(|_, diagnostics_by_server_id| {
10953                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10954                    diagnostics_by_server_id.remove(ix);
10955                    !diagnostics_by_server_id.is_empty()
10956                } else {
10957                    true
10958                }
10959            });
10960        }
10961        local.language_server_watched_paths.remove(&server_id);
10962
10963        let server_state = local.language_servers.remove(&server_id);
10964        self.cleanup_lsp_data(server_id);
10965        let name = self
10966            .language_server_statuses
10967            .remove(&server_id)
10968            .map(|status| status.name)
10969            .or_else(|| {
10970                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10971                    Some(adapter.name())
10972                } else {
10973                    None
10974                }
10975            });
10976
10977        if let Some(name) = name {
10978            log::info!("stopping language server {name}");
10979            self.languages
10980                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10981            cx.notify();
10982
10983            return cx.spawn(async move |lsp_store, cx| {
10984                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10985                lsp_store
10986                    .update(cx, |lsp_store, cx| {
10987                        lsp_store
10988                            .languages
10989                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10990                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10991                        cx.notify();
10992                    })
10993                    .ok();
10994            });
10995        }
10996
10997        if server_state.is_some() {
10998            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10999        }
11000        Task::ready(())
11001    }
11002
11003    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11004        self.shutdown_all_language_servers(cx).detach();
11005    }
11006
11007    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11008        if let Some((client, project_id)) = self.upstream_client() {
11009            let request = client.request(proto::StopLanguageServers {
11010                project_id,
11011                buffer_ids: Vec::new(),
11012                also_servers: Vec::new(),
11013                all: true,
11014            });
11015            cx.background_spawn(async move {
11016                request.await.ok();
11017            })
11018        } else {
11019            let Some(local) = self.as_local_mut() else {
11020                return Task::ready(());
11021            };
11022            let language_servers_to_stop = local
11023                .language_server_ids
11024                .values()
11025                .map(|state| state.id)
11026                .collect();
11027            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11028            let tasks = language_servers_to_stop
11029                .into_iter()
11030                .map(|server| self.stop_local_language_server(server, cx))
11031                .collect::<Vec<_>>();
11032            cx.background_spawn(async move {
11033                futures::future::join_all(tasks).await;
11034            })
11035        }
11036    }
11037
11038    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11039        let buffers = self.buffer_store.read(cx).buffers().collect();
11040        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11041    }
11042
11043    pub fn restart_language_servers_for_buffers(
11044        &mut self,
11045        buffers: Vec<Entity<Buffer>>,
11046        only_restart_servers: HashSet<LanguageServerSelector>,
11047        cx: &mut Context<Self>,
11048    ) {
11049        if let Some((client, project_id)) = self.upstream_client() {
11050            let request = client.request(proto::RestartLanguageServers {
11051                project_id,
11052                buffer_ids: buffers
11053                    .into_iter()
11054                    .map(|b| b.read(cx).remote_id().to_proto())
11055                    .collect(),
11056                only_servers: only_restart_servers
11057                    .into_iter()
11058                    .map(|selector| {
11059                        let selector = match selector {
11060                            LanguageServerSelector::Id(language_server_id) => {
11061                                proto::language_server_selector::Selector::ServerId(
11062                                    language_server_id.to_proto(),
11063                                )
11064                            }
11065                            LanguageServerSelector::Name(language_server_name) => {
11066                                proto::language_server_selector::Selector::Name(
11067                                    language_server_name.to_string(),
11068                                )
11069                            }
11070                        };
11071                        proto::LanguageServerSelector {
11072                            selector: Some(selector),
11073                        }
11074                    })
11075                    .collect(),
11076                all: false,
11077            });
11078            cx.background_spawn(request).detach_and_log_err(cx);
11079        } else {
11080            let stop_task = if only_restart_servers.is_empty() {
11081                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11082            } else {
11083                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11084            };
11085            cx.spawn(async move |lsp_store, cx| {
11086                stop_task.await;
11087                lsp_store.update(cx, |lsp_store, cx| {
11088                    for buffer in buffers {
11089                        lsp_store.register_buffer_with_language_servers(
11090                            &buffer,
11091                            only_restart_servers.clone(),
11092                            true,
11093                            cx,
11094                        );
11095                    }
11096                })
11097            })
11098            .detach();
11099        }
11100    }
11101
11102    pub fn stop_language_servers_for_buffers(
11103        &mut self,
11104        buffers: Vec<Entity<Buffer>>,
11105        also_stop_servers: HashSet<LanguageServerSelector>,
11106        cx: &mut Context<Self>,
11107    ) -> Task<Result<()>> {
11108        if let Some((client, project_id)) = self.upstream_client() {
11109            let request = client.request(proto::StopLanguageServers {
11110                project_id,
11111                buffer_ids: buffers
11112                    .into_iter()
11113                    .map(|b| b.read(cx).remote_id().to_proto())
11114                    .collect(),
11115                also_servers: also_stop_servers
11116                    .into_iter()
11117                    .map(|selector| {
11118                        let selector = match selector {
11119                            LanguageServerSelector::Id(language_server_id) => {
11120                                proto::language_server_selector::Selector::ServerId(
11121                                    language_server_id.to_proto(),
11122                                )
11123                            }
11124                            LanguageServerSelector::Name(language_server_name) => {
11125                                proto::language_server_selector::Selector::Name(
11126                                    language_server_name.to_string(),
11127                                )
11128                            }
11129                        };
11130                        proto::LanguageServerSelector {
11131                            selector: Some(selector),
11132                        }
11133                    })
11134                    .collect(),
11135                all: false,
11136            });
11137            cx.background_spawn(async move {
11138                let _ = request.await?;
11139                Ok(())
11140            })
11141        } else {
11142            let task =
11143                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11144            cx.background_spawn(async move {
11145                task.await;
11146                Ok(())
11147            })
11148        }
11149    }
11150
11151    fn stop_local_language_servers_for_buffers(
11152        &mut self,
11153        buffers: &[Entity<Buffer>],
11154        also_stop_servers: HashSet<LanguageServerSelector>,
11155        cx: &mut Context<Self>,
11156    ) -> Task<()> {
11157        let Some(local) = self.as_local_mut() else {
11158            return Task::ready(());
11159        };
11160        let mut language_server_names_to_stop = BTreeSet::default();
11161        let mut language_servers_to_stop = also_stop_servers
11162            .into_iter()
11163            .flat_map(|selector| match selector {
11164                LanguageServerSelector::Id(id) => Some(id),
11165                LanguageServerSelector::Name(name) => {
11166                    language_server_names_to_stop.insert(name);
11167                    None
11168                }
11169            })
11170            .collect::<BTreeSet<_>>();
11171
11172        let mut covered_worktrees = HashSet::default();
11173        for buffer in buffers {
11174            buffer.update(cx, |buffer, cx| {
11175                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11176                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11177                    && covered_worktrees.insert(worktree_id)
11178                {
11179                    language_server_names_to_stop.retain(|name| {
11180                        let old_ids_count = language_servers_to_stop.len();
11181                        let all_language_servers_with_this_name = local
11182                            .language_server_ids
11183                            .iter()
11184                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11185                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11186                        old_ids_count == language_servers_to_stop.len()
11187                    });
11188                }
11189            });
11190        }
11191        for name in language_server_names_to_stop {
11192            language_servers_to_stop.extend(
11193                local
11194                    .language_server_ids
11195                    .iter()
11196                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11197            );
11198        }
11199
11200        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11201        let tasks = language_servers_to_stop
11202            .into_iter()
11203            .map(|server| self.stop_local_language_server(server, cx))
11204            .collect::<Vec<_>>();
11205
11206        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11207    }
11208
11209    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11210        let (worktree, relative_path) =
11211            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11212
11213        let project_path = ProjectPath {
11214            worktree_id: worktree.read(cx).id(),
11215            path: relative_path,
11216        };
11217
11218        Some(
11219            self.buffer_store()
11220                .read(cx)
11221                .get_by_path(&project_path)?
11222                .read(cx),
11223        )
11224    }
11225
11226    #[cfg(any(test, feature = "test-support"))]
11227    pub fn update_diagnostics(
11228        &mut self,
11229        server_id: LanguageServerId,
11230        diagnostics: lsp::PublishDiagnosticsParams,
11231        result_id: Option<SharedString>,
11232        source_kind: DiagnosticSourceKind,
11233        disk_based_sources: &[String],
11234        cx: &mut Context<Self>,
11235    ) -> Result<()> {
11236        self.merge_lsp_diagnostics(
11237            source_kind,
11238            vec![DocumentDiagnosticsUpdate {
11239                diagnostics,
11240                result_id,
11241                server_id,
11242                disk_based_sources: Cow::Borrowed(disk_based_sources),
11243                registration_id: None,
11244            }],
11245            |_, _, _| false,
11246            cx,
11247        )
11248    }
11249
11250    pub fn merge_lsp_diagnostics(
11251        &mut self,
11252        source_kind: DiagnosticSourceKind,
11253        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11254        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11255        cx: &mut Context<Self>,
11256    ) -> Result<()> {
11257        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11258        let updates = lsp_diagnostics
11259            .into_iter()
11260            .filter_map(|update| {
11261                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11262                Some(DocumentDiagnosticsUpdate {
11263                    diagnostics: self.lsp_to_document_diagnostics(
11264                        abs_path,
11265                        source_kind,
11266                        update.server_id,
11267                        update.diagnostics,
11268                        &update.disk_based_sources,
11269                        update.registration_id.clone(),
11270                    ),
11271                    result_id: update.result_id,
11272                    server_id: update.server_id,
11273                    disk_based_sources: update.disk_based_sources,
11274                    registration_id: update.registration_id,
11275                })
11276            })
11277            .collect();
11278        self.merge_diagnostic_entries(updates, merge, cx)?;
11279        Ok(())
11280    }
11281
11282    fn lsp_to_document_diagnostics(
11283        &mut self,
11284        document_abs_path: PathBuf,
11285        source_kind: DiagnosticSourceKind,
11286        server_id: LanguageServerId,
11287        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11288        disk_based_sources: &[String],
11289        registration_id: Option<SharedString>,
11290    ) -> DocumentDiagnostics {
11291        let mut diagnostics = Vec::default();
11292        let mut primary_diagnostic_group_ids = HashMap::default();
11293        let mut sources_by_group_id = HashMap::default();
11294        let mut supporting_diagnostics = HashMap::default();
11295
11296        let adapter = self.language_server_adapter_for_id(server_id);
11297
11298        // Ensure that primary diagnostics are always the most severe
11299        lsp_diagnostics
11300            .diagnostics
11301            .sort_by_key(|item| item.severity);
11302
11303        for diagnostic in &lsp_diagnostics.diagnostics {
11304            let source = diagnostic.source.as_ref();
11305            let range = range_from_lsp(diagnostic.range);
11306            let is_supporting = diagnostic
11307                .related_information
11308                .as_ref()
11309                .is_some_and(|infos| {
11310                    infos.iter().any(|info| {
11311                        primary_diagnostic_group_ids.contains_key(&(
11312                            source,
11313                            diagnostic.code.clone(),
11314                            range_from_lsp(info.location.range),
11315                        ))
11316                    })
11317                });
11318
11319            let is_unnecessary = diagnostic
11320                .tags
11321                .as_ref()
11322                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11323
11324            let underline = self
11325                .language_server_adapter_for_id(server_id)
11326                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11327
11328            if is_supporting {
11329                supporting_diagnostics.insert(
11330                    (source, diagnostic.code.clone(), range),
11331                    (diagnostic.severity, is_unnecessary),
11332                );
11333            } else {
11334                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11335                let is_disk_based =
11336                    source.is_some_and(|source| disk_based_sources.contains(source));
11337
11338                sources_by_group_id.insert(group_id, source);
11339                primary_diagnostic_group_ids
11340                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11341
11342                diagnostics.push(DiagnosticEntry {
11343                    range,
11344                    diagnostic: Diagnostic {
11345                        source: diagnostic.source.clone(),
11346                        source_kind,
11347                        code: diagnostic.code.clone(),
11348                        code_description: diagnostic
11349                            .code_description
11350                            .as_ref()
11351                            .and_then(|d| d.href.clone()),
11352                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11353                        markdown: adapter.as_ref().and_then(|adapter| {
11354                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11355                        }),
11356                        message: diagnostic.message.trim().to_string(),
11357                        group_id,
11358                        is_primary: true,
11359                        is_disk_based,
11360                        is_unnecessary,
11361                        underline,
11362                        data: diagnostic.data.clone(),
11363                        registration_id: registration_id.clone(),
11364                    },
11365                });
11366                if let Some(infos) = &diagnostic.related_information {
11367                    for info in infos {
11368                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11369                            let range = range_from_lsp(info.location.range);
11370                            diagnostics.push(DiagnosticEntry {
11371                                range,
11372                                diagnostic: Diagnostic {
11373                                    source: diagnostic.source.clone(),
11374                                    source_kind,
11375                                    code: diagnostic.code.clone(),
11376                                    code_description: diagnostic
11377                                        .code_description
11378                                        .as_ref()
11379                                        .and_then(|d| d.href.clone()),
11380                                    severity: DiagnosticSeverity::INFORMATION,
11381                                    markdown: adapter.as_ref().and_then(|adapter| {
11382                                        adapter.diagnostic_message_to_markdown(&info.message)
11383                                    }),
11384                                    message: info.message.trim().to_string(),
11385                                    group_id,
11386                                    is_primary: false,
11387                                    is_disk_based,
11388                                    is_unnecessary: false,
11389                                    underline,
11390                                    data: diagnostic.data.clone(),
11391                                    registration_id: registration_id.clone(),
11392                                },
11393                            });
11394                        }
11395                    }
11396                }
11397            }
11398        }
11399
11400        for entry in &mut diagnostics {
11401            let diagnostic = &mut entry.diagnostic;
11402            if !diagnostic.is_primary {
11403                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11404                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11405                    source,
11406                    diagnostic.code.clone(),
11407                    entry.range.clone(),
11408                )) {
11409                    if let Some(severity) = severity {
11410                        diagnostic.severity = severity;
11411                    }
11412                    diagnostic.is_unnecessary = is_unnecessary;
11413                }
11414            }
11415        }
11416
11417        DocumentDiagnostics {
11418            diagnostics,
11419            document_abs_path,
11420            version: lsp_diagnostics.version,
11421        }
11422    }
11423
11424    fn insert_newly_running_language_server(
11425        &mut self,
11426        adapter: Arc<CachedLspAdapter>,
11427        language_server: Arc<LanguageServer>,
11428        server_id: LanguageServerId,
11429        key: LanguageServerSeed,
11430        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11431        cx: &mut Context<Self>,
11432    ) {
11433        let Some(local) = self.as_local_mut() else {
11434            return;
11435        };
11436        // If the language server for this key doesn't match the server id, don't store the
11437        // server. Which will cause it to be dropped, killing the process
11438        if local
11439            .language_server_ids
11440            .get(&key)
11441            .map(|state| state.id != server_id)
11442            .unwrap_or(false)
11443        {
11444            return;
11445        }
11446
11447        // Update language_servers collection with Running variant of LanguageServerState
11448        // indicating that the server is up and running and ready
11449        let workspace_folders = workspace_folders.lock().clone();
11450        language_server.set_workspace_folders(workspace_folders);
11451
11452        let workspace_diagnostics_refresh_tasks = language_server
11453            .capabilities()
11454            .diagnostic_provider
11455            .and_then(|provider| {
11456                local
11457                    .language_server_dynamic_registrations
11458                    .entry(server_id)
11459                    .or_default()
11460                    .diagnostics
11461                    .entry(None)
11462                    .or_insert(provider.clone());
11463                let workspace_refresher =
11464                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11465
11466                Some((None, workspace_refresher))
11467            })
11468            .into_iter()
11469            .collect();
11470        local.language_servers.insert(
11471            server_id,
11472            LanguageServerState::Running {
11473                workspace_diagnostics_refresh_tasks,
11474                adapter: adapter.clone(),
11475                server: language_server.clone(),
11476                simulate_disk_based_diagnostics_completion: None,
11477            },
11478        );
11479        local
11480            .languages
11481            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11482        if let Some(file_ops_caps) = language_server
11483            .capabilities()
11484            .workspace
11485            .as_ref()
11486            .and_then(|ws| ws.file_operations.as_ref())
11487        {
11488            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11489            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11490            if did_rename_caps.or(will_rename_caps).is_some() {
11491                let watcher = RenamePathsWatchedForServer::default()
11492                    .with_did_rename_patterns(did_rename_caps)
11493                    .with_will_rename_patterns(will_rename_caps);
11494                local
11495                    .language_server_paths_watched_for_rename
11496                    .insert(server_id, watcher);
11497            }
11498        }
11499
11500        self.language_server_statuses.insert(
11501            server_id,
11502            LanguageServerStatus {
11503                name: language_server.name(),
11504                server_version: language_server.version(),
11505                server_readable_version: language_server.readable_version(),
11506                pending_work: Default::default(),
11507                has_pending_diagnostic_updates: false,
11508                progress_tokens: Default::default(),
11509                worktree: Some(key.worktree_id),
11510                binary: Some(language_server.binary().clone()),
11511                configuration: Some(language_server.configuration().clone()),
11512                workspace_folders: language_server.workspace_folders(),
11513                process_id: language_server.process_id(),
11514            },
11515        );
11516
11517        cx.emit(LspStoreEvent::LanguageServerAdded(
11518            server_id,
11519            language_server.name(),
11520            Some(key.worktree_id),
11521        ));
11522
11523        let server_capabilities = language_server.capabilities();
11524        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11525            downstream_client
11526                .send(proto::StartLanguageServer {
11527                    project_id: *project_id,
11528                    server: Some(proto::LanguageServer {
11529                        id: server_id.to_proto(),
11530                        name: language_server.name().to_string(),
11531                        worktree_id: Some(key.worktree_id.to_proto()),
11532                    }),
11533                    capabilities: serde_json::to_string(&server_capabilities)
11534                        .expect("serializing server LSP capabilities"),
11535                })
11536                .log_err();
11537        }
11538        self.lsp_server_capabilities
11539            .insert(server_id, server_capabilities);
11540
11541        // Tell the language server about every open buffer in the worktree that matches the language.
11542        // Also check for buffers in worktrees that reused this server
11543        let mut worktrees_using_server = vec![key.worktree_id];
11544        if let Some(local) = self.as_local() {
11545            // Find all worktrees that have this server in their language server tree
11546            for (worktree_id, servers) in &local.lsp_tree.instances {
11547                if *worktree_id != key.worktree_id {
11548                    for server_map in servers.roots.values() {
11549                        if server_map
11550                            .values()
11551                            .any(|(node, _)| node.id() == Some(server_id))
11552                        {
11553                            worktrees_using_server.push(*worktree_id);
11554                        }
11555                    }
11556                }
11557            }
11558        }
11559
11560        let mut buffer_paths_registered = Vec::new();
11561        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11562            let mut lsp_adapters = HashMap::default();
11563            for buffer_handle in buffer_store.buffers() {
11564                let buffer = buffer_handle.read(cx);
11565                let file = match File::from_dyn(buffer.file()) {
11566                    Some(file) => file,
11567                    None => continue,
11568                };
11569                let language = match buffer.language() {
11570                    Some(language) => language,
11571                    None => continue,
11572                };
11573
11574                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11575                    || !lsp_adapters
11576                        .entry(language.name())
11577                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11578                        .iter()
11579                        .any(|a| a.name == key.name)
11580                {
11581                    continue;
11582                }
11583                // didOpen
11584                let file = match file.as_local() {
11585                    Some(file) => file,
11586                    None => continue,
11587                };
11588
11589                let local = self.as_local_mut().unwrap();
11590
11591                let buffer_id = buffer.remote_id();
11592                if local.registered_buffers.contains_key(&buffer_id) {
11593                    let abs_path = file.abs_path(cx);
11594                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11595                        Ok(uri) => uri,
11596                        Err(()) => {
11597                            log::error!("failed to convert path to URI: {:?}", abs_path);
11598                            continue;
11599                        }
11600                    };
11601
11602                    let versions = local
11603                        .buffer_snapshots
11604                        .entry(buffer_id)
11605                        .or_default()
11606                        .entry(server_id)
11607                        .and_modify(|_| {
11608                            assert!(
11609                            false,
11610                            "There should not be an existing snapshot for a newly inserted buffer"
11611                        )
11612                        })
11613                        .or_insert_with(|| {
11614                            vec![LspBufferSnapshot {
11615                                version: 0,
11616                                snapshot: buffer.text_snapshot(),
11617                            }]
11618                        });
11619
11620                    let snapshot = versions.last().unwrap();
11621                    let version = snapshot.version;
11622                    let initial_snapshot = &snapshot.snapshot;
11623                    language_server.register_buffer(
11624                        uri,
11625                        adapter.language_id(&language.name()),
11626                        version,
11627                        initial_snapshot.text(),
11628                    );
11629                    buffer_paths_registered.push((buffer_id, abs_path));
11630                    local
11631                        .buffers_opened_in_servers
11632                        .entry(buffer_id)
11633                        .or_default()
11634                        .insert(server_id);
11635                }
11636                buffer_handle.update(cx, |buffer, cx| {
11637                    buffer.set_completion_triggers(
11638                        server_id,
11639                        language_server
11640                            .capabilities()
11641                            .completion_provider
11642                            .as_ref()
11643                            .and_then(|provider| {
11644                                provider
11645                                    .trigger_characters
11646                                    .as_ref()
11647                                    .map(|characters| characters.iter().cloned().collect())
11648                            })
11649                            .unwrap_or_default(),
11650                        cx,
11651                    )
11652                });
11653            }
11654        });
11655
11656        for (buffer_id, abs_path) in buffer_paths_registered {
11657            cx.emit(LspStoreEvent::LanguageServerUpdate {
11658                language_server_id: server_id,
11659                name: Some(adapter.name()),
11660                message: proto::update_language_server::Variant::RegisteredForBuffer(
11661                    proto::RegisteredForBuffer {
11662                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11663                        buffer_id: buffer_id.to_proto(),
11664                    },
11665                ),
11666            });
11667        }
11668
11669        cx.notify();
11670    }
11671
11672    pub fn language_servers_running_disk_based_diagnostics(
11673        &self,
11674    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11675        self.language_server_statuses
11676            .iter()
11677            .filter_map(|(id, status)| {
11678                if status.has_pending_diagnostic_updates {
11679                    Some(*id)
11680                } else {
11681                    None
11682                }
11683            })
11684    }
11685
11686    pub(crate) fn cancel_language_server_work_for_buffers(
11687        &mut self,
11688        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11689        cx: &mut Context<Self>,
11690    ) {
11691        if let Some((client, project_id)) = self.upstream_client() {
11692            let request = client.request(proto::CancelLanguageServerWork {
11693                project_id,
11694                work: Some(proto::cancel_language_server_work::Work::Buffers(
11695                    proto::cancel_language_server_work::Buffers {
11696                        buffer_ids: buffers
11697                            .into_iter()
11698                            .map(|b| b.read(cx).remote_id().to_proto())
11699                            .collect(),
11700                    },
11701                )),
11702            });
11703            cx.background_spawn(request).detach_and_log_err(cx);
11704        } else if let Some(local) = self.as_local() {
11705            let servers = buffers
11706                .into_iter()
11707                .flat_map(|buffer| {
11708                    buffer.update(cx, |buffer, cx| {
11709                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11710                    })
11711                })
11712                .collect::<HashSet<_>>();
11713            for server_id in servers {
11714                self.cancel_language_server_work(server_id, None, cx);
11715            }
11716        }
11717    }
11718
11719    pub(crate) fn cancel_language_server_work(
11720        &mut self,
11721        server_id: LanguageServerId,
11722        token_to_cancel: Option<ProgressToken>,
11723        cx: &mut Context<Self>,
11724    ) {
11725        if let Some(local) = self.as_local() {
11726            let status = self.language_server_statuses.get(&server_id);
11727            let server = local.language_servers.get(&server_id);
11728            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11729            {
11730                for (token, progress) in &status.pending_work {
11731                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11732                        && token != token_to_cancel
11733                    {
11734                        continue;
11735                    }
11736                    if progress.is_cancellable {
11737                        server
11738                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11739                                WorkDoneProgressCancelParams {
11740                                    token: token.to_lsp(),
11741                                },
11742                            )
11743                            .ok();
11744                    }
11745                }
11746            }
11747        } else if let Some((client, project_id)) = self.upstream_client() {
11748            let request = client.request(proto::CancelLanguageServerWork {
11749                project_id,
11750                work: Some(
11751                    proto::cancel_language_server_work::Work::LanguageServerWork(
11752                        proto::cancel_language_server_work::LanguageServerWork {
11753                            language_server_id: server_id.to_proto(),
11754                            token: token_to_cancel.map(|token| token.to_proto()),
11755                        },
11756                    ),
11757                ),
11758            });
11759            cx.background_spawn(request).detach_and_log_err(cx);
11760        }
11761    }
11762
11763    fn register_supplementary_language_server(
11764        &mut self,
11765        id: LanguageServerId,
11766        name: LanguageServerName,
11767        server: Arc<LanguageServer>,
11768        cx: &mut Context<Self>,
11769    ) {
11770        if let Some(local) = self.as_local_mut() {
11771            local
11772                .supplementary_language_servers
11773                .insert(id, (name.clone(), server));
11774            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11775        }
11776    }
11777
11778    fn unregister_supplementary_language_server(
11779        &mut self,
11780        id: LanguageServerId,
11781        cx: &mut Context<Self>,
11782    ) {
11783        if let Some(local) = self.as_local_mut() {
11784            local.supplementary_language_servers.remove(&id);
11785            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11786        }
11787    }
11788
11789    pub(crate) fn supplementary_language_servers(
11790        &self,
11791    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11792        self.as_local().into_iter().flat_map(|local| {
11793            local
11794                .supplementary_language_servers
11795                .iter()
11796                .map(|(id, (name, _))| (*id, name.clone()))
11797        })
11798    }
11799
11800    pub fn language_server_adapter_for_id(
11801        &self,
11802        id: LanguageServerId,
11803    ) -> Option<Arc<CachedLspAdapter>> {
11804        self.as_local()
11805            .and_then(|local| local.language_servers.get(&id))
11806            .and_then(|language_server_state| match language_server_state {
11807                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11808                _ => None,
11809            })
11810    }
11811
11812    pub(super) fn update_local_worktree_language_servers(
11813        &mut self,
11814        worktree_handle: &Entity<Worktree>,
11815        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11816        cx: &mut Context<Self>,
11817    ) {
11818        if changes.is_empty() {
11819            return;
11820        }
11821
11822        let Some(local) = self.as_local() else { return };
11823
11824        local.prettier_store.update(cx, |prettier_store, cx| {
11825            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11826        });
11827
11828        let worktree_id = worktree_handle.read(cx).id();
11829        let mut language_server_ids = local
11830            .language_server_ids
11831            .iter()
11832            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11833            .collect::<Vec<_>>();
11834        language_server_ids.sort();
11835        language_server_ids.dedup();
11836
11837        // let abs_path = worktree_handle.read(cx).abs_path();
11838        for server_id in &language_server_ids {
11839            if let Some(LanguageServerState::Running { server, .. }) =
11840                local.language_servers.get(server_id)
11841                && let Some(watched_paths) = local
11842                    .language_server_watched_paths
11843                    .get(server_id)
11844                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11845            {
11846                let params = lsp::DidChangeWatchedFilesParams {
11847                    changes: changes
11848                        .iter()
11849                        .filter_map(|(path, _, change)| {
11850                            if !watched_paths.is_match(path.as_std_path()) {
11851                                return None;
11852                            }
11853                            let typ = match change {
11854                                PathChange::Loaded => return None,
11855                                PathChange::Added => lsp::FileChangeType::CREATED,
11856                                PathChange::Removed => lsp::FileChangeType::DELETED,
11857                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11858                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11859                            };
11860                            let uri = lsp::Uri::from_file_path(
11861                                worktree_handle.read(cx).absolutize(&path),
11862                            )
11863                            .ok()?;
11864                            Some(lsp::FileEvent { uri, typ })
11865                        })
11866                        .collect(),
11867                };
11868                if !params.changes.is_empty() {
11869                    server
11870                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11871                        .ok();
11872                }
11873            }
11874        }
11875        for (path, _, _) in changes {
11876            if let Some(file_name) = path.file_name()
11877                && local.watched_manifest_filenames.contains(file_name)
11878            {
11879                self.request_workspace_config_refresh();
11880                break;
11881            }
11882        }
11883    }
11884
11885    pub fn wait_for_remote_buffer(
11886        &mut self,
11887        id: BufferId,
11888        cx: &mut Context<Self>,
11889    ) -> Task<Result<Entity<Buffer>>> {
11890        self.buffer_store.update(cx, |buffer_store, cx| {
11891            buffer_store.wait_for_remote_buffer(id, cx)
11892        })
11893    }
11894
11895    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11896        let mut result = proto::Symbol {
11897            language_server_name: symbol.language_server_name.0.to_string(),
11898            source_worktree_id: symbol.source_worktree_id.to_proto(),
11899            language_server_id: symbol.source_language_server_id.to_proto(),
11900            name: symbol.name.clone(),
11901            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11902            start: Some(proto::PointUtf16 {
11903                row: symbol.range.start.0.row,
11904                column: symbol.range.start.0.column,
11905            }),
11906            end: Some(proto::PointUtf16 {
11907                row: symbol.range.end.0.row,
11908                column: symbol.range.end.0.column,
11909            }),
11910            worktree_id: Default::default(),
11911            path: Default::default(),
11912            signature: Default::default(),
11913            container_name: symbol.container_name.clone(),
11914        };
11915        match &symbol.path {
11916            SymbolLocation::InProject(path) => {
11917                result.worktree_id = path.worktree_id.to_proto();
11918                result.path = path.path.to_proto();
11919            }
11920            SymbolLocation::OutsideProject {
11921                abs_path,
11922                signature,
11923            } => {
11924                result.path = abs_path.to_string_lossy().into_owned();
11925                result.signature = signature.to_vec();
11926            }
11927        }
11928        result
11929    }
11930
11931    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11932        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11933        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11934        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11935
11936        let path = if serialized_symbol.signature.is_empty() {
11937            SymbolLocation::InProject(ProjectPath {
11938                worktree_id,
11939                path: RelPath::from_proto(&serialized_symbol.path)
11940                    .context("invalid symbol path")?,
11941            })
11942        } else {
11943            SymbolLocation::OutsideProject {
11944                abs_path: Path::new(&serialized_symbol.path).into(),
11945                signature: serialized_symbol
11946                    .signature
11947                    .try_into()
11948                    .map_err(|_| anyhow!("invalid signature"))?,
11949            }
11950        };
11951
11952        let start = serialized_symbol.start.context("invalid start")?;
11953        let end = serialized_symbol.end.context("invalid end")?;
11954        Ok(CoreSymbol {
11955            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11956            source_worktree_id,
11957            source_language_server_id: LanguageServerId::from_proto(
11958                serialized_symbol.language_server_id,
11959            ),
11960            path,
11961            name: serialized_symbol.name,
11962            range: Unclipped(PointUtf16::new(start.row, start.column))
11963                ..Unclipped(PointUtf16::new(end.row, end.column)),
11964            kind,
11965            container_name: serialized_symbol.container_name,
11966        })
11967    }
11968
11969    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11970        let mut serialized_completion = proto::Completion {
11971            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11972            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11973            new_text: completion.new_text.clone(),
11974            ..proto::Completion::default()
11975        };
11976        match &completion.source {
11977            CompletionSource::Lsp {
11978                insert_range,
11979                server_id,
11980                lsp_completion,
11981                lsp_defaults,
11982                resolved,
11983            } => {
11984                let (old_insert_start, old_insert_end) = insert_range
11985                    .as_ref()
11986                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11987                    .unzip();
11988
11989                serialized_completion.old_insert_start = old_insert_start;
11990                serialized_completion.old_insert_end = old_insert_end;
11991                serialized_completion.source = proto::completion::Source::Lsp as i32;
11992                serialized_completion.server_id = server_id.0 as u64;
11993                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11994                serialized_completion.lsp_defaults = lsp_defaults
11995                    .as_deref()
11996                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11997                serialized_completion.resolved = *resolved;
11998            }
11999            CompletionSource::BufferWord {
12000                word_range,
12001                resolved,
12002            } => {
12003                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12004                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12005                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12006                serialized_completion.resolved = *resolved;
12007            }
12008            CompletionSource::Custom => {
12009                serialized_completion.source = proto::completion::Source::Custom as i32;
12010                serialized_completion.resolved = true;
12011            }
12012            CompletionSource::Dap { sort_text } => {
12013                serialized_completion.source = proto::completion::Source::Dap as i32;
12014                serialized_completion.sort_text = Some(sort_text.clone());
12015            }
12016        }
12017
12018        serialized_completion
12019    }
12020
12021    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12022        let old_replace_start = completion
12023            .old_replace_start
12024            .and_then(deserialize_anchor)
12025            .context("invalid old start")?;
12026        let old_replace_end = completion
12027            .old_replace_end
12028            .and_then(deserialize_anchor)
12029            .context("invalid old end")?;
12030        let insert_range = {
12031            match completion.old_insert_start.zip(completion.old_insert_end) {
12032                Some((start, end)) => {
12033                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12034                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12035                    Some(start..end)
12036                }
12037                None => None,
12038            }
12039        };
12040        Ok(CoreCompletion {
12041            replace_range: old_replace_start..old_replace_end,
12042            new_text: completion.new_text,
12043            source: match proto::completion::Source::from_i32(completion.source) {
12044                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12045                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12046                    insert_range,
12047                    server_id: LanguageServerId::from_proto(completion.server_id),
12048                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12049                    lsp_defaults: completion
12050                        .lsp_defaults
12051                        .as_deref()
12052                        .map(serde_json::from_slice)
12053                        .transpose()?,
12054                    resolved: completion.resolved,
12055                },
12056                Some(proto::completion::Source::BufferWord) => {
12057                    let word_range = completion
12058                        .buffer_word_start
12059                        .and_then(deserialize_anchor)
12060                        .context("invalid buffer word start")?
12061                        ..completion
12062                            .buffer_word_end
12063                            .and_then(deserialize_anchor)
12064                            .context("invalid buffer word end")?;
12065                    CompletionSource::BufferWord {
12066                        word_range,
12067                        resolved: completion.resolved,
12068                    }
12069                }
12070                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12071                    sort_text: completion
12072                        .sort_text
12073                        .context("expected sort text to exist")?,
12074                },
12075                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12076            },
12077        })
12078    }
12079
12080    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12081        let (kind, lsp_action) = match &action.lsp_action {
12082            LspAction::Action(code_action) => (
12083                proto::code_action::Kind::Action as i32,
12084                serde_json::to_vec(code_action).unwrap(),
12085            ),
12086            LspAction::Command(command) => (
12087                proto::code_action::Kind::Command as i32,
12088                serde_json::to_vec(command).unwrap(),
12089            ),
12090            LspAction::CodeLens(code_lens) => (
12091                proto::code_action::Kind::CodeLens as i32,
12092                serde_json::to_vec(code_lens).unwrap(),
12093            ),
12094        };
12095
12096        proto::CodeAction {
12097            server_id: action.server_id.0 as u64,
12098            start: Some(serialize_anchor(&action.range.start)),
12099            end: Some(serialize_anchor(&action.range.end)),
12100            lsp_action,
12101            kind,
12102            resolved: action.resolved,
12103        }
12104    }
12105
12106    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12107        let start = action
12108            .start
12109            .and_then(deserialize_anchor)
12110            .context("invalid start")?;
12111        let end = action
12112            .end
12113            .and_then(deserialize_anchor)
12114            .context("invalid end")?;
12115        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12116            Some(proto::code_action::Kind::Action) => {
12117                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12118            }
12119            Some(proto::code_action::Kind::Command) => {
12120                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12121            }
12122            Some(proto::code_action::Kind::CodeLens) => {
12123                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12124            }
12125            None => anyhow::bail!("Unknown action kind {}", action.kind),
12126        };
12127        Ok(CodeAction {
12128            server_id: LanguageServerId(action.server_id as usize),
12129            range: start..end,
12130            resolved: action.resolved,
12131            lsp_action,
12132        })
12133    }
12134
12135    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12136        match &formatting_result {
12137            Ok(_) => self.last_formatting_failure = None,
12138            Err(error) => {
12139                let error_string = format!("{error:#}");
12140                log::error!("Formatting failed: {error_string}");
12141                self.last_formatting_failure
12142                    .replace(error_string.lines().join(" "));
12143            }
12144        }
12145    }
12146
12147    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12148        self.lsp_server_capabilities.remove(&for_server);
12149        self.semantic_token_config.remove_server_data(for_server);
12150        for lsp_data in self.lsp_data.values_mut() {
12151            lsp_data.remove_server_data(for_server);
12152        }
12153        if let Some(local) = self.as_local_mut() {
12154            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12155            local
12156                .workspace_pull_diagnostics_result_ids
12157                .remove(&for_server);
12158            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12159                buffer_servers.remove(&for_server);
12160            }
12161        }
12162    }
12163
12164    pub fn result_id_for_buffer_pull(
12165        &self,
12166        server_id: LanguageServerId,
12167        buffer_id: BufferId,
12168        registration_id: &Option<SharedString>,
12169        cx: &App,
12170    ) -> Option<SharedString> {
12171        let abs_path = self
12172            .buffer_store
12173            .read(cx)
12174            .get(buffer_id)
12175            .and_then(|b| File::from_dyn(b.read(cx).file()))
12176            .map(|f| f.abs_path(cx))?;
12177        self.as_local()?
12178            .buffer_pull_diagnostics_result_ids
12179            .get(&server_id)?
12180            .get(registration_id)?
12181            .get(&abs_path)?
12182            .clone()
12183    }
12184
12185    /// Gets all result_ids for a workspace diagnostics pull request.
12186    /// 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.
12187    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12188    pub fn result_ids_for_workspace_refresh(
12189        &self,
12190        server_id: LanguageServerId,
12191        registration_id: &Option<SharedString>,
12192    ) -> HashMap<PathBuf, SharedString> {
12193        let Some(local) = self.as_local() else {
12194            return HashMap::default();
12195        };
12196        local
12197            .workspace_pull_diagnostics_result_ids
12198            .get(&server_id)
12199            .into_iter()
12200            .filter_map(|diagnostics| diagnostics.get(registration_id))
12201            .flatten()
12202            .filter_map(|(abs_path, result_id)| {
12203                let result_id = local
12204                    .buffer_pull_diagnostics_result_ids
12205                    .get(&server_id)
12206                    .and_then(|buffer_ids_result_ids| {
12207                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12208                    })
12209                    .cloned()
12210                    .flatten()
12211                    .or_else(|| result_id.clone())?;
12212                Some((abs_path.clone(), result_id))
12213            })
12214            .collect()
12215    }
12216
12217    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12218        if let Some(LanguageServerState::Running {
12219            workspace_diagnostics_refresh_tasks,
12220            ..
12221        }) = self
12222            .as_local_mut()
12223            .and_then(|local| local.language_servers.get_mut(&server_id))
12224        {
12225            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12226                diagnostics.refresh_tx.try_send(()).ok();
12227            }
12228        }
12229    }
12230
12231    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12232    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12233    /// which requires refreshing both workspace and document diagnostics.
12234    pub fn pull_document_diagnostics_for_server(
12235        &mut self,
12236        server_id: LanguageServerId,
12237        source_buffer_id: Option<BufferId>,
12238        cx: &mut Context<Self>,
12239    ) -> Shared<Task<()>> {
12240        let Some(local) = self.as_local_mut() else {
12241            return Task::ready(()).shared();
12242        };
12243        let mut buffers_to_refresh = HashSet::default();
12244        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12245            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12246                buffers_to_refresh.insert(*buffer_id);
12247            }
12248        }
12249
12250        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12251    }
12252
12253    pub fn pull_document_diagnostics_for_buffer_edit(
12254        &mut self,
12255        buffer_id: BufferId,
12256        cx: &mut Context<Self>,
12257    ) {
12258        let Some(local) = self.as_local_mut() else {
12259            return;
12260        };
12261        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12262        else {
12263            return;
12264        };
12265        for server_id in languages_servers {
12266            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12267        }
12268    }
12269
12270    fn apply_workspace_diagnostic_report(
12271        &mut self,
12272        server_id: LanguageServerId,
12273        report: lsp::WorkspaceDiagnosticReportResult,
12274        registration_id: Option<SharedString>,
12275        cx: &mut Context<Self>,
12276    ) {
12277        let mut workspace_diagnostics =
12278            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12279                report,
12280                server_id,
12281                registration_id,
12282            );
12283        workspace_diagnostics.retain(|d| match &d.diagnostics {
12284            LspPullDiagnostics::Response {
12285                server_id,
12286                registration_id,
12287                ..
12288            } => self.diagnostic_registration_exists(*server_id, registration_id),
12289            LspPullDiagnostics::Default => false,
12290        });
12291        let mut unchanged_buffers = HashMap::default();
12292        let workspace_diagnostics_updates = workspace_diagnostics
12293            .into_iter()
12294            .filter_map(
12295                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12296                    LspPullDiagnostics::Response {
12297                        server_id,
12298                        uri,
12299                        diagnostics,
12300                        registration_id,
12301                    } => Some((
12302                        server_id,
12303                        uri,
12304                        diagnostics,
12305                        workspace_diagnostics.version,
12306                        registration_id,
12307                    )),
12308                    LspPullDiagnostics::Default => None,
12309                },
12310            )
12311            .fold(
12312                HashMap::default(),
12313                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12314                    let (result_id, diagnostics) = match diagnostics {
12315                        PulledDiagnostics::Unchanged { result_id } => {
12316                            unchanged_buffers
12317                                .entry(new_registration_id.clone())
12318                                .or_insert_with(HashSet::default)
12319                                .insert(uri.clone());
12320                            (Some(result_id), Vec::new())
12321                        }
12322                        PulledDiagnostics::Changed {
12323                            result_id,
12324                            diagnostics,
12325                        } => (result_id, diagnostics),
12326                    };
12327                    let disk_based_sources = Cow::Owned(
12328                        self.language_server_adapter_for_id(server_id)
12329                            .as_ref()
12330                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12331                            .unwrap_or(&[])
12332                            .to_vec(),
12333                    );
12334
12335                    let Some(abs_path) = uri.to_file_path().ok() else {
12336                        return acc;
12337                    };
12338                    let Some((worktree, relative_path)) =
12339                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12340                    else {
12341                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12342                        return acc;
12343                    };
12344                    let worktree_id = worktree.read(cx).id();
12345                    let project_path = ProjectPath {
12346                        worktree_id,
12347                        path: relative_path,
12348                    };
12349                    if let Some(local_lsp_store) = self.as_local_mut() {
12350                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12351                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12352                    }
12353                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12354                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12355                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12356                        acc.entry(server_id)
12357                            .or_insert_with(HashMap::default)
12358                            .entry(new_registration_id.clone())
12359                            .or_insert_with(Vec::new)
12360                            .push(DocumentDiagnosticsUpdate {
12361                                server_id,
12362                                diagnostics: lsp::PublishDiagnosticsParams {
12363                                    uri,
12364                                    diagnostics,
12365                                    version,
12366                                },
12367                                result_id: result_id.map(SharedString::new),
12368                                disk_based_sources,
12369                                registration_id: new_registration_id,
12370                            });
12371                    }
12372                    acc
12373                },
12374            );
12375
12376        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12377            for (registration_id, diagnostic_updates) in diagnostic_updates {
12378                self.merge_lsp_diagnostics(
12379                    DiagnosticSourceKind::Pulled,
12380                    diagnostic_updates,
12381                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12382                        DiagnosticSourceKind::Pulled => {
12383                            old_diagnostic.registration_id != registration_id
12384                                || unchanged_buffers
12385                                    .get(&old_diagnostic.registration_id)
12386                                    .is_some_and(|unchanged_buffers| {
12387                                        unchanged_buffers.contains(&document_uri)
12388                                    })
12389                        }
12390                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12391                    },
12392                    cx,
12393                )
12394                .log_err();
12395            }
12396        }
12397    }
12398
12399    fn register_server_capabilities(
12400        &mut self,
12401        server_id: LanguageServerId,
12402        params: lsp::RegistrationParams,
12403        cx: &mut Context<Self>,
12404    ) -> anyhow::Result<()> {
12405        let server = self
12406            .language_server_for_id(server_id)
12407            .with_context(|| format!("no server {server_id} found"))?;
12408        for reg in params.registrations {
12409            match reg.method.as_str() {
12410                "workspace/didChangeWatchedFiles" => {
12411                    if let Some(options) = reg.register_options {
12412                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12413                            let caps = serde_json::from_value(options)?;
12414                            local_lsp_store
12415                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12416                            true
12417                        } else {
12418                            false
12419                        };
12420                        if notify {
12421                            notify_server_capabilities_updated(&server, cx);
12422                        }
12423                    }
12424                }
12425                "workspace/didChangeConfiguration" => {
12426                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12427                }
12428                "workspace/didChangeWorkspaceFolders" => {
12429                    // In this case register options is an empty object, we can ignore it
12430                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12431                        supported: Some(true),
12432                        change_notifications: Some(OneOf::Right(reg.id)),
12433                    };
12434                    server.update_capabilities(|capabilities| {
12435                        capabilities
12436                            .workspace
12437                            .get_or_insert_default()
12438                            .workspace_folders = Some(caps);
12439                    });
12440                    notify_server_capabilities_updated(&server, cx);
12441                }
12442                "workspace/symbol" => {
12443                    let options = parse_register_capabilities(reg)?;
12444                    server.update_capabilities(|capabilities| {
12445                        capabilities.workspace_symbol_provider = Some(options);
12446                    });
12447                    notify_server_capabilities_updated(&server, cx);
12448                }
12449                "workspace/fileOperations" => {
12450                    if let Some(options) = reg.register_options {
12451                        let caps = serde_json::from_value(options)?;
12452                        server.update_capabilities(|capabilities| {
12453                            capabilities
12454                                .workspace
12455                                .get_or_insert_default()
12456                                .file_operations = Some(caps);
12457                        });
12458                        notify_server_capabilities_updated(&server, cx);
12459                    }
12460                }
12461                "workspace/executeCommand" => {
12462                    if let Some(options) = reg.register_options {
12463                        let options = serde_json::from_value(options)?;
12464                        server.update_capabilities(|capabilities| {
12465                            capabilities.execute_command_provider = Some(options);
12466                        });
12467                        notify_server_capabilities_updated(&server, cx);
12468                    }
12469                }
12470                "textDocument/rangeFormatting" => {
12471                    let options = parse_register_capabilities(reg)?;
12472                    server.update_capabilities(|capabilities| {
12473                        capabilities.document_range_formatting_provider = Some(options);
12474                    });
12475                    notify_server_capabilities_updated(&server, cx);
12476                }
12477                "textDocument/onTypeFormatting" => {
12478                    if let Some(options) = reg
12479                        .register_options
12480                        .map(serde_json::from_value)
12481                        .transpose()?
12482                    {
12483                        server.update_capabilities(|capabilities| {
12484                            capabilities.document_on_type_formatting_provider = Some(options);
12485                        });
12486                        notify_server_capabilities_updated(&server, cx);
12487                    }
12488                }
12489                "textDocument/formatting" => {
12490                    let options = parse_register_capabilities(reg)?;
12491                    server.update_capabilities(|capabilities| {
12492                        capabilities.document_formatting_provider = Some(options);
12493                    });
12494                    notify_server_capabilities_updated(&server, cx);
12495                }
12496                "textDocument/rename" => {
12497                    let options = parse_register_capabilities(reg)?;
12498                    server.update_capabilities(|capabilities| {
12499                        capabilities.rename_provider = Some(options);
12500                    });
12501                    notify_server_capabilities_updated(&server, cx);
12502                }
12503                "textDocument/inlayHint" => {
12504                    let options = parse_register_capabilities(reg)?;
12505                    server.update_capabilities(|capabilities| {
12506                        capabilities.inlay_hint_provider = Some(options);
12507                    });
12508                    notify_server_capabilities_updated(&server, cx);
12509                }
12510                "textDocument/documentSymbol" => {
12511                    let options = parse_register_capabilities(reg)?;
12512                    server.update_capabilities(|capabilities| {
12513                        capabilities.document_symbol_provider = Some(options);
12514                    });
12515                    notify_server_capabilities_updated(&server, cx);
12516                }
12517                "textDocument/codeAction" => {
12518                    let options = parse_register_capabilities(reg)?;
12519                    let provider = match options {
12520                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12521                        OneOf::Right(caps) => caps,
12522                    };
12523                    server.update_capabilities(|capabilities| {
12524                        capabilities.code_action_provider = Some(provider);
12525                    });
12526                    notify_server_capabilities_updated(&server, cx);
12527                }
12528                "textDocument/definition" => {
12529                    let options = parse_register_capabilities(reg)?;
12530                    server.update_capabilities(|capabilities| {
12531                        capabilities.definition_provider = Some(options);
12532                    });
12533                    notify_server_capabilities_updated(&server, cx);
12534                }
12535                "textDocument/completion" => {
12536                    if let Some(caps) = reg
12537                        .register_options
12538                        .map(serde_json::from_value::<CompletionOptions>)
12539                        .transpose()?
12540                    {
12541                        server.update_capabilities(|capabilities| {
12542                            capabilities.completion_provider = Some(caps.clone());
12543                        });
12544
12545                        if let Some(local) = self.as_local() {
12546                            let mut buffers_with_language_server = Vec::new();
12547                            for handle in self.buffer_store.read(cx).buffers() {
12548                                let buffer_id = handle.read(cx).remote_id();
12549                                if local
12550                                    .buffers_opened_in_servers
12551                                    .get(&buffer_id)
12552                                    .filter(|s| s.contains(&server_id))
12553                                    .is_some()
12554                                {
12555                                    buffers_with_language_server.push(handle);
12556                                }
12557                            }
12558                            let triggers = caps
12559                                .trigger_characters
12560                                .unwrap_or_default()
12561                                .into_iter()
12562                                .collect::<BTreeSet<_>>();
12563                            for handle in buffers_with_language_server {
12564                                let triggers = triggers.clone();
12565                                let _ = handle.update(cx, move |buffer, cx| {
12566                                    buffer.set_completion_triggers(server_id, triggers, cx);
12567                                });
12568                            }
12569                        }
12570                        notify_server_capabilities_updated(&server, cx);
12571                    }
12572                }
12573                "textDocument/hover" => {
12574                    let options = parse_register_capabilities(reg)?;
12575                    let provider = match options {
12576                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12577                        OneOf::Right(caps) => caps,
12578                    };
12579                    server.update_capabilities(|capabilities| {
12580                        capabilities.hover_provider = Some(provider);
12581                    });
12582                    notify_server_capabilities_updated(&server, cx);
12583                }
12584                "textDocument/signatureHelp" => {
12585                    if let Some(caps) = reg
12586                        .register_options
12587                        .map(serde_json::from_value)
12588                        .transpose()?
12589                    {
12590                        server.update_capabilities(|capabilities| {
12591                            capabilities.signature_help_provider = Some(caps);
12592                        });
12593                        notify_server_capabilities_updated(&server, cx);
12594                    }
12595                }
12596                "textDocument/didChange" => {
12597                    if let Some(sync_kind) = reg
12598                        .register_options
12599                        .and_then(|opts| opts.get("syncKind").cloned())
12600                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12601                        .transpose()?
12602                    {
12603                        server.update_capabilities(|capabilities| {
12604                            let mut sync_options =
12605                                Self::take_text_document_sync_options(capabilities);
12606                            sync_options.change = Some(sync_kind);
12607                            capabilities.text_document_sync =
12608                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12609                        });
12610                        notify_server_capabilities_updated(&server, cx);
12611                    }
12612                }
12613                "textDocument/didSave" => {
12614                    if let Some(include_text) = reg
12615                        .register_options
12616                        .map(|opts| {
12617                            let transpose = opts
12618                                .get("includeText")
12619                                .cloned()
12620                                .map(serde_json::from_value::<Option<bool>>)
12621                                .transpose();
12622                            match transpose {
12623                                Ok(value) => Ok(value.flatten()),
12624                                Err(e) => Err(e),
12625                            }
12626                        })
12627                        .transpose()?
12628                    {
12629                        server.update_capabilities(|capabilities| {
12630                            let mut sync_options =
12631                                Self::take_text_document_sync_options(capabilities);
12632                            sync_options.save =
12633                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12634                                    include_text,
12635                                }));
12636                            capabilities.text_document_sync =
12637                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12638                        });
12639                        notify_server_capabilities_updated(&server, cx);
12640                    }
12641                }
12642                "textDocument/codeLens" => {
12643                    if let Some(caps) = reg
12644                        .register_options
12645                        .map(serde_json::from_value)
12646                        .transpose()?
12647                    {
12648                        server.update_capabilities(|capabilities| {
12649                            capabilities.code_lens_provider = Some(caps);
12650                        });
12651                        notify_server_capabilities_updated(&server, cx);
12652                    }
12653                }
12654                "textDocument/diagnostic" => {
12655                    if let Some(caps) = reg
12656                        .register_options
12657                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12658                        .transpose()?
12659                    {
12660                        let local = self
12661                            .as_local_mut()
12662                            .context("Expected LSP Store to be local")?;
12663                        let state = local
12664                            .language_servers
12665                            .get_mut(&server_id)
12666                            .context("Could not obtain Language Servers state")?;
12667                        local
12668                            .language_server_dynamic_registrations
12669                            .entry(server_id)
12670                            .or_default()
12671                            .diagnostics
12672                            .insert(Some(reg.id.clone()), caps.clone());
12673
12674                        let supports_workspace_diagnostics =
12675                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12676                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12677                                    diagnostic_options.workspace_diagnostics
12678                                }
12679                                DiagnosticServerCapabilities::RegistrationOptions(
12680                                    diagnostic_registration_options,
12681                                ) => {
12682                                    diagnostic_registration_options
12683                                        .diagnostic_options
12684                                        .workspace_diagnostics
12685                                }
12686                            };
12687
12688                        if supports_workspace_diagnostics(&caps) {
12689                            if let LanguageServerState::Running {
12690                                workspace_diagnostics_refresh_tasks,
12691                                ..
12692                            } = state
12693                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12694                                    Some(reg.id.clone()),
12695                                    caps.clone(),
12696                                    server.clone(),
12697                                    cx,
12698                                )
12699                            {
12700                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12701                            }
12702                        }
12703
12704                        server.update_capabilities(|capabilities| {
12705                            capabilities.diagnostic_provider = Some(caps);
12706                        });
12707
12708                        notify_server_capabilities_updated(&server, cx);
12709
12710                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12711                    }
12712                }
12713                "textDocument/documentColor" => {
12714                    let options = parse_register_capabilities(reg)?;
12715                    let provider = match options {
12716                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12717                        OneOf::Right(caps) => caps,
12718                    };
12719                    server.update_capabilities(|capabilities| {
12720                        capabilities.color_provider = Some(provider);
12721                    });
12722                    notify_server_capabilities_updated(&server, cx);
12723                }
12724                "textDocument/foldingRange" => {
12725                    let options = parse_register_capabilities(reg)?;
12726                    let provider = match options {
12727                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12728                        OneOf::Right(caps) => caps,
12729                    };
12730                    server.update_capabilities(|capabilities| {
12731                        capabilities.folding_range_provider = Some(provider);
12732                    });
12733                    notify_server_capabilities_updated(&server, cx);
12734                }
12735                _ => log::warn!("unhandled capability registration: {reg:?}"),
12736            }
12737        }
12738
12739        Ok(())
12740    }
12741
12742    fn unregister_server_capabilities(
12743        &mut self,
12744        server_id: LanguageServerId,
12745        params: lsp::UnregistrationParams,
12746        cx: &mut Context<Self>,
12747    ) -> anyhow::Result<()> {
12748        let server = self
12749            .language_server_for_id(server_id)
12750            .with_context(|| format!("no server {server_id} found"))?;
12751        for unreg in params.unregisterations.iter() {
12752            match unreg.method.as_str() {
12753                "workspace/didChangeWatchedFiles" => {
12754                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12755                        local_lsp_store
12756                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12757                        true
12758                    } else {
12759                        false
12760                    };
12761                    if notify {
12762                        notify_server_capabilities_updated(&server, cx);
12763                    }
12764                }
12765                "workspace/didChangeConfiguration" => {
12766                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12767                }
12768                "workspace/didChangeWorkspaceFolders" => {
12769                    server.update_capabilities(|capabilities| {
12770                        capabilities
12771                            .workspace
12772                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12773                                workspace_folders: None,
12774                                file_operations: None,
12775                            })
12776                            .workspace_folders = None;
12777                    });
12778                    notify_server_capabilities_updated(&server, cx);
12779                }
12780                "workspace/symbol" => {
12781                    server.update_capabilities(|capabilities| {
12782                        capabilities.workspace_symbol_provider = None
12783                    });
12784                    notify_server_capabilities_updated(&server, cx);
12785                }
12786                "workspace/fileOperations" => {
12787                    server.update_capabilities(|capabilities| {
12788                        capabilities
12789                            .workspace
12790                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12791                                workspace_folders: None,
12792                                file_operations: None,
12793                            })
12794                            .file_operations = None;
12795                    });
12796                    notify_server_capabilities_updated(&server, cx);
12797                }
12798                "workspace/executeCommand" => {
12799                    server.update_capabilities(|capabilities| {
12800                        capabilities.execute_command_provider = None;
12801                    });
12802                    notify_server_capabilities_updated(&server, cx);
12803                }
12804                "textDocument/rangeFormatting" => {
12805                    server.update_capabilities(|capabilities| {
12806                        capabilities.document_range_formatting_provider = None
12807                    });
12808                    notify_server_capabilities_updated(&server, cx);
12809                }
12810                "textDocument/onTypeFormatting" => {
12811                    server.update_capabilities(|capabilities| {
12812                        capabilities.document_on_type_formatting_provider = None;
12813                    });
12814                    notify_server_capabilities_updated(&server, cx);
12815                }
12816                "textDocument/formatting" => {
12817                    server.update_capabilities(|capabilities| {
12818                        capabilities.document_formatting_provider = None;
12819                    });
12820                    notify_server_capabilities_updated(&server, cx);
12821                }
12822                "textDocument/rename" => {
12823                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12824                    notify_server_capabilities_updated(&server, cx);
12825                }
12826                "textDocument/codeAction" => {
12827                    server.update_capabilities(|capabilities| {
12828                        capabilities.code_action_provider = None;
12829                    });
12830                    notify_server_capabilities_updated(&server, cx);
12831                }
12832                "textDocument/definition" => {
12833                    server.update_capabilities(|capabilities| {
12834                        capabilities.definition_provider = None;
12835                    });
12836                    notify_server_capabilities_updated(&server, cx);
12837                }
12838                "textDocument/completion" => {
12839                    server.update_capabilities(|capabilities| {
12840                        capabilities.completion_provider = None;
12841                    });
12842                    notify_server_capabilities_updated(&server, cx);
12843                }
12844                "textDocument/hover" => {
12845                    server.update_capabilities(|capabilities| {
12846                        capabilities.hover_provider = None;
12847                    });
12848                    notify_server_capabilities_updated(&server, cx);
12849                }
12850                "textDocument/signatureHelp" => {
12851                    server.update_capabilities(|capabilities| {
12852                        capabilities.signature_help_provider = None;
12853                    });
12854                    notify_server_capabilities_updated(&server, cx);
12855                }
12856                "textDocument/didChange" => {
12857                    server.update_capabilities(|capabilities| {
12858                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12859                        sync_options.change = None;
12860                        capabilities.text_document_sync =
12861                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12862                    });
12863                    notify_server_capabilities_updated(&server, cx);
12864                }
12865                "textDocument/didSave" => {
12866                    server.update_capabilities(|capabilities| {
12867                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12868                        sync_options.save = None;
12869                        capabilities.text_document_sync =
12870                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12871                    });
12872                    notify_server_capabilities_updated(&server, cx);
12873                }
12874                "textDocument/codeLens" => {
12875                    server.update_capabilities(|capabilities| {
12876                        capabilities.code_lens_provider = None;
12877                    });
12878                    notify_server_capabilities_updated(&server, cx);
12879                }
12880                "textDocument/diagnostic" => {
12881                    let local = self
12882                        .as_local_mut()
12883                        .context("Expected LSP Store to be local")?;
12884
12885                    let state = local
12886                        .language_servers
12887                        .get_mut(&server_id)
12888                        .context("Could not obtain Language Servers state")?;
12889                    let registrations = local
12890                        .language_server_dynamic_registrations
12891                        .get_mut(&server_id)
12892                        .with_context(|| {
12893                            format!("Expected dynamic registration to exist for server {server_id}")
12894                        })?;
12895                    registrations.diagnostics
12896                        .remove(&Some(unreg.id.clone()))
12897                        .with_context(|| format!(
12898                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12899                            unreg.id)
12900                        )?;
12901                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12902
12903                    if let LanguageServerState::Running {
12904                        workspace_diagnostics_refresh_tasks,
12905                        ..
12906                    } = state
12907                    {
12908                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12909                    }
12910
12911                    self.clear_unregistered_diagnostics(
12912                        server_id,
12913                        SharedString::from(unreg.id.clone()),
12914                        cx,
12915                    )?;
12916
12917                    if removed_last_diagnostic_provider {
12918                        server.update_capabilities(|capabilities| {
12919                            debug_assert!(capabilities.diagnostic_provider.is_some());
12920                            capabilities.diagnostic_provider = None;
12921                        });
12922                    }
12923
12924                    notify_server_capabilities_updated(&server, cx);
12925                }
12926                "textDocument/documentColor" => {
12927                    server.update_capabilities(|capabilities| {
12928                        capabilities.color_provider = None;
12929                    });
12930                    notify_server_capabilities_updated(&server, cx);
12931                }
12932                "textDocument/foldingRange" => {
12933                    server.update_capabilities(|capabilities| {
12934                        capabilities.folding_range_provider = None;
12935                    });
12936                    notify_server_capabilities_updated(&server, cx);
12937                }
12938                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12939            }
12940        }
12941
12942        Ok(())
12943    }
12944
12945    fn clear_unregistered_diagnostics(
12946        &mut self,
12947        server_id: LanguageServerId,
12948        cleared_registration_id: SharedString,
12949        cx: &mut Context<Self>,
12950    ) -> anyhow::Result<()> {
12951        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12952
12953        self.buffer_store.update(cx, |buffer_store, cx| {
12954            for buffer_handle in buffer_store.buffers() {
12955                let buffer = buffer_handle.read(cx);
12956                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12957                let Some(abs_path) = abs_path else {
12958                    continue;
12959                };
12960                affected_abs_paths.insert(abs_path);
12961            }
12962        });
12963
12964        let local = self.as_local().context("Expected LSP Store to be local")?;
12965        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12966            let Some(worktree) = self
12967                .worktree_store
12968                .read(cx)
12969                .worktree_for_id(*worktree_id, cx)
12970            else {
12971                continue;
12972            };
12973
12974            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12975                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12976                    let has_matching_registration =
12977                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12978                            entry.diagnostic.registration_id.as_ref()
12979                                == Some(&cleared_registration_id)
12980                        });
12981                    if has_matching_registration {
12982                        let abs_path = worktree.read(cx).absolutize(rel_path);
12983                        affected_abs_paths.insert(abs_path);
12984                    }
12985                }
12986            }
12987        }
12988
12989        if affected_abs_paths.is_empty() {
12990            return Ok(());
12991        }
12992
12993        // Send a fake diagnostic update which clears the state for the registration ID
12994        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12995            affected_abs_paths
12996                .into_iter()
12997                .map(|abs_path| DocumentDiagnosticsUpdate {
12998                    diagnostics: DocumentDiagnostics {
12999                        diagnostics: Vec::new(),
13000                        document_abs_path: abs_path,
13001                        version: None,
13002                    },
13003                    result_id: None,
13004                    registration_id: Some(cleared_registration_id.clone()),
13005                    server_id,
13006                    disk_based_sources: Cow::Borrowed(&[]),
13007                })
13008                .collect();
13009
13010        let merge_registration_id = cleared_registration_id.clone();
13011        self.merge_diagnostic_entries(
13012            clears,
13013            move |_, diagnostic, _| {
13014                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13015                    diagnostic.registration_id != Some(merge_registration_id.clone())
13016                } else {
13017                    true
13018                }
13019            },
13020            cx,
13021        )?;
13022
13023        Ok(())
13024    }
13025
13026    async fn deduplicate_range_based_lsp_requests<T>(
13027        lsp_store: &Entity<Self>,
13028        server_id: Option<LanguageServerId>,
13029        lsp_request_id: LspRequestId,
13030        proto_request: &T::ProtoRequest,
13031        range: Range<Anchor>,
13032        cx: &mut AsyncApp,
13033    ) -> Result<()>
13034    where
13035        T: LspCommand,
13036        T::ProtoRequest: proto::LspRequestMessage,
13037    {
13038        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13039        let version = deserialize_version(proto_request.buffer_version());
13040        let buffer = lsp_store.update(cx, |this, cx| {
13041            this.buffer_store.read(cx).get_existing(buffer_id)
13042        })?;
13043        buffer
13044            .update(cx, |buffer, _| buffer.wait_for_version(version))
13045            .await?;
13046        lsp_store.update(cx, |lsp_store, cx| {
13047            let buffer_snapshot = buffer.read(cx).snapshot();
13048            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13049            let chunks_queried_for = lsp_data
13050                .inlay_hints
13051                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13052                .collect::<Vec<_>>();
13053            match chunks_queried_for.as_slice() {
13054                &[chunk] => {
13055                    let key = LspKey {
13056                        request_type: TypeId::of::<T>(),
13057                        server_queried: server_id,
13058                    };
13059                    let previous_request = lsp_data
13060                        .chunk_lsp_requests
13061                        .entry(key)
13062                        .or_default()
13063                        .insert(chunk, lsp_request_id);
13064                    if let Some((previous_request, running_requests)) =
13065                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13066                    {
13067                        running_requests.remove(&previous_request);
13068                    }
13069                }
13070                _ambiguous_chunks => {
13071                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13072                    // there, a buffer version-based check will be performed and outdated requests discarded.
13073                }
13074            }
13075            anyhow::Ok(())
13076        })?;
13077
13078        Ok(())
13079    }
13080
13081    async fn query_lsp_locally<T>(
13082        lsp_store: Entity<Self>,
13083        for_server_id: Option<LanguageServerId>,
13084        sender_id: proto::PeerId,
13085        lsp_request_id: LspRequestId,
13086        proto_request: T::ProtoRequest,
13087        position: Option<Anchor>,
13088        cx: &mut AsyncApp,
13089    ) -> Result<()>
13090    where
13091        T: LspCommand + Clone,
13092        T::ProtoRequest: proto::LspRequestMessage,
13093        <T::ProtoRequest as proto::RequestMessage>::Response:
13094            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13095    {
13096        let (buffer_version, buffer) =
13097            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13098        let request =
13099            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13100        let key = LspKey {
13101            request_type: TypeId::of::<T>(),
13102            server_queried: for_server_id,
13103        };
13104        lsp_store.update(cx, |lsp_store, cx| {
13105            let request_task = match for_server_id {
13106                Some(server_id) => {
13107                    let server_task = lsp_store.request_lsp(
13108                        buffer.clone(),
13109                        LanguageServerToQuery::Other(server_id),
13110                        request.clone(),
13111                        cx,
13112                    );
13113                    cx.background_spawn(async move {
13114                        let mut responses = Vec::new();
13115                        match server_task.await {
13116                            Ok(response) => responses.push((server_id, response)),
13117                            // rust-analyzer likes to error with this when its still loading up
13118                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13119                            Err(e) => log::error!(
13120                                "Error handling response for request {request:?}: {e:#}"
13121                            ),
13122                        }
13123                        responses
13124                    })
13125                }
13126                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13127            };
13128            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13129            if T::ProtoRequest::stop_previous_requests() {
13130                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13131                    lsp_requests.clear();
13132                }
13133            }
13134            lsp_data.lsp_requests.entry(key).or_default().insert(
13135                lsp_request_id,
13136                cx.spawn(async move |lsp_store, cx| {
13137                    let response = request_task.await;
13138                    lsp_store
13139                        .update(cx, |lsp_store, cx| {
13140                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13141                            {
13142                                let response = response
13143                                    .into_iter()
13144                                    .map(|(server_id, response)| {
13145                                        (
13146                                            server_id.to_proto(),
13147                                            T::response_to_proto(
13148                                                response,
13149                                                lsp_store,
13150                                                sender_id,
13151                                                &buffer_version,
13152                                                cx,
13153                                            )
13154                                            .into(),
13155                                        )
13156                                    })
13157                                    .collect::<HashMap<_, _>>();
13158                                match client.send_lsp_response::<T::ProtoRequest>(
13159                                    project_id,
13160                                    lsp_request_id,
13161                                    response,
13162                                ) {
13163                                    Ok(()) => {}
13164                                    Err(e) => {
13165                                        log::error!("Failed to send LSP response: {e:#}",)
13166                                    }
13167                                }
13168                            }
13169                        })
13170                        .ok();
13171                }),
13172            );
13173        });
13174        Ok(())
13175    }
13176
13177    async fn wait_for_buffer_version<T>(
13178        lsp_store: &Entity<Self>,
13179        proto_request: &T::ProtoRequest,
13180        cx: &mut AsyncApp,
13181    ) -> Result<(Global, Entity<Buffer>)>
13182    where
13183        T: LspCommand,
13184        T::ProtoRequest: proto::LspRequestMessage,
13185    {
13186        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13187        let version = deserialize_version(proto_request.buffer_version());
13188        let buffer = lsp_store.update(cx, |this, cx| {
13189            this.buffer_store.read(cx).get_existing(buffer_id)
13190        })?;
13191        buffer
13192            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13193            .await?;
13194        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13195        Ok((buffer_version, buffer))
13196    }
13197
13198    fn take_text_document_sync_options(
13199        capabilities: &mut lsp::ServerCapabilities,
13200    ) -> lsp::TextDocumentSyncOptions {
13201        match capabilities.text_document_sync.take() {
13202            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13203            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13204                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13205                sync_options.change = Some(sync_kind);
13206                sync_options
13207            }
13208            None => lsp::TextDocumentSyncOptions::default(),
13209        }
13210    }
13211
13212    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13213        self.downstream_client.clone()
13214    }
13215
13216    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13217        self.worktree_store.clone()
13218    }
13219
13220    /// Gets what's stored in the LSP data for the given buffer.
13221    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13222        self.lsp_data.get_mut(&buffer_id)
13223    }
13224
13225    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13226    /// new [`BufferLspData`] will be created to replace the previous state.
13227    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13228        let (buffer_id, buffer_version) =
13229            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13230        let lsp_data = self
13231            .lsp_data
13232            .entry(buffer_id)
13233            .or_insert_with(|| BufferLspData::new(buffer, cx));
13234        if buffer_version.changed_since(&lsp_data.buffer_version) {
13235            // To send delta requests for semantic tokens, the previous tokens
13236            // need to be kept between buffer changes.
13237            let semantic_tokens = lsp_data.semantic_tokens.take();
13238            *lsp_data = BufferLspData::new(buffer, cx);
13239            lsp_data.semantic_tokens = semantic_tokens;
13240        }
13241        lsp_data
13242    }
13243}
13244
13245// Registration with registerOptions as null, should fallback to true.
13246// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13247fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13248    reg: lsp::Registration,
13249) -> Result<OneOf<bool, T>> {
13250    Ok(match reg.register_options {
13251        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13252        None => OneOf::Left(true),
13253    })
13254}
13255
13256fn subscribe_to_binary_statuses(
13257    languages: &Arc<LanguageRegistry>,
13258    cx: &mut Context<'_, LspStore>,
13259) -> Task<()> {
13260    let mut server_statuses = languages.language_server_binary_statuses();
13261    cx.spawn(async move |lsp_store, cx| {
13262        while let Some((server_name, binary_status)) = server_statuses.next().await {
13263            if lsp_store
13264                .update(cx, |_, cx| {
13265                    let mut message = None;
13266                    let binary_status = match binary_status {
13267                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13268                        BinaryStatus::CheckingForUpdate => {
13269                            proto::ServerBinaryStatus::CheckingForUpdate
13270                        }
13271                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13272                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13273                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13274                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13275                        BinaryStatus::Failed { error } => {
13276                            message = Some(error);
13277                            proto::ServerBinaryStatus::Failed
13278                        }
13279                    };
13280                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13281                        // Binary updates are about the binary that might not have any language server id at that point.
13282                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13283                        language_server_id: LanguageServerId(0),
13284                        name: Some(server_name),
13285                        message: proto::update_language_server::Variant::StatusUpdate(
13286                            proto::StatusUpdate {
13287                                message,
13288                                status: Some(proto::status_update::Status::Binary(
13289                                    binary_status as i32,
13290                                )),
13291                            },
13292                        ),
13293                    });
13294                })
13295                .is_err()
13296            {
13297                break;
13298            }
13299        }
13300    })
13301}
13302
13303fn lsp_workspace_diagnostics_refresh(
13304    registration_id: Option<String>,
13305    options: DiagnosticServerCapabilities,
13306    server: Arc<LanguageServer>,
13307    cx: &mut Context<'_, LspStore>,
13308) -> Option<WorkspaceRefreshTask> {
13309    let identifier = workspace_diagnostic_identifier(&options)?;
13310    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13311
13312    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13313    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13314    refresh_tx.try_send(()).ok();
13315
13316    let request_timeout = ProjectSettings::get_global(cx)
13317        .global_lsp_settings
13318        .get_request_timeout();
13319
13320    // 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.
13321    // This allows users to increase the duration if need be
13322    let timeout = if request_timeout != Duration::ZERO {
13323        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13324    } else {
13325        request_timeout
13326    };
13327
13328    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13329        let mut attempts = 0;
13330        let max_attempts = 50;
13331        let mut requests = 0;
13332
13333        loop {
13334            let Some(()) = refresh_rx.recv().await else {
13335                return;
13336            };
13337
13338            'request: loop {
13339                requests += 1;
13340                if attempts > max_attempts {
13341                    log::error!(
13342                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13343                    );
13344                    return;
13345                }
13346                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13347                cx.background_executor()
13348                    .timer(Duration::from_millis(backoff_millis))
13349                    .await;
13350                attempts += 1;
13351
13352                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13353                    lsp_store
13354                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13355                        .into_iter()
13356                        .filter_map(|(abs_path, result_id)| {
13357                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13358                            Some(lsp::PreviousResultId {
13359                                uri,
13360                                value: result_id.to_string(),
13361                            })
13362                        })
13363                        .collect()
13364                }) else {
13365                    return;
13366                };
13367
13368                let token = if let Some(registration_id) = &registration_id {
13369                    format!(
13370                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13371                        server.server_id(),
13372                    )
13373                } else {
13374                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13375                };
13376
13377                progress_rx.try_recv().ok();
13378                let timer = server.request_timer(timeout).fuse();
13379                let progress = pin!(progress_rx.recv().fuse());
13380                let response_result = server
13381                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13382                        lsp::WorkspaceDiagnosticParams {
13383                            previous_result_ids,
13384                            identifier: identifier.clone(),
13385                            work_done_progress_params: Default::default(),
13386                            partial_result_params: lsp::PartialResultParams {
13387                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13388                            },
13389                        },
13390                        select(timer, progress).then(|either| match either {
13391                            Either::Left((message, ..)) => ready(message).left_future(),
13392                            Either::Right(..) => pending::<String>().right_future(),
13393                        }),
13394                    )
13395                    .await;
13396
13397                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13398                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13399                match response_result {
13400                    ConnectionResult::Timeout => {
13401                        log::error!("Timeout during workspace diagnostics pull");
13402                        continue 'request;
13403                    }
13404                    ConnectionResult::ConnectionReset => {
13405                        log::error!("Server closed a workspace diagnostics pull request");
13406                        continue 'request;
13407                    }
13408                    ConnectionResult::Result(Err(e)) => {
13409                        log::error!("Error during workspace diagnostics pull: {e:#}");
13410                        break 'request;
13411                    }
13412                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13413                        attempts = 0;
13414                        if lsp_store
13415                            .update(cx, |lsp_store, cx| {
13416                                lsp_store.apply_workspace_diagnostic_report(
13417                                    server.server_id(),
13418                                    pulled_diagnostics,
13419                                    registration_id_shared.clone(),
13420                                    cx,
13421                                )
13422                            })
13423                            .is_err()
13424                        {
13425                            return;
13426                        }
13427                        break 'request;
13428                    }
13429                }
13430            }
13431        }
13432    });
13433
13434    Some(WorkspaceRefreshTask {
13435        refresh_tx,
13436        progress_tx,
13437        task: workspace_query_language_server,
13438    })
13439}
13440
13441fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13442    match &options {
13443        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13444            .identifier
13445            .as_deref()
13446            .map(SharedString::new),
13447        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13448            let diagnostic_options = &registration_options.diagnostic_options;
13449            diagnostic_options
13450                .identifier
13451                .as_deref()
13452                .map(SharedString::new)
13453        }
13454    }
13455}
13456
13457fn workspace_diagnostic_identifier(
13458    options: &DiagnosticServerCapabilities,
13459) -> Option<Option<String>> {
13460    match &options {
13461        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13462            if !diagnostic_options.workspace_diagnostics {
13463                return None;
13464            }
13465            Some(diagnostic_options.identifier.clone())
13466        }
13467        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13468            let diagnostic_options = &registration_options.diagnostic_options;
13469            if !diagnostic_options.workspace_diagnostics {
13470                return None;
13471            }
13472            Some(diagnostic_options.identifier.clone())
13473        }
13474    }
13475}
13476
13477fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13478    let CompletionSource::BufferWord {
13479        word_range,
13480        resolved,
13481    } = &mut completion.source
13482    else {
13483        return;
13484    };
13485    if *resolved {
13486        return;
13487    }
13488
13489    if completion.new_text
13490        != snapshot
13491            .text_for_range(word_range.clone())
13492            .collect::<String>()
13493    {
13494        return;
13495    }
13496
13497    let mut offset = 0;
13498    for chunk in snapshot.chunks(word_range.clone(), true) {
13499        let end_offset = offset + chunk.text.len();
13500        if let Some(highlight_id) = chunk.syntax_highlight_id {
13501            completion
13502                .label
13503                .runs
13504                .push((offset..end_offset, highlight_id));
13505        }
13506        offset = end_offset;
13507    }
13508    *resolved = true;
13509}
13510
13511impl EventEmitter<LspStoreEvent> for LspStore {}
13512
13513fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13514    hover
13515        .contents
13516        .retain(|hover_block| !hover_block.text.trim().is_empty());
13517    if hover.contents.is_empty() {
13518        None
13519    } else {
13520        Some(hover)
13521    }
13522}
13523
13524async fn populate_labels_for_completions(
13525    new_completions: Vec<CoreCompletion>,
13526    language: Option<Arc<Language>>,
13527    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13528) -> Vec<Completion> {
13529    let lsp_completions = new_completions
13530        .iter()
13531        .filter_map(|new_completion| {
13532            new_completion
13533                .source
13534                .lsp_completion(true)
13535                .map(|lsp_completion| lsp_completion.into_owned())
13536        })
13537        .collect::<Vec<_>>();
13538
13539    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13540        lsp_adapter
13541            .labels_for_completions(&lsp_completions, language)
13542            .await
13543            .log_err()
13544            .unwrap_or_default()
13545    } else {
13546        Vec::new()
13547    }
13548    .into_iter()
13549    .fuse();
13550
13551    let mut completions = Vec::new();
13552    for completion in new_completions {
13553        match completion.source.lsp_completion(true) {
13554            Some(lsp_completion) => {
13555                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13556
13557                let mut label = labels.next().flatten().unwrap_or_else(|| {
13558                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13559                });
13560                ensure_uniform_list_compatible_label(&mut label);
13561                completions.push(Completion {
13562                    label,
13563                    documentation,
13564                    replace_range: completion.replace_range,
13565                    new_text: completion.new_text,
13566                    insert_text_mode: lsp_completion.insert_text_mode,
13567                    source: completion.source,
13568                    icon_path: None,
13569                    confirm: None,
13570                    match_start: None,
13571                    snippet_deduplication_key: None,
13572                });
13573            }
13574            None => {
13575                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13576                ensure_uniform_list_compatible_label(&mut label);
13577                completions.push(Completion {
13578                    label,
13579                    documentation: None,
13580                    replace_range: completion.replace_range,
13581                    new_text: completion.new_text,
13582                    source: completion.source,
13583                    insert_text_mode: None,
13584                    icon_path: None,
13585                    confirm: None,
13586                    match_start: None,
13587                    snippet_deduplication_key: None,
13588                });
13589            }
13590        }
13591    }
13592    completions
13593}
13594
13595#[derive(Debug)]
13596pub enum LanguageServerToQuery {
13597    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13598    FirstCapable,
13599    /// Query a specific language server.
13600    Other(LanguageServerId),
13601}
13602
13603#[derive(Default)]
13604struct RenamePathsWatchedForServer {
13605    did_rename: Vec<RenameActionPredicate>,
13606    will_rename: Vec<RenameActionPredicate>,
13607}
13608
13609impl RenamePathsWatchedForServer {
13610    fn with_did_rename_patterns(
13611        mut self,
13612        did_rename: Option<&FileOperationRegistrationOptions>,
13613    ) -> Self {
13614        if let Some(did_rename) = did_rename {
13615            self.did_rename = did_rename
13616                .filters
13617                .iter()
13618                .filter_map(|filter| filter.try_into().log_err())
13619                .collect();
13620        }
13621        self
13622    }
13623    fn with_will_rename_patterns(
13624        mut self,
13625        will_rename: Option<&FileOperationRegistrationOptions>,
13626    ) -> Self {
13627        if let Some(will_rename) = will_rename {
13628            self.will_rename = will_rename
13629                .filters
13630                .iter()
13631                .filter_map(|filter| filter.try_into().log_err())
13632                .collect();
13633        }
13634        self
13635    }
13636
13637    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13638        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13639    }
13640    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13641        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13642    }
13643}
13644
13645impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13646    type Error = globset::Error;
13647    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13648        Ok(Self {
13649            kind: ops.pattern.matches.clone(),
13650            glob: GlobBuilder::new(&ops.pattern.glob)
13651                .case_insensitive(
13652                    ops.pattern
13653                        .options
13654                        .as_ref()
13655                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13656                )
13657                .build()?
13658                .compile_matcher(),
13659        })
13660    }
13661}
13662struct RenameActionPredicate {
13663    glob: GlobMatcher,
13664    kind: Option<FileOperationPatternKind>,
13665}
13666
13667impl RenameActionPredicate {
13668    // Returns true if language server should be notified
13669    fn eval(&self, path: &str, is_dir: bool) -> bool {
13670        self.kind.as_ref().is_none_or(|kind| {
13671            let expected_kind = if is_dir {
13672                FileOperationPatternKind::Folder
13673            } else {
13674                FileOperationPatternKind::File
13675            };
13676            kind == &expected_kind
13677        }) && self.glob.is_match(path)
13678    }
13679}
13680
13681#[derive(Default)]
13682struct LanguageServerWatchedPaths {
13683    worktree_paths: HashMap<WorktreeId, GlobSet>,
13684    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13685}
13686
13687#[derive(Default)]
13688struct LanguageServerWatchedPathsBuilder {
13689    worktree_paths: HashMap<WorktreeId, GlobSet>,
13690    abs_paths: HashMap<Arc<Path>, GlobSet>,
13691}
13692
13693impl LanguageServerWatchedPathsBuilder {
13694    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13695        self.worktree_paths.insert(worktree_id, glob_set);
13696    }
13697    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13698        self.abs_paths.insert(path, glob_set);
13699    }
13700    fn build(
13701        self,
13702        fs: Arc<dyn Fs>,
13703        language_server_id: LanguageServerId,
13704        cx: &mut Context<LspStore>,
13705    ) -> LanguageServerWatchedPaths {
13706        let lsp_store = cx.weak_entity();
13707
13708        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13709        let abs_paths = self
13710            .abs_paths
13711            .into_iter()
13712            .map(|(abs_path, globset)| {
13713                let task = cx.spawn({
13714                    let abs_path = abs_path.clone();
13715                    let fs = fs.clone();
13716
13717                    let lsp_store = lsp_store.clone();
13718                    async move |_, cx| {
13719                        maybe!(async move {
13720                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13721                            while let Some(update) = push_updates.0.next().await {
13722                                let action = lsp_store
13723                                    .update(cx, |this, _| {
13724                                        let Some(local) = this.as_local() else {
13725                                            return ControlFlow::Break(());
13726                                        };
13727                                        let Some(watcher) = local
13728                                            .language_server_watched_paths
13729                                            .get(&language_server_id)
13730                                        else {
13731                                            return ControlFlow::Break(());
13732                                        };
13733                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13734                                            "Watched abs path is not registered with a watcher",
13735                                        );
13736                                        let matching_entries = update
13737                                            .into_iter()
13738                                            .filter(|event| globs.is_match(&event.path))
13739                                            .collect::<Vec<_>>();
13740                                        this.lsp_notify_abs_paths_changed(
13741                                            language_server_id,
13742                                            matching_entries,
13743                                        );
13744                                        ControlFlow::Continue(())
13745                                    })
13746                                    .ok()?;
13747
13748                                if action.is_break() {
13749                                    break;
13750                                }
13751                            }
13752                            Some(())
13753                        })
13754                        .await;
13755                    }
13756                });
13757                (abs_path, (globset, task))
13758            })
13759            .collect();
13760        LanguageServerWatchedPaths {
13761            worktree_paths: self.worktree_paths,
13762            abs_paths,
13763        }
13764    }
13765}
13766
13767struct LspBufferSnapshot {
13768    version: i32,
13769    snapshot: TextBufferSnapshot,
13770}
13771
13772/// A prompt requested by LSP server.
13773#[derive(Clone, Debug)]
13774pub struct LanguageServerPromptRequest {
13775    pub id: usize,
13776    pub level: PromptLevel,
13777    pub message: String,
13778    pub actions: Vec<MessageActionItem>,
13779    pub lsp_name: String,
13780    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13781}
13782
13783impl LanguageServerPromptRequest {
13784    pub fn new(
13785        level: PromptLevel,
13786        message: String,
13787        actions: Vec<MessageActionItem>,
13788        lsp_name: String,
13789        response_channel: smol::channel::Sender<MessageActionItem>,
13790    ) -> Self {
13791        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13792        LanguageServerPromptRequest {
13793            id,
13794            level,
13795            message,
13796            actions,
13797            lsp_name,
13798            response_channel,
13799        }
13800    }
13801    pub async fn respond(self, index: usize) -> Option<()> {
13802        if let Some(response) = self.actions.into_iter().nth(index) {
13803            self.response_channel.send(response).await.ok()
13804        } else {
13805            None
13806        }
13807    }
13808
13809    #[cfg(any(test, feature = "test-support"))]
13810    pub fn test(
13811        level: PromptLevel,
13812        message: String,
13813        actions: Vec<MessageActionItem>,
13814        lsp_name: String,
13815    ) -> Self {
13816        let (tx, _rx) = smol::channel::unbounded();
13817        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13818    }
13819}
13820impl PartialEq for LanguageServerPromptRequest {
13821    fn eq(&self, other: &Self) -> bool {
13822        self.message == other.message && self.actions == other.actions
13823    }
13824}
13825
13826#[derive(Clone, Debug, PartialEq)]
13827pub enum LanguageServerLogType {
13828    Log(MessageType),
13829    Trace { verbose_info: Option<String> },
13830    Rpc { received: bool },
13831}
13832
13833impl LanguageServerLogType {
13834    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13835        match self {
13836            Self::Log(log_type) => {
13837                use proto::log_message::LogLevel;
13838                let level = match *log_type {
13839                    MessageType::ERROR => LogLevel::Error,
13840                    MessageType::WARNING => LogLevel::Warning,
13841                    MessageType::INFO => LogLevel::Info,
13842                    MessageType::LOG => LogLevel::Log,
13843                    other => {
13844                        log::warn!("Unknown lsp log message type: {other:?}");
13845                        LogLevel::Log
13846                    }
13847                };
13848                proto::language_server_log::LogType::Log(proto::LogMessage {
13849                    level: level as i32,
13850                })
13851            }
13852            Self::Trace { verbose_info } => {
13853                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13854                    verbose_info: verbose_info.to_owned(),
13855                })
13856            }
13857            Self::Rpc { received } => {
13858                let kind = if *received {
13859                    proto::rpc_message::Kind::Received
13860                } else {
13861                    proto::rpc_message::Kind::Sent
13862                };
13863                let kind = kind as i32;
13864                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13865            }
13866        }
13867    }
13868
13869    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13870        use proto::log_message::LogLevel;
13871        use proto::rpc_message;
13872        match log_type {
13873            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13874                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13875                    LogLevel::Error => MessageType::ERROR,
13876                    LogLevel::Warning => MessageType::WARNING,
13877                    LogLevel::Info => MessageType::INFO,
13878                    LogLevel::Log => MessageType::LOG,
13879                },
13880            ),
13881            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13882                verbose_info: trace_message.verbose_info,
13883            },
13884            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13885                received: match rpc_message::Kind::from_i32(message.kind)
13886                    .unwrap_or(rpc_message::Kind::Received)
13887                {
13888                    rpc_message::Kind::Received => true,
13889                    rpc_message::Kind::Sent => false,
13890                },
13891            },
13892        }
13893    }
13894}
13895
13896pub struct WorkspaceRefreshTask {
13897    refresh_tx: mpsc::Sender<()>,
13898    progress_tx: mpsc::Sender<()>,
13899    #[allow(dead_code)]
13900    task: Task<()>,
13901}
13902
13903pub enum LanguageServerState {
13904    Starting {
13905        startup: Task<Option<Arc<LanguageServer>>>,
13906        /// List of language servers that will be added to the workspace once it's initialization completes.
13907        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13908    },
13909
13910    Running {
13911        adapter: Arc<CachedLspAdapter>,
13912        server: Arc<LanguageServer>,
13913        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13914        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13915    },
13916}
13917
13918impl LanguageServerState {
13919    fn add_workspace_folder(&self, uri: Uri) {
13920        match self {
13921            LanguageServerState::Starting {
13922                pending_workspace_folders,
13923                ..
13924            } => {
13925                pending_workspace_folders.lock().insert(uri);
13926            }
13927            LanguageServerState::Running { server, .. } => {
13928                server.add_workspace_folder(uri);
13929            }
13930        }
13931    }
13932    fn _remove_workspace_folder(&self, uri: Uri) {
13933        match self {
13934            LanguageServerState::Starting {
13935                pending_workspace_folders,
13936                ..
13937            } => {
13938                pending_workspace_folders.lock().remove(&uri);
13939            }
13940            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13941        }
13942    }
13943}
13944
13945impl std::fmt::Debug for LanguageServerState {
13946    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13947        match self {
13948            LanguageServerState::Starting { .. } => {
13949                f.debug_struct("LanguageServerState::Starting").finish()
13950            }
13951            LanguageServerState::Running { .. } => {
13952                f.debug_struct("LanguageServerState::Running").finish()
13953            }
13954        }
13955    }
13956}
13957
13958#[derive(Clone, Debug, Serialize)]
13959pub struct LanguageServerProgress {
13960    pub is_disk_based_diagnostics_progress: bool,
13961    pub is_cancellable: bool,
13962    pub title: Option<String>,
13963    pub message: Option<String>,
13964    pub percentage: Option<usize>,
13965    #[serde(skip_serializing)]
13966    pub last_update_at: Instant,
13967}
13968
13969#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13970pub struct DiagnosticSummary {
13971    pub error_count: usize,
13972    pub warning_count: usize,
13973}
13974
13975impl DiagnosticSummary {
13976    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13977        let mut this = Self {
13978            error_count: 0,
13979            warning_count: 0,
13980        };
13981
13982        for entry in diagnostics {
13983            if entry.diagnostic.is_primary {
13984                match entry.diagnostic.severity {
13985                    DiagnosticSeverity::ERROR => this.error_count += 1,
13986                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13987                    _ => {}
13988                }
13989            }
13990        }
13991
13992        this
13993    }
13994
13995    pub fn is_empty(&self) -> bool {
13996        self.error_count == 0 && self.warning_count == 0
13997    }
13998
13999    pub fn to_proto(
14000        self,
14001        language_server_id: LanguageServerId,
14002        path: &RelPath,
14003    ) -> proto::DiagnosticSummary {
14004        proto::DiagnosticSummary {
14005            path: path.to_proto(),
14006            language_server_id: language_server_id.0 as u64,
14007            error_count: self.error_count as u32,
14008            warning_count: self.warning_count as u32,
14009        }
14010    }
14011}
14012
14013#[derive(Clone, Debug)]
14014pub enum CompletionDocumentation {
14015    /// There is no documentation for this completion.
14016    Undocumented,
14017    /// A single line of documentation.
14018    SingleLine(SharedString),
14019    /// Multiple lines of plain text documentation.
14020    MultiLinePlainText(SharedString),
14021    /// Markdown documentation.
14022    MultiLineMarkdown(SharedString),
14023    /// Both single line and multiple lines of plain text documentation.
14024    SingleLineAndMultiLinePlainText {
14025        single_line: SharedString,
14026        plain_text: Option<SharedString>,
14027    },
14028}
14029
14030impl CompletionDocumentation {
14031    #[cfg(any(test, feature = "test-support"))]
14032    pub fn text(&self) -> SharedString {
14033        match self {
14034            CompletionDocumentation::Undocumented => "".into(),
14035            CompletionDocumentation::SingleLine(s) => s.clone(),
14036            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14037            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14038            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14039                single_line.clone()
14040            }
14041        }
14042    }
14043}
14044
14045impl From<lsp::Documentation> for CompletionDocumentation {
14046    fn from(docs: lsp::Documentation) -> Self {
14047        match docs {
14048            lsp::Documentation::String(text) => {
14049                if text.lines().count() <= 1 {
14050                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14051                } else {
14052                    CompletionDocumentation::MultiLinePlainText(text.into())
14053                }
14054            }
14055
14056            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14057                lsp::MarkupKind::PlainText => {
14058                    if value.lines().count() <= 1 {
14059                        CompletionDocumentation::SingleLine(value.into())
14060                    } else {
14061                        CompletionDocumentation::MultiLinePlainText(value.into())
14062                    }
14063                }
14064
14065                lsp::MarkupKind::Markdown => {
14066                    CompletionDocumentation::MultiLineMarkdown(value.into())
14067                }
14068            },
14069        }
14070    }
14071}
14072
14073pub enum ResolvedHint {
14074    Resolved(InlayHint),
14075    Resolving(Shared<Task<()>>),
14076}
14077
14078pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14079    glob.components()
14080        .take_while(|component| match component {
14081            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14082            _ => true,
14083        })
14084        .collect()
14085}
14086
14087pub struct SshLspAdapter {
14088    name: LanguageServerName,
14089    binary: LanguageServerBinary,
14090    initialization_options: Option<String>,
14091    code_action_kinds: Option<Vec<CodeActionKind>>,
14092}
14093
14094impl SshLspAdapter {
14095    pub fn new(
14096        name: LanguageServerName,
14097        binary: LanguageServerBinary,
14098        initialization_options: Option<String>,
14099        code_action_kinds: Option<String>,
14100    ) -> Self {
14101        Self {
14102            name,
14103            binary,
14104            initialization_options,
14105            code_action_kinds: code_action_kinds
14106                .as_ref()
14107                .and_then(|c| serde_json::from_str(c).ok()),
14108        }
14109    }
14110}
14111
14112impl LspInstaller for SshLspAdapter {
14113    type BinaryVersion = ();
14114    async fn check_if_user_installed(
14115        &self,
14116        _: &dyn LspAdapterDelegate,
14117        _: Option<Toolchain>,
14118        _: &AsyncApp,
14119    ) -> Option<LanguageServerBinary> {
14120        Some(self.binary.clone())
14121    }
14122
14123    async fn cached_server_binary(
14124        &self,
14125        _: PathBuf,
14126        _: &dyn LspAdapterDelegate,
14127    ) -> Option<LanguageServerBinary> {
14128        None
14129    }
14130
14131    async fn fetch_latest_server_version(
14132        &self,
14133        _: &dyn LspAdapterDelegate,
14134        _: bool,
14135        _: &mut AsyncApp,
14136    ) -> Result<()> {
14137        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14138    }
14139
14140    async fn fetch_server_binary(
14141        &self,
14142        _: (),
14143        _: PathBuf,
14144        _: &dyn LspAdapterDelegate,
14145    ) -> Result<LanguageServerBinary> {
14146        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14147    }
14148}
14149
14150#[async_trait(?Send)]
14151impl LspAdapter for SshLspAdapter {
14152    fn name(&self) -> LanguageServerName {
14153        self.name.clone()
14154    }
14155
14156    async fn initialization_options(
14157        self: Arc<Self>,
14158        _: &Arc<dyn LspAdapterDelegate>,
14159        _: &mut AsyncApp,
14160    ) -> Result<Option<serde_json::Value>> {
14161        let Some(options) = &self.initialization_options else {
14162            return Ok(None);
14163        };
14164        let result = serde_json::from_str(options)?;
14165        Ok(result)
14166    }
14167
14168    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14169        self.code_action_kinds.clone()
14170    }
14171}
14172
14173pub fn language_server_settings<'a>(
14174    delegate: &'a dyn LspAdapterDelegate,
14175    language: &LanguageServerName,
14176    cx: &'a App,
14177) -> Option<&'a LspSettings> {
14178    language_server_settings_for(
14179        SettingsLocation {
14180            worktree_id: delegate.worktree_id(),
14181            path: RelPath::empty(),
14182        },
14183        language,
14184        cx,
14185    )
14186}
14187
14188pub fn language_server_settings_for<'a>(
14189    location: SettingsLocation<'a>,
14190    language: &LanguageServerName,
14191    cx: &'a App,
14192) -> Option<&'a LspSettings> {
14193    ProjectSettings::get(Some(location), cx).lsp.get(language)
14194}
14195
14196pub struct LocalLspAdapterDelegate {
14197    lsp_store: WeakEntity<LspStore>,
14198    worktree: worktree::Snapshot,
14199    fs: Arc<dyn Fs>,
14200    http_client: Arc<dyn HttpClient>,
14201    language_registry: Arc<LanguageRegistry>,
14202    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14203}
14204
14205impl LocalLspAdapterDelegate {
14206    pub fn new(
14207        language_registry: Arc<LanguageRegistry>,
14208        environment: &Entity<ProjectEnvironment>,
14209        lsp_store: WeakEntity<LspStore>,
14210        worktree: &Entity<Worktree>,
14211        http_client: Arc<dyn HttpClient>,
14212        fs: Arc<dyn Fs>,
14213        cx: &mut App,
14214    ) -> Arc<Self> {
14215        let load_shell_env_task =
14216            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14217
14218        Arc::new(Self {
14219            lsp_store,
14220            worktree: worktree.read(cx).snapshot(),
14221            fs,
14222            http_client,
14223            language_registry,
14224            load_shell_env_task,
14225        })
14226    }
14227
14228    pub fn from_local_lsp(
14229        local: &LocalLspStore,
14230        worktree: &Entity<Worktree>,
14231        cx: &mut App,
14232    ) -> Arc<Self> {
14233        Self::new(
14234            local.languages.clone(),
14235            &local.environment,
14236            local.weak.clone(),
14237            worktree,
14238            local.http_client.clone(),
14239            local.fs.clone(),
14240            cx,
14241        )
14242    }
14243}
14244
14245#[async_trait]
14246impl LspAdapterDelegate for LocalLspAdapterDelegate {
14247    fn show_notification(&self, message: &str, cx: &mut App) {
14248        self.lsp_store
14249            .update(cx, |_, cx| {
14250                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14251            })
14252            .ok();
14253    }
14254
14255    fn http_client(&self) -> Arc<dyn HttpClient> {
14256        self.http_client.clone()
14257    }
14258
14259    fn worktree_id(&self) -> WorktreeId {
14260        self.worktree.id()
14261    }
14262
14263    fn worktree_root_path(&self) -> &Path {
14264        self.worktree.abs_path().as_ref()
14265    }
14266
14267    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14268        self.worktree.resolve_relative_path(path)
14269    }
14270
14271    async fn shell_env(&self) -> HashMap<String, String> {
14272        let task = self.load_shell_env_task.clone();
14273        task.await.unwrap_or_default()
14274    }
14275
14276    async fn npm_package_installed_version(
14277        &self,
14278        package_name: &str,
14279    ) -> Result<Option<(PathBuf, Version)>> {
14280        let local_package_directory = self.worktree_root_path();
14281        let node_modules_directory = local_package_directory.join("node_modules");
14282
14283        if let Some(version) =
14284            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14285        {
14286            return Ok(Some((node_modules_directory, version)));
14287        }
14288        let Some(npm) = self.which("npm".as_ref()).await else {
14289            log::warn!(
14290                "Failed to find npm executable for {:?}",
14291                local_package_directory
14292            );
14293            return Ok(None);
14294        };
14295
14296        let env = self.shell_env().await;
14297        let output = util::command::new_command(&npm)
14298            .args(["root", "-g"])
14299            .envs(env)
14300            .current_dir(local_package_directory)
14301            .output()
14302            .await?;
14303        let global_node_modules =
14304            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14305
14306        if let Some(version) =
14307            read_package_installed_version(global_node_modules.clone(), package_name).await?
14308        {
14309            return Ok(Some((global_node_modules, version)));
14310        }
14311        return Ok(None);
14312    }
14313
14314    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14315        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14316        if self.fs.is_file(&worktree_abs_path).await {
14317            worktree_abs_path.pop();
14318        }
14319
14320        let env = self.shell_env().await;
14321
14322        let shell_path = env.get("PATH").cloned();
14323
14324        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14325    }
14326
14327    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14328        let mut working_dir = self.worktree_root_path().to_path_buf();
14329        if self.fs.is_file(&working_dir).await {
14330            working_dir.pop();
14331        }
14332        let output = util::command::new_command(&command.path)
14333            .args(command.arguments)
14334            .envs(command.env.clone().unwrap_or_default())
14335            .current_dir(working_dir)
14336            .output()
14337            .await?;
14338
14339        anyhow::ensure!(
14340            output.status.success(),
14341            "{}, stdout: {:?}, stderr: {:?}",
14342            output.status,
14343            String::from_utf8_lossy(&output.stdout),
14344            String::from_utf8_lossy(&output.stderr)
14345        );
14346        Ok(())
14347    }
14348
14349    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14350        self.language_registry
14351            .update_lsp_binary_status(server_name, status);
14352    }
14353
14354    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14355        self.language_registry
14356            .all_lsp_adapters()
14357            .into_iter()
14358            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14359            .collect()
14360    }
14361
14362    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14363        let dir = self.language_registry.language_server_download_dir(name)?;
14364
14365        if !dir.exists() {
14366            smol::fs::create_dir_all(&dir)
14367                .await
14368                .context("failed to create container directory")
14369                .log_err()?;
14370        }
14371
14372        Some(dir)
14373    }
14374
14375    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14376        let entry = self
14377            .worktree
14378            .entry_for_path(path)
14379            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14380        let abs_path = self.worktree.absolutize(&entry.path);
14381        self.fs.load(&abs_path).await
14382    }
14383}
14384
14385async fn populate_labels_for_symbols(
14386    symbols: Vec<CoreSymbol>,
14387    language_registry: &Arc<LanguageRegistry>,
14388    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14389    output: &mut Vec<Symbol>,
14390) {
14391    #[allow(clippy::mutable_key_type)]
14392    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14393
14394    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14395    for symbol in symbols {
14396        let Some(file_name) = symbol.path.file_name() else {
14397            continue;
14398        };
14399        let language = language_registry
14400            .load_language_for_file_path(Path::new(file_name))
14401            .await
14402            .ok()
14403            .or_else(|| {
14404                unknown_paths.insert(file_name.into());
14405                None
14406            });
14407        symbols_by_language
14408            .entry(language)
14409            .or_default()
14410            .push(symbol);
14411    }
14412
14413    for unknown_path in unknown_paths {
14414        log::info!("no language found for symbol in file {unknown_path:?}");
14415    }
14416
14417    let mut label_params = Vec::new();
14418    for (language, mut symbols) in symbols_by_language {
14419        label_params.clear();
14420        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14421            name: mem::take(&mut symbol.name),
14422            kind: symbol.kind,
14423            container_name: symbol.container_name.take(),
14424        }));
14425
14426        let mut labels = Vec::new();
14427        if let Some(language) = language {
14428            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14429                language_registry
14430                    .lsp_adapters(&language.name())
14431                    .first()
14432                    .cloned()
14433            });
14434            if let Some(lsp_adapter) = lsp_adapter {
14435                labels = lsp_adapter
14436                    .labels_for_symbols(&label_params, &language)
14437                    .await
14438                    .log_err()
14439                    .unwrap_or_default();
14440            }
14441        }
14442
14443        for (
14444            (
14445                symbol,
14446                language::Symbol {
14447                    name,
14448                    container_name,
14449                    ..
14450                },
14451            ),
14452            label,
14453        ) in symbols
14454            .into_iter()
14455            .zip(label_params.drain(..))
14456            .zip(labels.into_iter().chain(iter::repeat(None)))
14457        {
14458            output.push(Symbol {
14459                language_server_name: symbol.language_server_name,
14460                source_worktree_id: symbol.source_worktree_id,
14461                source_language_server_id: symbol.source_language_server_id,
14462                path: symbol.path,
14463                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14464                name,
14465                kind: symbol.kind,
14466                range: symbol.range,
14467                container_name,
14468            });
14469        }
14470    }
14471}
14472
14473pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14474    text.lines()
14475        .map(|line| line.trim())
14476        .filter(|line| !line.is_empty())
14477        .join(separator)
14478}
14479
14480fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14481    match server.capabilities().text_document_sync.as_ref()? {
14482        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14483            // Server wants didSave but didn't specify includeText.
14484            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14485            // Server doesn't want didSave at all.
14486            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14487            // Server provided SaveOptions.
14488            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14489                Some(save_options.include_text.unwrap_or(false))
14490            }
14491        },
14492        // We do not have any save info. Kind affects didChange only.
14493        lsp::TextDocumentSyncCapability::Kind(_) => None,
14494    }
14495}
14496
14497/// Completion items are displayed in a `UniformList`.
14498/// Usually, those items are single-line strings, but in LSP responses,
14499/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14500/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14501/// 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,
14502/// breaking the completions menu presentation.
14503///
14504/// 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.
14505pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14506    let mut new_text = String::with_capacity(label.text.len());
14507    let mut offset_map = vec![0; label.text.len() + 1];
14508    let mut last_char_was_space = false;
14509    let mut new_idx = 0;
14510    let chars = label.text.char_indices().fuse();
14511    let mut newlines_removed = false;
14512
14513    for (idx, c) in chars {
14514        offset_map[idx] = new_idx;
14515
14516        match c {
14517            '\n' if last_char_was_space => {
14518                newlines_removed = true;
14519            }
14520            '\t' | ' ' if last_char_was_space => {}
14521            '\n' if !last_char_was_space => {
14522                new_text.push(' ');
14523                new_idx += 1;
14524                last_char_was_space = true;
14525                newlines_removed = true;
14526            }
14527            ' ' | '\t' => {
14528                new_text.push(' ');
14529                new_idx += 1;
14530                last_char_was_space = true;
14531            }
14532            _ => {
14533                new_text.push(c);
14534                new_idx += c.len_utf8();
14535                last_char_was_space = false;
14536            }
14537        }
14538    }
14539    offset_map[label.text.len()] = new_idx;
14540
14541    // Only modify the label if newlines were removed.
14542    if !newlines_removed {
14543        return;
14544    }
14545
14546    let last_index = new_idx;
14547    let mut run_ranges_errors = Vec::new();
14548    label.runs.retain_mut(|(range, _)| {
14549        match offset_map.get(range.start) {
14550            Some(&start) => range.start = start,
14551            None => {
14552                run_ranges_errors.push(range.clone());
14553                return false;
14554            }
14555        }
14556
14557        match offset_map.get(range.end) {
14558            Some(&end) => range.end = end,
14559            None => {
14560                run_ranges_errors.push(range.clone());
14561                range.end = last_index;
14562            }
14563        }
14564        true
14565    });
14566    if !run_ranges_errors.is_empty() {
14567        log::error!(
14568            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14569            label.text
14570        );
14571    }
14572
14573    let mut wrong_filter_range = None;
14574    if label.filter_range == (0..label.text.len()) {
14575        label.filter_range = 0..new_text.len();
14576    } else {
14577        let mut original_filter_range = Some(label.filter_range.clone());
14578        match offset_map.get(label.filter_range.start) {
14579            Some(&start) => label.filter_range.start = start,
14580            None => {
14581                wrong_filter_range = original_filter_range.take();
14582                label.filter_range.start = last_index;
14583            }
14584        }
14585
14586        match offset_map.get(label.filter_range.end) {
14587            Some(&end) => label.filter_range.end = end,
14588            None => {
14589                wrong_filter_range = original_filter_range.take();
14590                label.filter_range.end = last_index;
14591            }
14592        }
14593    }
14594    if let Some(wrong_filter_range) = wrong_filter_range {
14595        log::error!(
14596            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14597            label.text
14598        );
14599    }
14600
14601    label.text = new_text;
14602}
14603
14604/// Apply edits to the buffer that will become part of the formatting transaction.
14605/// Fails if the buffer has been edited since the start of that transaction.
14606fn extend_formatting_transaction(
14607    buffer: &FormattableBuffer,
14608    formatting_transaction_id: text::TransactionId,
14609    cx: &mut AsyncApp,
14610    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14611) -> anyhow::Result<()> {
14612    buffer.handle.update(cx, |buffer, cx| {
14613        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14614        if last_transaction_id != Some(formatting_transaction_id) {
14615            anyhow::bail!("Buffer edited while formatting. Aborting")
14616        }
14617        buffer.start_transaction();
14618        operation(buffer, cx);
14619        if let Some(transaction_id) = buffer.end_transaction(cx) {
14620            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14621        }
14622        Ok(())
14623    })
14624}