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 folding_ranges;
   16mod inlay_hints;
   17pub mod json_language_server_ext;
   18pub mod log_store;
   19pub mod lsp_ext_command;
   20pub mod rust_analyzer_ext;
   21mod semantic_tokens;
   22pub mod vue_language_server_ext;
   23
   24use self::code_lens::CodeLensData;
   25use self::document_colors::DocumentColorData;
   26use self::inlay_hints::BufferInlayHints;
   27use crate::{
   28    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   29    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   30    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   31    PulledDiagnostics, ResolveState, Symbol,
   32    buffer_store::{BufferStore, BufferStoreEvent},
   33    environment::ProjectEnvironment,
   34    lsp_command::{self, *},
   35    lsp_store::{
   36        self,
   37        folding_ranges::FoldingRangeData,
   38        log_store::{GlobalLogStore, LanguageServerKind},
   39        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   40    },
   41    manifest_tree::{
   42        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   43        ManifestTree,
   44    },
   45    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   46    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   47    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   48    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   49    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   50    yarn::YarnPathStore,
   51};
   52use anyhow::{Context as _, Result, anyhow};
   53use async_trait::async_trait;
   54use client::{TypedEnvelope, proto};
   55use clock::Global;
   56use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   57use futures::{
   58    AsyncWriteExt, Future, FutureExt, StreamExt,
   59    future::{Either, Shared, join_all, pending, select},
   60    select, select_biased,
   61    stream::FuturesUnordered,
   62};
   63use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   64use gpui::{
   65    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   66    Subscription, Task, WeakEntity,
   67};
   68use http_client::HttpClient;
   69use itertools::Itertools as _;
   70use language::{
   71    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   72    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   73    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   74    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   75    Toolchain, Transaction, Unclipped,
   76    language_settings::{
   77        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   78        language_settings,
   79    },
   80    point_to_lsp,
   81    proto::{
   82        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   83        serialize_anchor_range, serialize_version,
   84    },
   85    range_from_lsp, range_to_lsp,
   86    row_chunk::RowChunk,
   87};
   88use lsp::{
   89    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   90    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   91    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   92    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   93    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   94    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   95    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   96    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   97};
   98use node_runtime::read_package_installed_version;
   99use parking_lot::Mutex;
  100use postage::{mpsc, sink::Sink, stream::Stream, watch};
  101use rand::prelude::*;
  102use rpc::{
  103    AnyProtoClient, ErrorCode, ErrorExt as _,
  104    proto::{LspRequestId, LspRequestMessage as _},
  105};
  106use semver::Version;
  107use serde::Serialize;
  108use serde_json::Value;
  109use settings::{Settings, SettingsLocation, SettingsStore};
  110use sha2::{Digest, Sha256};
  111use snippet::Snippet;
  112use std::{
  113    any::TypeId,
  114    borrow::Cow,
  115    cell::RefCell,
  116    cmp::{Ordering, Reverse},
  117    collections::{VecDeque, hash_map},
  118    convert::TryInto,
  119    ffi::OsStr,
  120    future::ready,
  121    iter, mem,
  122    ops::{ControlFlow, Range},
  123    path::{self, Path, PathBuf},
  124    pin::pin,
  125    rc::Rc,
  126    sync::{
  127        Arc,
  128        atomic::{self, AtomicUsize},
  129    },
  130    time::{Duration, Instant},
  131    vec,
  132};
  133use sum_tree::Dimensions;
  134use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  135
  136use util::{
  137    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  138    paths::{PathStyle, SanitizedPath, UrlExt},
  139    post_inc,
  140    redact::redact_command,
  141    rel_path::RelPath,
  142};
  143
  144pub use document_colors::DocumentColors;
  145pub use folding_ranges::LspFoldingRange;
  146pub use fs::*;
  147pub use language::Location;
  148pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  149#[cfg(any(test, feature = "test-support"))]
  150pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  151pub use semantic_tokens::{
  152    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  153};
  154
  155pub use worktree::{
  156    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  157    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  158};
  159
  160const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  161pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  162const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  163const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  164static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  165
  166#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  167pub enum ProgressToken {
  168    Number(i32),
  169    String(SharedString),
  170}
  171
  172impl std::fmt::Display for ProgressToken {
  173    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  174        match self {
  175            Self::Number(number) => write!(f, "{number}"),
  176            Self::String(string) => write!(f, "{string}"),
  177        }
  178    }
  179}
  180
  181impl ProgressToken {
  182    fn from_lsp(value: lsp::NumberOrString) -> Self {
  183        match value {
  184            lsp::NumberOrString::Number(number) => Self::Number(number),
  185            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  186        }
  187    }
  188
  189    fn to_lsp(&self) -> lsp::NumberOrString {
  190        match self {
  191            Self::Number(number) => lsp::NumberOrString::Number(*number),
  192            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  193        }
  194    }
  195
  196    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  197        Some(match value.value? {
  198            proto::progress_token::Value::Number(number) => Self::Number(number),
  199            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  200        })
  201    }
  202
  203    fn to_proto(&self) -> proto::ProgressToken {
  204        proto::ProgressToken {
  205            value: Some(match self {
  206                Self::Number(number) => proto::progress_token::Value::Number(*number),
  207                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  208            }),
  209        }
  210    }
  211}
  212
  213#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  214pub enum FormatTrigger {
  215    Save,
  216    Manual,
  217}
  218
  219pub enum LspFormatTarget {
  220    Buffers,
  221    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  222}
  223
  224#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  225pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  226
  227struct OpenLspBuffer(Entity<Buffer>);
  228
  229impl FormatTrigger {
  230    fn from_proto(value: i32) -> FormatTrigger {
  231        match value {
  232            0 => FormatTrigger::Save,
  233            1 => FormatTrigger::Manual,
  234            _ => FormatTrigger::Save,
  235        }
  236    }
  237}
  238
  239#[derive(Clone)]
  240struct UnifiedLanguageServer {
  241    id: LanguageServerId,
  242    project_roots: HashSet<Arc<RelPath>>,
  243}
  244
  245/// Settings that affect language server identity.
  246///
  247/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  248/// updated via `workspace/didChangeConfiguration` without restarting the server.
  249#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  250struct LanguageServerSeedSettings {
  251    binary: Option<BinarySettings>,
  252    initialization_options: Option<serde_json::Value>,
  253}
  254
  255#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  256struct LanguageServerSeed {
  257    worktree_id: WorktreeId,
  258    name: LanguageServerName,
  259    toolchain: Option<Toolchain>,
  260    settings: LanguageServerSeedSettings,
  261}
  262
  263#[derive(Debug)]
  264pub struct DocumentDiagnosticsUpdate<'a, D> {
  265    pub diagnostics: D,
  266    pub result_id: Option<SharedString>,
  267    pub registration_id: Option<SharedString>,
  268    pub server_id: LanguageServerId,
  269    pub disk_based_sources: Cow<'a, [String]>,
  270}
  271
  272pub struct DocumentDiagnostics {
  273    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  274    document_abs_path: PathBuf,
  275    version: Option<i32>,
  276}
  277
  278#[derive(Default, Debug)]
  279struct DynamicRegistrations {
  280    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  281    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  282}
  283
  284pub struct LocalLspStore {
  285    weak: WeakEntity<LspStore>,
  286    pub worktree_store: Entity<WorktreeStore>,
  287    toolchain_store: Entity<LocalToolchainStore>,
  288    http_client: Arc<dyn HttpClient>,
  289    environment: Entity<ProjectEnvironment>,
  290    fs: Arc<dyn Fs>,
  291    languages: Arc<LanguageRegistry>,
  292    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  293    yarn: Entity<YarnPathStore>,
  294    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  295    buffers_being_formatted: HashSet<BufferId>,
  296    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  297    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  298    watched_manifest_filenames: HashSet<ManifestName>,
  299    language_server_paths_watched_for_rename:
  300        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  301    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  302    supplementary_language_servers:
  303        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  304    prettier_store: Entity<PrettierStore>,
  305    next_diagnostic_group_id: usize,
  306    diagnostics: HashMap<
  307        WorktreeId,
  308        HashMap<
  309            Arc<RelPath>,
  310            Vec<(
  311                LanguageServerId,
  312                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  313            )>,
  314        >,
  315    >,
  316    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  317    _subscription: gpui::Subscription,
  318    lsp_tree: LanguageServerTree,
  319    registered_buffers: HashMap<BufferId, usize>,
  320    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  321    buffer_pull_diagnostics_result_ids: HashMap<
  322        LanguageServerId,
  323        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  324    >,
  325    workspace_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  330
  331    buffers_to_refresh_hash_set: HashSet<BufferId>,
  332    buffers_to_refresh_queue: VecDeque<BufferId>,
  333    _background_diagnostics_worker: Shared<Task<()>>,
  334}
  335
  336impl LocalLspStore {
  337    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  338    pub fn running_language_server_for_id(
  339        &self,
  340        id: LanguageServerId,
  341    ) -> Option<&Arc<LanguageServer>> {
  342        let language_server_state = self.language_servers.get(&id)?;
  343
  344        match language_server_state {
  345            LanguageServerState::Running { server, .. } => Some(server),
  346            LanguageServerState::Starting { .. } => None,
  347        }
  348    }
  349
  350    fn get_or_insert_language_server(
  351        &mut self,
  352        worktree_handle: &Entity<Worktree>,
  353        delegate: Arc<LocalLspAdapterDelegate>,
  354        disposition: &Arc<LaunchDisposition>,
  355        language_name: &LanguageName,
  356        cx: &mut App,
  357    ) -> LanguageServerId {
  358        let key = LanguageServerSeed {
  359            worktree_id: worktree_handle.read(cx).id(),
  360            name: disposition.server_name.clone(),
  361            settings: LanguageServerSeedSettings {
  362                binary: disposition.settings.binary.clone(),
  363                initialization_options: disposition.settings.initialization_options.clone(),
  364            },
  365            toolchain: disposition.toolchain.clone(),
  366        };
  367        if let Some(state) = self.language_server_ids.get_mut(&key) {
  368            state.project_roots.insert(disposition.path.path.clone());
  369            state.id
  370        } else {
  371            let adapter = self
  372                .languages
  373                .lsp_adapters(language_name)
  374                .into_iter()
  375                .find(|adapter| adapter.name() == disposition.server_name)
  376                .expect("To find LSP adapter");
  377            let new_language_server_id = self.start_language_server(
  378                worktree_handle,
  379                delegate,
  380                adapter,
  381                disposition.settings.clone(),
  382                key.clone(),
  383                language_name.clone(),
  384                cx,
  385            );
  386            if let Some(state) = self.language_server_ids.get_mut(&key) {
  387                state.project_roots.insert(disposition.path.path.clone());
  388            } else {
  389                debug_assert!(
  390                    false,
  391                    "Expected `start_language_server` to ensure that `key` exists in a map"
  392                );
  393            }
  394            new_language_server_id
  395        }
  396    }
  397
  398    fn start_language_server(
  399        &mut self,
  400        worktree_handle: &Entity<Worktree>,
  401        delegate: Arc<LocalLspAdapterDelegate>,
  402        adapter: Arc<CachedLspAdapter>,
  403        settings: Arc<LspSettings>,
  404        key: LanguageServerSeed,
  405        language_name: LanguageName,
  406        cx: &mut App,
  407    ) -> LanguageServerId {
  408        let worktree = worktree_handle.read(cx);
  409
  410        let worktree_id = worktree.id();
  411        let worktree_abs_path = worktree.abs_path();
  412        let toolchain = key.toolchain.clone();
  413        let override_options = settings.initialization_options.clone();
  414
  415        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  416
  417        let server_id = self.languages.next_language_server_id();
  418        log::trace!(
  419            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  420            adapter.name.0
  421        );
  422
  423        let wait_until_worktree_trust =
  424            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  425                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  426                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  427                });
  428                if can_trust {
  429                    self.restricted_worktrees_tasks.remove(&worktree_id);
  430                    None
  431                } else {
  432                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  433                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  434                        hash_map::Entry::Vacant(v) => {
  435                            let (mut tx, rx) = watch::channel::<bool>();
  436                            let lsp_store = self.weak.clone();
  437                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  438                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  439                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  440                                        tx.blocking_send(true).ok();
  441                                        lsp_store
  442                                            .update(cx, |lsp_store, _| {
  443                                                if let Some(local_lsp_store) =
  444                                                    lsp_store.as_local_mut()
  445                                                {
  446                                                    local_lsp_store
  447                                                        .restricted_worktrees_tasks
  448                                                        .remove(&worktree_id);
  449                                                }
  450                                            })
  451                                            .ok();
  452                                    }
  453                                }
  454                            });
  455                            v.insert((subscription, rx.clone()));
  456                            Some(rx)
  457                        }
  458                    }
  459                }
  460            });
  461        let update_binary_status = wait_until_worktree_trust.is_none();
  462
  463        let binary = self.get_language_server_binary(
  464            worktree_abs_path.clone(),
  465            adapter.clone(),
  466            settings,
  467            toolchain.clone(),
  468            delegate.clone(),
  469            true,
  470            wait_until_worktree_trust,
  471            cx,
  472        );
  473        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  474
  475        let pending_server = cx.spawn({
  476            let adapter = adapter.clone();
  477            let server_name = adapter.name.clone();
  478            let stderr_capture = stderr_capture.clone();
  479            #[cfg(any(test, feature = "test-support"))]
  480            let lsp_store = self.weak.clone();
  481            let pending_workspace_folders = pending_workspace_folders.clone();
  482            async move |cx| {
  483                let binary = binary.await?;
  484                #[cfg(any(test, feature = "test-support"))]
  485                if let Some(server) = lsp_store
  486                    .update(&mut cx.clone(), |this, cx| {
  487                        this.languages.create_fake_language_server(
  488                            server_id,
  489                            &server_name,
  490                            binary.clone(),
  491                            &mut cx.to_async(),
  492                        )
  493                    })
  494                    .ok()
  495                    .flatten()
  496                {
  497                    return Ok(server);
  498                }
  499
  500                let code_action_kinds = adapter.code_action_kinds();
  501                lsp::LanguageServer::new(
  502                    stderr_capture,
  503                    server_id,
  504                    server_name,
  505                    binary,
  506                    &worktree_abs_path,
  507                    code_action_kinds,
  508                    Some(pending_workspace_folders),
  509                    cx,
  510                )
  511            }
  512        });
  513
  514        let startup = {
  515            let server_name = adapter.name.0.clone();
  516            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  517            let key = key.clone();
  518            let adapter = adapter.clone();
  519            let lsp_store = self.weak.clone();
  520            let pending_workspace_folders = pending_workspace_folders.clone();
  521            let pull_diagnostics = ProjectSettings::get_global(cx)
  522                .diagnostics
  523                .lsp_pull_diagnostics
  524                .enabled;
  525            let settings_location = SettingsLocation {
  526                worktree_id,
  527                path: RelPath::empty(),
  528            };
  529            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  530                .language(Some(settings_location), Some(&language_name), cx)
  531                .semantic_tokens
  532                .use_tree_sitter();
  533            cx.spawn(async move |cx| {
  534                let result = async {
  535                    let language_server = pending_server.await?;
  536
  537                    let workspace_config = Self::workspace_configuration_for_adapter(
  538                        adapter.adapter.clone(),
  539                        &delegate,
  540                        toolchain,
  541                        None,
  542                        cx,
  543                    )
  544                    .await?;
  545
  546                    let mut initialization_options = Self::initialization_options_for_adapter(
  547                        adapter.adapter.clone(),
  548                        &delegate,
  549                    )
  550                    .await?;
  551
  552                    match (&mut initialization_options, override_options) {
  553                        (Some(initialization_options), Some(override_options)) => {
  554                            merge_json_value_into(override_options, initialization_options);
  555                        }
  556                        (None, override_options) => initialization_options = override_options,
  557                        _ => {}
  558                    }
  559
  560                    let initialization_params = cx.update(|cx| {
  561                        let mut params = language_server.default_initialize_params(
  562                            pull_diagnostics,
  563                            augments_syntax_tokens,
  564                            cx,
  565                        );
  566                        params.initialization_options = initialization_options;
  567                        adapter.adapter.prepare_initialize_params(params, cx)
  568                    })?;
  569
  570                    Self::setup_lsp_messages(
  571                        lsp_store.clone(),
  572                        &language_server,
  573                        delegate.clone(),
  574                        adapter.clone(),
  575                    );
  576
  577                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  578                        settings: workspace_config,
  579                    };
  580                    let language_server = cx
  581                        .update(|cx| {
  582                            let request_timeout = ProjectSettings::get_global(cx)
  583                                .global_lsp_settings
  584                                .get_request_timeout();
  585
  586                            language_server.initialize(
  587                                initialization_params,
  588                                Arc::new(did_change_configuration_params.clone()),
  589                                request_timeout,
  590                                cx,
  591                            )
  592                        })
  593                        .await
  594                        .inspect_err(|_| {
  595                            if let Some(lsp_store) = lsp_store.upgrade() {
  596                                lsp_store.update(cx, |lsp_store, cx| {
  597                                    lsp_store.cleanup_lsp_data(server_id);
  598                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  599                                });
  600                            }
  601                        })?;
  602
  603                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  604                        did_change_configuration_params,
  605                    )?;
  606
  607                    anyhow::Ok(language_server)
  608                }
  609                .await;
  610
  611                match result {
  612                    Ok(server) => {
  613                        lsp_store
  614                            .update(cx, |lsp_store, cx| {
  615                                lsp_store.insert_newly_running_language_server(
  616                                    adapter,
  617                                    server.clone(),
  618                                    server_id,
  619                                    key,
  620                                    pending_workspace_folders,
  621                                    cx,
  622                                );
  623                            })
  624                            .ok();
  625                        stderr_capture.lock().take();
  626                        Some(server)
  627                    }
  628
  629                    Err(err) => {
  630                        let log = stderr_capture.lock().take().unwrap_or_default();
  631                        delegate.update_status(
  632                            adapter.name(),
  633                            BinaryStatus::Failed {
  634                                error: if log.is_empty() {
  635                                    format!("{err:#}")
  636                                } else {
  637                                    format!("{err:#}\n-- stderr --\n{log}")
  638                                },
  639                            },
  640                        );
  641                        log::error!(
  642                            "Failed to start language server {server_name:?}: {}",
  643                            redact_command(&format!("{err:?}"))
  644                        );
  645                        if !log.is_empty() {
  646                            log::error!("server stderr: {}", redact_command(&log));
  647                        }
  648                        None
  649                    }
  650                }
  651            })
  652        };
  653        let state = LanguageServerState::Starting {
  654            startup,
  655            pending_workspace_folders,
  656        };
  657
  658        if update_binary_status {
  659            self.languages
  660                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  661        }
  662
  663        self.language_servers.insert(server_id, state);
  664        self.language_server_ids
  665            .entry(key)
  666            .or_insert(UnifiedLanguageServer {
  667                id: server_id,
  668                project_roots: Default::default(),
  669            });
  670        server_id
  671    }
  672
  673    fn get_language_server_binary(
  674        &self,
  675        worktree_abs_path: Arc<Path>,
  676        adapter: Arc<CachedLspAdapter>,
  677        settings: Arc<LspSettings>,
  678        toolchain: Option<Toolchain>,
  679        delegate: Arc<dyn LspAdapterDelegate>,
  680        allow_binary_download: bool,
  681        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  682        cx: &mut App,
  683    ) -> Task<Result<LanguageServerBinary>> {
  684        if let Some(settings) = &settings.binary
  685            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  686        {
  687            let settings = settings.clone();
  688            let languages = self.languages.clone();
  689            return cx.background_spawn(async move {
  690                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  691                    let already_trusted =  *wait_until_worktree_trust.borrow();
  692                    if !already_trusted {
  693                        log::info!(
  694                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  695                            adapter.name(),
  696                        );
  697                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  698                            if worktree_trusted {
  699                                break;
  700                            }
  701                        }
  702                        log::info!(
  703                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  704                            adapter.name(),
  705                        );
  706                    }
  707                    languages
  708                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  709                }
  710                let mut env = delegate.shell_env().await;
  711                env.extend(settings.env.unwrap_or_default());
  712
  713                Ok(LanguageServerBinary {
  714                    path: delegate.resolve_executable_path(path),
  715                    env: Some(env),
  716                    arguments: settings
  717                        .arguments
  718                        .unwrap_or_default()
  719                        .iter()
  720                        .map(Into::into)
  721                        .collect(),
  722                })
  723            });
  724        }
  725        let lsp_binary_options = LanguageServerBinaryOptions {
  726            allow_path_lookup: !settings
  727                .binary
  728                .as_ref()
  729                .and_then(|b| b.ignore_system_version)
  730                .unwrap_or_default(),
  731            allow_binary_download,
  732            pre_release: settings
  733                .fetch
  734                .as_ref()
  735                .and_then(|f| f.pre_release)
  736                .unwrap_or(false),
  737        };
  738
  739        cx.spawn(async move |cx| {
  740            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  741                let already_trusted =  *wait_until_worktree_trust.borrow();
  742                if !already_trusted {
  743                    log::info!(
  744                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  745                        adapter.name(),
  746                    );
  747                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  748                        if worktree_trusted {
  749                            break;
  750                        }
  751                    }
  752                    log::info!(
  753                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  754                            adapter.name(),
  755                    );
  756                }
  757            }
  758
  759            let (existing_binary, maybe_download_binary) = adapter
  760                .clone()
  761                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  762                .await
  763                .await;
  764
  765            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  766
  767            let mut binary = match (existing_binary, maybe_download_binary) {
  768                (binary, None) => binary?,
  769                (Err(_), Some(downloader)) => downloader.await?,
  770                (Ok(existing_binary), Some(downloader)) => {
  771                    let mut download_timeout = cx
  772                        .background_executor()
  773                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  774                        .fuse();
  775                    let mut downloader = downloader.fuse();
  776                    futures::select! {
  777                        _ = download_timeout => {
  778                            // Return existing binary and kick the existing work to the background.
  779                            cx.spawn(async move |_| downloader.await).detach();
  780                            Ok(existing_binary)
  781                        },
  782                        downloaded_or_existing_binary = downloader => {
  783                            // If download fails, this results in the existing binary.
  784                            downloaded_or_existing_binary
  785                        }
  786                    }?
  787                }
  788            };
  789            let mut shell_env = delegate.shell_env().await;
  790
  791            shell_env.extend(binary.env.unwrap_or_default());
  792
  793            if let Some(settings) = settings.binary.as_ref() {
  794                if let Some(arguments) = &settings.arguments {
  795                    binary.arguments = arguments.iter().map(Into::into).collect();
  796                }
  797                if let Some(env) = &settings.env {
  798                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  799                }
  800            }
  801
  802            binary.env = Some(shell_env);
  803            Ok(binary)
  804        })
  805    }
  806
  807    fn setup_lsp_messages(
  808        lsp_store: WeakEntity<LspStore>,
  809        language_server: &LanguageServer,
  810        delegate: Arc<dyn LspAdapterDelegate>,
  811        adapter: Arc<CachedLspAdapter>,
  812    ) {
  813        let name = language_server.name();
  814        let server_id = language_server.server_id();
  815        language_server
  816            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  817                let adapter = adapter.clone();
  818                let this = lsp_store.clone();
  819                move |mut params, cx| {
  820                    let adapter = adapter.clone();
  821                    if let Some(this) = this.upgrade() {
  822                        this.update(cx, |this, cx| {
  823                            {
  824                                let buffer = params
  825                                    .uri
  826                                    .to_file_path()
  827                                    .map(|file_path| this.get_buffer(&file_path, cx))
  828                                    .ok()
  829                                    .flatten();
  830                                adapter.process_diagnostics(&mut params, server_id, buffer);
  831                            }
  832
  833                            this.merge_lsp_diagnostics(
  834                                DiagnosticSourceKind::Pushed,
  835                                vec![DocumentDiagnosticsUpdate {
  836                                    server_id,
  837                                    diagnostics: params,
  838                                    result_id: None,
  839                                    disk_based_sources: Cow::Borrowed(
  840                                        &adapter.disk_based_diagnostic_sources,
  841                                    ),
  842                                    registration_id: None,
  843                                }],
  844                                |_, diagnostic, cx| match diagnostic.source_kind {
  845                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  846                                        adapter.retain_old_diagnostic(diagnostic, cx)
  847                                    }
  848                                    DiagnosticSourceKind::Pulled => true,
  849                                },
  850                                cx,
  851                            )
  852                            .log_err();
  853                        });
  854                    }
  855                }
  856            })
  857            .detach();
  858        language_server
  859            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  860                let adapter = adapter.adapter.clone();
  861                let delegate = delegate.clone();
  862                let this = lsp_store.clone();
  863                move |params, cx| {
  864                    let adapter = adapter.clone();
  865                    let delegate = delegate.clone();
  866                    let this = this.clone();
  867                    let mut cx = cx.clone();
  868                    async move {
  869                        let toolchain_for_id = this
  870                            .update(&mut cx, |this, _| {
  871                                this.as_local()?.language_server_ids.iter().find_map(
  872                                    |(seed, value)| {
  873                                        (value.id == server_id).then(|| seed.toolchain.clone())
  874                                    },
  875                                )
  876                            })?
  877                            .context("Expected the LSP store to be in a local mode")?;
  878
  879                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  880                        for item in &params.items {
  881                            let scope_uri = item.scope_uri.clone();
  882                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  883                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  884                            else {
  885                                // We've already queried workspace configuration of this URI.
  886                                continue;
  887                            };
  888                            let workspace_config = Self::workspace_configuration_for_adapter(
  889                                adapter.clone(),
  890                                &delegate,
  891                                toolchain_for_id.clone(),
  892                                scope_uri,
  893                                &mut cx,
  894                            )
  895                            .await?;
  896                            new_scope_uri.insert(workspace_config);
  897                        }
  898
  899                        Ok(params
  900                            .items
  901                            .into_iter()
  902                            .filter_map(|item| {
  903                                let workspace_config =
  904                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  905                                if let Some(section) = &item.section {
  906                                    Some(
  907                                        workspace_config
  908                                            .get(section)
  909                                            .cloned()
  910                                            .unwrap_or(serde_json::Value::Null),
  911                                    )
  912                                } else {
  913                                    Some(workspace_config.clone())
  914                                }
  915                            })
  916                            .collect())
  917                    }
  918                }
  919            })
  920            .detach();
  921
  922        language_server
  923            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  924                let this = lsp_store.clone();
  925                move |_, cx| {
  926                    let this = this.clone();
  927                    let cx = cx.clone();
  928                    async move {
  929                        let Some(server) =
  930                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  931                        else {
  932                            return Ok(None);
  933                        };
  934                        let root = server.workspace_folders();
  935                        Ok(Some(
  936                            root.into_iter()
  937                                .map(|uri| WorkspaceFolder {
  938                                    uri,
  939                                    name: Default::default(),
  940                                })
  941                                .collect(),
  942                        ))
  943                    }
  944                }
  945            })
  946            .detach();
  947        // Even though we don't have handling for these requests, respond to them to
  948        // avoid stalling any language server like `gopls` which waits for a response
  949        // to these requests when initializing.
  950        language_server
  951            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  952                let this = lsp_store.clone();
  953                move |params, cx| {
  954                    let this = this.clone();
  955                    let mut cx = cx.clone();
  956                    async move {
  957                        this.update(&mut cx, |this, _| {
  958                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  959                            {
  960                                status
  961                                    .progress_tokens
  962                                    .insert(ProgressToken::from_lsp(params.token));
  963                            }
  964                        })?;
  965
  966                        Ok(())
  967                    }
  968                }
  969            })
  970            .detach();
  971
  972        language_server
  973            .on_request::<lsp::request::RegisterCapability, _, _>({
  974                let lsp_store = lsp_store.clone();
  975                move |params, cx| {
  976                    let lsp_store = lsp_store.clone();
  977                    let mut cx = cx.clone();
  978                    async move {
  979                        lsp_store
  980                            .update(&mut cx, |lsp_store, cx| {
  981                                if lsp_store.as_local().is_some() {
  982                                    match lsp_store
  983                                        .register_server_capabilities(server_id, params, cx)
  984                                    {
  985                                        Ok(()) => {}
  986                                        Err(e) => {
  987                                            log::error!(
  988                                                "Failed to register server capabilities: {e:#}"
  989                                            );
  990                                        }
  991                                    };
  992                                }
  993                            })
  994                            .ok();
  995                        Ok(())
  996                    }
  997                }
  998            })
  999            .detach();
 1000
 1001        language_server
 1002            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1003                let lsp_store = lsp_store.clone();
 1004                move |params, cx| {
 1005                    let lsp_store = lsp_store.clone();
 1006                    let mut cx = cx.clone();
 1007                    async move {
 1008                        lsp_store
 1009                            .update(&mut cx, |lsp_store, cx| {
 1010                                if lsp_store.as_local().is_some() {
 1011                                    match lsp_store
 1012                                        .unregister_server_capabilities(server_id, params, cx)
 1013                                    {
 1014                                        Ok(()) => {}
 1015                                        Err(e) => {
 1016                                            log::error!(
 1017                                                "Failed to unregister server capabilities: {e:#}"
 1018                                            );
 1019                                        }
 1020                                    }
 1021                                }
 1022                            })
 1023                            .ok();
 1024                        Ok(())
 1025                    }
 1026                }
 1027            })
 1028            .detach();
 1029
 1030        language_server
 1031            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1032                let this = lsp_store.clone();
 1033                move |params, cx| {
 1034                    let mut cx = cx.clone();
 1035                    let this = this.clone();
 1036                    async move {
 1037                        LocalLspStore::on_lsp_workspace_edit(
 1038                            this.clone(),
 1039                            params,
 1040                            server_id,
 1041                            &mut cx,
 1042                        )
 1043                        .await
 1044                    }
 1045                }
 1046            })
 1047            .detach();
 1048
 1049        language_server
 1050            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1051                let lsp_store = lsp_store.clone();
 1052                let request_id = Arc::new(AtomicUsize::new(0));
 1053                move |(), cx| {
 1054                    let lsp_store = lsp_store.clone();
 1055                    let request_id = request_id.clone();
 1056                    let mut cx = cx.clone();
 1057                    async move {
 1058                        lsp_store
 1059                            .update(&mut cx, |lsp_store, cx| {
 1060                                let request_id =
 1061                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1062                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1063                                    server_id,
 1064                                    request_id,
 1065                                });
 1066                                lsp_store
 1067                                    .downstream_client
 1068                                    .as_ref()
 1069                                    .map(|(client, project_id)| {
 1070                                        client.send(proto::RefreshInlayHints {
 1071                                            project_id: *project_id,
 1072                                            server_id: server_id.to_proto(),
 1073                                            request_id: request_id.map(|id| id as u64),
 1074                                        })
 1075                                    })
 1076                            })?
 1077                            .transpose()?;
 1078                        Ok(())
 1079                    }
 1080                }
 1081            })
 1082            .detach();
 1083
 1084        language_server
 1085            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1086                let this = lsp_store.clone();
 1087                move |(), cx| {
 1088                    let this = this.clone();
 1089                    let mut cx = cx.clone();
 1090                    async move {
 1091                        this.update(&mut cx, |this, cx| {
 1092                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1093                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1094                                client.send(proto::RefreshCodeLens {
 1095                                    project_id: *project_id,
 1096                                })
 1097                            })
 1098                        })?
 1099                        .transpose()?;
 1100                        Ok(())
 1101                    }
 1102                }
 1103            })
 1104            .detach();
 1105
 1106        language_server
 1107            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1108                let lsp_store = lsp_store.clone();
 1109                let request_id = Arc::new(AtomicUsize::new(0));
 1110                move |(), cx| {
 1111                    let lsp_store = lsp_store.clone();
 1112                    let request_id = request_id.clone();
 1113                    let mut cx = cx.clone();
 1114                    async move {
 1115                        lsp_store
 1116                            .update(&mut cx, |lsp_store, cx| {
 1117                                let request_id =
 1118                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1119                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1120                                    server_id,
 1121                                    request_id,
 1122                                });
 1123                                lsp_store
 1124                                    .downstream_client
 1125                                    .as_ref()
 1126                                    .map(|(client, project_id)| {
 1127                                        client.send(proto::RefreshSemanticTokens {
 1128                                            project_id: *project_id,
 1129                                            server_id: server_id.to_proto(),
 1130                                            request_id: request_id.map(|id| id as u64),
 1131                                        })
 1132                                    })
 1133                            })?
 1134                            .transpose()?;
 1135                        Ok(())
 1136                    }
 1137                }
 1138            })
 1139            .detach();
 1140
 1141        language_server
 1142            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1143                let this = lsp_store.clone();
 1144                move |(), cx| {
 1145                    let this = this.clone();
 1146                    let mut cx = cx.clone();
 1147                    async move {
 1148                        this.update(&mut cx, |lsp_store, cx| {
 1149                            lsp_store.pull_workspace_diagnostics(server_id);
 1150                            lsp_store
 1151                                .downstream_client
 1152                                .as_ref()
 1153                                .map(|(client, project_id)| {
 1154                                    client.send(proto::PullWorkspaceDiagnostics {
 1155                                        project_id: *project_id,
 1156                                        server_id: server_id.to_proto(),
 1157                                    })
 1158                                })
 1159                                .transpose()?;
 1160                            anyhow::Ok(
 1161                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1162                            )
 1163                        })??
 1164                        .await;
 1165                        Ok(())
 1166                    }
 1167                }
 1168            })
 1169            .detach();
 1170
 1171        language_server
 1172            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1173                let this = lsp_store.clone();
 1174                let name = name.to_string();
 1175                let adapter = adapter.clone();
 1176                move |params, cx| {
 1177                    let this = this.clone();
 1178                    let name = name.to_string();
 1179                    let adapter = adapter.clone();
 1180                    let mut cx = cx.clone();
 1181                    async move {
 1182                        let actions = params.actions.unwrap_or_default();
 1183                        let message = params.message.clone();
 1184                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1185                        let level = match params.typ {
 1186                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1187                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1188                            _ => PromptLevel::Info,
 1189                        };
 1190                        let request = LanguageServerPromptRequest::new(
 1191                            level,
 1192                            params.message,
 1193                            actions,
 1194                            name.clone(),
 1195                            tx,
 1196                        );
 1197
 1198                        let did_update = this
 1199                            .update(&mut cx, |_, cx| {
 1200                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1201                            })
 1202                            .is_ok();
 1203                        if did_update {
 1204                            let response = rx.recv().await.ok();
 1205                            if let Some(ref selected_action) = response {
 1206                                let context = language::PromptResponseContext {
 1207                                    message,
 1208                                    selected_action: selected_action.clone(),
 1209                                };
 1210                                adapter.process_prompt_response(&context, &mut cx)
 1211                            }
 1212
 1213                            Ok(response)
 1214                        } else {
 1215                            Ok(None)
 1216                        }
 1217                    }
 1218                }
 1219            })
 1220            .detach();
 1221        language_server
 1222            .on_notification::<lsp::notification::ShowMessage, _>({
 1223                let this = lsp_store.clone();
 1224                let name = name.to_string();
 1225                move |params, cx| {
 1226                    let this = this.clone();
 1227                    let name = name.to_string();
 1228                    let mut cx = cx.clone();
 1229
 1230                    let (tx, _) = smol::channel::bounded(1);
 1231                    let level = match params.typ {
 1232                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1233                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1234                        _ => PromptLevel::Info,
 1235                    };
 1236                    let request =
 1237                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1238
 1239                    let _ = this.update(&mut cx, |_, cx| {
 1240                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1241                    });
 1242                }
 1243            })
 1244            .detach();
 1245
 1246        let disk_based_diagnostics_progress_token =
 1247            adapter.disk_based_diagnostics_progress_token.clone();
 1248
 1249        language_server
 1250            .on_notification::<lsp::notification::Progress, _>({
 1251                let this = lsp_store.clone();
 1252                move |params, cx| {
 1253                    if let Some(this) = this.upgrade() {
 1254                        this.update(cx, |this, cx| {
 1255                            this.on_lsp_progress(
 1256                                params,
 1257                                server_id,
 1258                                disk_based_diagnostics_progress_token.clone(),
 1259                                cx,
 1260                            );
 1261                        });
 1262                    }
 1263                }
 1264            })
 1265            .detach();
 1266
 1267        language_server
 1268            .on_notification::<lsp::notification::LogMessage, _>({
 1269                let this = lsp_store.clone();
 1270                move |params, cx| {
 1271                    if let Some(this) = this.upgrade() {
 1272                        this.update(cx, |_, cx| {
 1273                            cx.emit(LspStoreEvent::LanguageServerLog(
 1274                                server_id,
 1275                                LanguageServerLogType::Log(params.typ),
 1276                                params.message,
 1277                            ));
 1278                        });
 1279                    }
 1280                }
 1281            })
 1282            .detach();
 1283
 1284        language_server
 1285            .on_notification::<lsp::notification::LogTrace, _>({
 1286                let this = lsp_store.clone();
 1287                move |params, cx| {
 1288                    let mut cx = cx.clone();
 1289                    if let Some(this) = this.upgrade() {
 1290                        this.update(&mut cx, |_, cx| {
 1291                            cx.emit(LspStoreEvent::LanguageServerLog(
 1292                                server_id,
 1293                                LanguageServerLogType::Trace {
 1294                                    verbose_info: params.verbose,
 1295                                },
 1296                                params.message,
 1297                            ));
 1298                        });
 1299                    }
 1300                }
 1301            })
 1302            .detach();
 1303
 1304        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1305        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1306        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1307        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1308    }
 1309
 1310    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1311        let shutdown_futures = self
 1312            .language_servers
 1313            .drain()
 1314            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1315            .collect::<Vec<_>>();
 1316
 1317        async move {
 1318            join_all(shutdown_futures).await;
 1319        }
 1320    }
 1321
 1322    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1323        match server_state {
 1324            LanguageServerState::Running { server, .. } => {
 1325                if let Some(shutdown) = server.shutdown() {
 1326                    shutdown.await;
 1327                }
 1328            }
 1329            LanguageServerState::Starting { startup, .. } => {
 1330                if let Some(server) = startup.await
 1331                    && let Some(shutdown) = server.shutdown()
 1332                {
 1333                    shutdown.await;
 1334                }
 1335            }
 1336        }
 1337        Ok(())
 1338    }
 1339
 1340    fn language_servers_for_worktree(
 1341        &self,
 1342        worktree_id: WorktreeId,
 1343    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1344        self.language_server_ids
 1345            .iter()
 1346            .filter_map(move |(seed, state)| {
 1347                if seed.worktree_id != worktree_id {
 1348                    return None;
 1349                }
 1350
 1351                if let Some(LanguageServerState::Running { server, .. }) =
 1352                    self.language_servers.get(&state.id)
 1353                {
 1354                    Some(server)
 1355                } else {
 1356                    None
 1357                }
 1358            })
 1359    }
 1360
 1361    fn language_server_ids_for_project_path(
 1362        &self,
 1363        project_path: ProjectPath,
 1364        language: &Language,
 1365        cx: &mut App,
 1366    ) -> Vec<LanguageServerId> {
 1367        let Some(worktree) = self
 1368            .worktree_store
 1369            .read(cx)
 1370            .worktree_for_id(project_path.worktree_id, cx)
 1371        else {
 1372            return Vec::new();
 1373        };
 1374        let delegate: Arc<dyn ManifestDelegate> =
 1375            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1376
 1377        self.lsp_tree
 1378            .get(
 1379                project_path,
 1380                language.name(),
 1381                language.manifest(),
 1382                &delegate,
 1383                cx,
 1384            )
 1385            .collect::<Vec<_>>()
 1386    }
 1387
 1388    fn language_server_ids_for_buffer(
 1389        &self,
 1390        buffer: &Buffer,
 1391        cx: &mut App,
 1392    ) -> Vec<LanguageServerId> {
 1393        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1394            let worktree_id = file.worktree_id(cx);
 1395
 1396            let path: Arc<RelPath> = file
 1397                .path()
 1398                .parent()
 1399                .map(Arc::from)
 1400                .unwrap_or_else(|| file.path().clone());
 1401            let worktree_path = ProjectPath { worktree_id, path };
 1402            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1403        } else {
 1404            Vec::new()
 1405        }
 1406    }
 1407
 1408    fn language_servers_for_buffer<'a>(
 1409        &'a self,
 1410        buffer: &'a Buffer,
 1411        cx: &'a mut App,
 1412    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1413        self.language_server_ids_for_buffer(buffer, cx)
 1414            .into_iter()
 1415            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1416                LanguageServerState::Running {
 1417                    adapter, server, ..
 1418                } => Some((adapter, server)),
 1419                _ => None,
 1420            })
 1421    }
 1422
 1423    async fn execute_code_action_kind_locally(
 1424        lsp_store: WeakEntity<LspStore>,
 1425        mut buffers: Vec<Entity<Buffer>>,
 1426        kind: CodeActionKind,
 1427        push_to_history: bool,
 1428        cx: &mut AsyncApp,
 1429    ) -> anyhow::Result<ProjectTransaction> {
 1430        // Do not allow multiple concurrent code actions requests for the
 1431        // same buffer.
 1432        lsp_store.update(cx, |this, cx| {
 1433            let this = this.as_local_mut().unwrap();
 1434            buffers.retain(|buffer| {
 1435                this.buffers_being_formatted
 1436                    .insert(buffer.read(cx).remote_id())
 1437            });
 1438        })?;
 1439        let _cleanup = defer({
 1440            let this = lsp_store.clone();
 1441            let mut cx = cx.clone();
 1442            let buffers = &buffers;
 1443            move || {
 1444                this.update(&mut cx, |this, cx| {
 1445                    let this = this.as_local_mut().unwrap();
 1446                    for buffer in buffers {
 1447                        this.buffers_being_formatted
 1448                            .remove(&buffer.read(cx).remote_id());
 1449                    }
 1450                })
 1451                .ok();
 1452            }
 1453        });
 1454        let mut project_transaction = ProjectTransaction::default();
 1455
 1456        for buffer in &buffers {
 1457            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1458                buffer.update(cx, |buffer, cx| {
 1459                    lsp_store
 1460                        .as_local()
 1461                        .unwrap()
 1462                        .language_servers_for_buffer(buffer, cx)
 1463                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1464                        .collect::<Vec<_>>()
 1465                })
 1466            })?;
 1467            for (_, language_server) in adapters_and_servers.iter() {
 1468                let actions = Self::get_server_code_actions_from_action_kinds(
 1469                    &lsp_store,
 1470                    language_server.server_id(),
 1471                    vec![kind.clone()],
 1472                    buffer,
 1473                    cx,
 1474                )
 1475                .await?;
 1476                Self::execute_code_actions_on_server(
 1477                    &lsp_store,
 1478                    language_server,
 1479                    actions,
 1480                    push_to_history,
 1481                    &mut project_transaction,
 1482                    cx,
 1483                )
 1484                .await?;
 1485            }
 1486        }
 1487        Ok(project_transaction)
 1488    }
 1489
 1490    async fn format_locally(
 1491        lsp_store: WeakEntity<LspStore>,
 1492        mut buffers: Vec<FormattableBuffer>,
 1493        push_to_history: bool,
 1494        trigger: FormatTrigger,
 1495        logger: zlog::Logger,
 1496        cx: &mut AsyncApp,
 1497    ) -> anyhow::Result<ProjectTransaction> {
 1498        // Do not allow multiple concurrent formatting requests for the
 1499        // same buffer.
 1500        lsp_store.update(cx, |this, cx| {
 1501            let this = this.as_local_mut().unwrap();
 1502            buffers.retain(|buffer| {
 1503                this.buffers_being_formatted
 1504                    .insert(buffer.handle.read(cx).remote_id())
 1505            });
 1506        })?;
 1507
 1508        let _cleanup = defer({
 1509            let this = lsp_store.clone();
 1510            let mut cx = cx.clone();
 1511            let buffers = &buffers;
 1512            move || {
 1513                this.update(&mut cx, |this, cx| {
 1514                    let this = this.as_local_mut().unwrap();
 1515                    for buffer in buffers {
 1516                        this.buffers_being_formatted
 1517                            .remove(&buffer.handle.read(cx).remote_id());
 1518                    }
 1519                })
 1520                .ok();
 1521            }
 1522        });
 1523
 1524        let mut project_transaction = ProjectTransaction::default();
 1525
 1526        for buffer in &buffers {
 1527            zlog::debug!(
 1528                logger =>
 1529                "formatting buffer '{:?}'",
 1530                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1531            );
 1532            // Create an empty transaction to hold all of the formatting edits.
 1533            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1534                // ensure no transactions created while formatting are
 1535                // grouped with the previous transaction in the history
 1536                // based on the transaction group interval
 1537                buffer.finalize_last_transaction();
 1538                buffer
 1539                    .start_transaction()
 1540                    .context("transaction already open")?;
 1541                buffer.end_transaction(cx);
 1542                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1543                buffer.finalize_last_transaction();
 1544                anyhow::Ok(transaction_id)
 1545            })?;
 1546
 1547            let result = Self::format_buffer_locally(
 1548                lsp_store.clone(),
 1549                buffer,
 1550                formatting_transaction_id,
 1551                trigger,
 1552                logger,
 1553                cx,
 1554            )
 1555            .await;
 1556
 1557            buffer.handle.update(cx, |buffer, cx| {
 1558                let Some(formatting_transaction) =
 1559                    buffer.get_transaction(formatting_transaction_id).cloned()
 1560                else {
 1561                    zlog::warn!(logger => "no formatting transaction");
 1562                    return;
 1563                };
 1564                if formatting_transaction.edit_ids.is_empty() {
 1565                    zlog::debug!(logger => "no changes made while formatting");
 1566                    buffer.forget_transaction(formatting_transaction_id);
 1567                    return;
 1568                }
 1569                if !push_to_history {
 1570                    zlog::trace!(logger => "forgetting format transaction");
 1571                    buffer.forget_transaction(formatting_transaction.id);
 1572                }
 1573                project_transaction
 1574                    .0
 1575                    .insert(cx.entity(), formatting_transaction);
 1576            });
 1577
 1578            result?;
 1579        }
 1580
 1581        Ok(project_transaction)
 1582    }
 1583
 1584    async fn format_buffer_locally(
 1585        lsp_store: WeakEntity<LspStore>,
 1586        buffer: &FormattableBuffer,
 1587        formatting_transaction_id: clock::Lamport,
 1588        trigger: FormatTrigger,
 1589        logger: zlog::Logger,
 1590        cx: &mut AsyncApp,
 1591    ) -> Result<()> {
 1592        let (adapters_and_servers, settings, request_timeout) =
 1593            lsp_store.update(cx, |lsp_store, cx| {
 1594                buffer.handle.update(cx, |buffer, cx| {
 1595                    let adapters_and_servers = lsp_store
 1596                        .as_local()
 1597                        .unwrap()
 1598                        .language_servers_for_buffer(buffer, cx)
 1599                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1600                        .collect::<Vec<_>>();
 1601                    let settings =
 1602                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1603                            .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        /// Apply edits to the buffer that will become part of the formatting transaction.
 1612        /// Fails if the buffer has been edited since the start of that transaction.
 1613        fn extend_formatting_transaction(
 1614            buffer: &FormattableBuffer,
 1615            formatting_transaction_id: text::TransactionId,
 1616            cx: &mut AsyncApp,
 1617            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1618        ) -> anyhow::Result<()> {
 1619            buffer.handle.update(cx, |buffer, cx| {
 1620                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1621                if last_transaction_id != Some(formatting_transaction_id) {
 1622                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1623                }
 1624                buffer.start_transaction();
 1625                operation(buffer, cx);
 1626                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1627                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1628                }
 1629                Ok(())
 1630            })
 1631        }
 1632
 1633        // handle whitespace formatting
 1634        if settings.remove_trailing_whitespace_on_save {
 1635            zlog::trace!(logger => "removing trailing whitespace");
 1636            let diff = buffer
 1637                .handle
 1638                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1639                .await;
 1640            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1641                buffer.apply_diff(diff, cx);
 1642            })?;
 1643        }
 1644
 1645        if settings.ensure_final_newline_on_save {
 1646            zlog::trace!(logger => "ensuring final newline");
 1647            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1648                buffer.ensure_final_newline(cx);
 1649            })?;
 1650        }
 1651
 1652        // Formatter for `code_actions_on_format` that runs before
 1653        // the rest of the formatters
 1654        let mut code_actions_on_format_formatters = None;
 1655        let should_run_code_actions_on_format = !matches!(
 1656            (trigger, &settings.format_on_save),
 1657            (FormatTrigger::Save, &FormatOnSave::Off)
 1658        );
 1659        if should_run_code_actions_on_format {
 1660            let have_code_actions_to_run_on_format = settings
 1661                .code_actions_on_format
 1662                .values()
 1663                .any(|enabled| *enabled);
 1664            if have_code_actions_to_run_on_format {
 1665                zlog::trace!(logger => "going to run code actions on format");
 1666                code_actions_on_format_formatters = Some(
 1667                    settings
 1668                        .code_actions_on_format
 1669                        .iter()
 1670                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1671                        .cloned()
 1672                        .map(Formatter::CodeAction)
 1673                        .collect::<Vec<_>>(),
 1674                );
 1675            }
 1676        }
 1677
 1678        let formatters = match (trigger, &settings.format_on_save) {
 1679            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1680            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1681                settings.formatter.as_ref()
 1682            }
 1683        };
 1684
 1685        let formatters = code_actions_on_format_formatters
 1686            .iter()
 1687            .flatten()
 1688            .chain(formatters);
 1689
 1690        for formatter in formatters {
 1691            let formatter = if formatter == &Formatter::Auto {
 1692                if settings.prettier.allowed {
 1693                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1694                    &Formatter::Prettier
 1695                } else {
 1696                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1697                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1698                }
 1699            } else {
 1700                formatter
 1701            };
 1702            match formatter {
 1703                Formatter::Auto => unreachable!("Auto resolved above"),
 1704                Formatter::Prettier => {
 1705                    let logger = zlog::scoped!(logger => "prettier");
 1706                    zlog::trace!(logger => "formatting");
 1707                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1708
 1709                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1710                        lsp_store.prettier_store().unwrap().downgrade()
 1711                    })?;
 1712                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1713                        .await
 1714                        .transpose()?;
 1715                    let Some(diff) = diff else {
 1716                        zlog::trace!(logger => "No changes");
 1717                        continue;
 1718                    };
 1719
 1720                    extend_formatting_transaction(
 1721                        buffer,
 1722                        formatting_transaction_id,
 1723                        cx,
 1724                        |buffer, cx| {
 1725                            buffer.apply_diff(diff, cx);
 1726                        },
 1727                    )?;
 1728                }
 1729                Formatter::External { command, arguments } => {
 1730                    let logger = zlog::scoped!(logger => "command");
 1731                    zlog::trace!(logger => "formatting");
 1732                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1733
 1734                    let diff = Self::format_via_external_command(
 1735                        buffer,
 1736                        &command,
 1737                        arguments.as_deref(),
 1738                        cx,
 1739                    )
 1740                    .await
 1741                    .with_context(|| {
 1742                        format!("Failed to format buffer via external command: {}", command)
 1743                    })?;
 1744                    let Some(diff) = diff else {
 1745                        zlog::trace!(logger => "No changes");
 1746                        continue;
 1747                    };
 1748
 1749                    extend_formatting_transaction(
 1750                        buffer,
 1751                        formatting_transaction_id,
 1752                        cx,
 1753                        |buffer, cx| {
 1754                            buffer.apply_diff(diff, cx);
 1755                        },
 1756                    )?;
 1757                }
 1758                Formatter::LanguageServer(specifier) => {
 1759                    let logger = zlog::scoped!(logger => "language-server");
 1760                    zlog::trace!(logger => "formatting");
 1761                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1762
 1763                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1764                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1765                        continue;
 1766                    };
 1767
 1768                    let language_server = match specifier {
 1769                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1770                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1771                                if adapter.name.0.as_ref() == name {
 1772                                    Some(server.clone())
 1773                                } else {
 1774                                    None
 1775                                }
 1776                            })
 1777                        }
 1778                        settings::LanguageServerFormatterSpecifier::Current => {
 1779                            adapters_and_servers.first().map(|e| e.1.clone())
 1780                        }
 1781                    };
 1782
 1783                    let Some(language_server) = language_server else {
 1784                        log::debug!(
 1785                            "No language server found to format buffer '{:?}'. Skipping",
 1786                            buffer_path_abs.as_path().to_string_lossy()
 1787                        );
 1788                        continue;
 1789                    };
 1790
 1791                    zlog::trace!(
 1792                        logger =>
 1793                        "Formatting buffer '{:?}' using language server '{:?}'",
 1794                        buffer_path_abs.as_path().to_string_lossy(),
 1795                        language_server.name()
 1796                    );
 1797
 1798                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1799                        zlog::trace!(logger => "formatting ranges");
 1800                        Self::format_ranges_via_lsp(
 1801                            &lsp_store,
 1802                            &buffer.handle,
 1803                            ranges,
 1804                            buffer_path_abs,
 1805                            &language_server,
 1806                            &settings,
 1807                            cx,
 1808                        )
 1809                        .await
 1810                        .context("Failed to format ranges via language server")?
 1811                    } else {
 1812                        zlog::trace!(logger => "formatting full");
 1813                        Self::format_via_lsp(
 1814                            &lsp_store,
 1815                            &buffer.handle,
 1816                            buffer_path_abs,
 1817                            &language_server,
 1818                            &settings,
 1819                            cx,
 1820                        )
 1821                        .await
 1822                        .context("failed to format via language server")?
 1823                    };
 1824
 1825                    if edits.is_empty() {
 1826                        zlog::trace!(logger => "No changes");
 1827                        continue;
 1828                    }
 1829                    extend_formatting_transaction(
 1830                        buffer,
 1831                        formatting_transaction_id,
 1832                        cx,
 1833                        |buffer, cx| {
 1834                            buffer.edit(edits, None, cx);
 1835                        },
 1836                    )?;
 1837                }
 1838                Formatter::CodeAction(code_action_name) => {
 1839                    let logger = zlog::scoped!(logger => "code-actions");
 1840                    zlog::trace!(logger => "formatting");
 1841                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1842
 1843                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1844                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1845                        continue;
 1846                    };
 1847
 1848                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1849                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1850
 1851                    let mut actions_and_servers = Vec::new();
 1852
 1853                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1854                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1855                            &lsp_store,
 1856                            language_server.server_id(),
 1857                            vec![code_action_kind.clone()],
 1858                            &buffer.handle,
 1859                            cx,
 1860                        )
 1861                        .await
 1862                        .with_context(|| {
 1863                            format!(
 1864                                "Failed to resolve code action {:?} with language server {}",
 1865                                code_action_kind,
 1866                                language_server.name()
 1867                            )
 1868                        });
 1869                        let Ok(actions) = actions_result else {
 1870                            // note: it may be better to set result to the error and break formatters here
 1871                            // but for now we try to execute the actions that we can resolve and skip the rest
 1872                            zlog::error!(
 1873                                logger =>
 1874                                "Failed to resolve code action {:?} with language server {}",
 1875                                code_action_kind,
 1876                                language_server.name()
 1877                            );
 1878                            continue;
 1879                        };
 1880                        for action in actions {
 1881                            actions_and_servers.push((action, index));
 1882                        }
 1883                    }
 1884
 1885                    if actions_and_servers.is_empty() {
 1886                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1887                        continue;
 1888                    }
 1889
 1890                    'actions: for (mut action, server_index) in actions_and_servers {
 1891                        let server = &adapters_and_servers[server_index].1;
 1892
 1893                        let describe_code_action = |action: &CodeAction| {
 1894                            format!(
 1895                                "code action '{}' with title \"{}\" on server {}",
 1896                                action
 1897                                    .lsp_action
 1898                                    .action_kind()
 1899                                    .unwrap_or("unknown".into())
 1900                                    .as_str(),
 1901                                action.lsp_action.title(),
 1902                                server.name(),
 1903                            )
 1904                        };
 1905
 1906                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1907
 1908                        if let Err(err) =
 1909                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1910                                .await
 1911                        {
 1912                            zlog::error!(
 1913                                logger =>
 1914                                "Failed to resolve {}. Error: {}",
 1915                                describe_code_action(&action),
 1916                                err
 1917                            );
 1918                            continue;
 1919                        }
 1920
 1921                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1922                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1923                            // but filters out and logs warnings for code actions that require unreasonably
 1924                            // difficult handling on our part, such as:
 1925                            // - applying edits that call commands
 1926                            //   which can result in arbitrary workspace edits being sent from the server that
 1927                            //   have no way of being tied back to the command that initiated them (i.e. we
 1928                            //   can't know which edits are part of the format request, or if the server is done sending
 1929                            //   actions in response to the command)
 1930                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1931                            //   as we then would need to handle such changes correctly in the local history as well
 1932                            //   as the remote history through the ProjectTransaction
 1933                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1934                            // Supporting these actions is not impossible, but not supported as of yet.
 1935                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1936                                zlog::trace!(
 1937                                    logger =>
 1938                                    "No changes for code action. Skipping {}",
 1939                                    describe_code_action(&action),
 1940                                );
 1941                                continue;
 1942                            }
 1943
 1944                            let mut operations = Vec::new();
 1945                            if let Some(document_changes) = edit.document_changes {
 1946                                match document_changes {
 1947                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1948                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1949                                    ),
 1950                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1951                                }
 1952                            } else if let Some(changes) = edit.changes {
 1953                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1954                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1955                                        text_document:
 1956                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1957                                                uri,
 1958                                                version: None,
 1959                                            },
 1960                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1961                                    })
 1962                                }));
 1963                            }
 1964
 1965                            let mut edits = Vec::with_capacity(operations.len());
 1966
 1967                            if operations.is_empty() {
 1968                                zlog::trace!(
 1969                                    logger =>
 1970                                    "No changes for code action. Skipping {}",
 1971                                    describe_code_action(&action),
 1972                                );
 1973                                continue;
 1974                            }
 1975                            for operation in operations {
 1976                                let op = match operation {
 1977                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1978                                    lsp::DocumentChangeOperation::Op(_) => {
 1979                                        zlog::warn!(
 1980                                            logger =>
 1981                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1982                                            describe_code_action(&action),
 1983                                        );
 1984                                        continue 'actions;
 1985                                    }
 1986                                };
 1987                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1988                                    zlog::warn!(
 1989                                        logger =>
 1990                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1991                                        &op.text_document.uri,
 1992                                        describe_code_action(&action),
 1993                                    );
 1994                                    continue 'actions;
 1995                                };
 1996                                if &file_path != buffer_path_abs {
 1997                                    zlog::warn!(
 1998                                        logger =>
 1999                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2000                                        file_path,
 2001                                        buffer_path_abs,
 2002                                        describe_code_action(&action),
 2003                                    );
 2004                                    continue 'actions;
 2005                                }
 2006
 2007                                let mut lsp_edits = Vec::new();
 2008                                for edit in op.edits {
 2009                                    match edit {
 2010                                        Edit::Plain(edit) => {
 2011                                            if !lsp_edits.contains(&edit) {
 2012                                                lsp_edits.push(edit);
 2013                                            }
 2014                                        }
 2015                                        Edit::Annotated(edit) => {
 2016                                            if !lsp_edits.contains(&edit.text_edit) {
 2017                                                lsp_edits.push(edit.text_edit);
 2018                                            }
 2019                                        }
 2020                                        Edit::Snippet(_) => {
 2021                                            zlog::warn!(
 2022                                                logger =>
 2023                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2024                                                describe_code_action(&action),
 2025                                            );
 2026                                            continue 'actions;
 2027                                        }
 2028                                    }
 2029                                }
 2030                                let edits_result = lsp_store
 2031                                    .update(cx, |lsp_store, cx| {
 2032                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2033                                            &buffer.handle,
 2034                                            lsp_edits,
 2035                                            server.server_id(),
 2036                                            op.text_document.version,
 2037                                            cx,
 2038                                        )
 2039                                    })?
 2040                                    .await;
 2041                                let Ok(resolved_edits) = edits_result else {
 2042                                    zlog::warn!(
 2043                                        logger =>
 2044                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2045                                        buffer_path_abs.as_path(),
 2046                                        describe_code_action(&action),
 2047                                    );
 2048                                    continue 'actions;
 2049                                };
 2050                                edits.extend(resolved_edits);
 2051                            }
 2052
 2053                            if edits.is_empty() {
 2054                                zlog::warn!(logger => "No edits resolved from LSP");
 2055                                continue;
 2056                            }
 2057
 2058                            extend_formatting_transaction(
 2059                                buffer,
 2060                                formatting_transaction_id,
 2061                                cx,
 2062                                |buffer, cx| {
 2063                                    zlog::info!(
 2064                                        "Applying edits {edits:?}. Content: {:?}",
 2065                                        buffer.text()
 2066                                    );
 2067                                    buffer.edit(edits, None, cx);
 2068                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2069                                },
 2070                            )?;
 2071                        }
 2072
 2073                        // bail early if command is invalid
 2074                        let Some(command) = action.lsp_action.command() else {
 2075                            continue;
 2076                        };
 2077
 2078                        zlog::warn!(
 2079                            logger =>
 2080                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2081                            &command.command,
 2082                        );
 2083
 2084                        let server_capabilities = server.capabilities();
 2085                        let available_commands = server_capabilities
 2086                            .execute_command_provider
 2087                            .as_ref()
 2088                            .map(|options| options.commands.as_slice())
 2089                            .unwrap_or_default();
 2090                        if !available_commands.contains(&command.command) {
 2091                            zlog::warn!(
 2092                                logger =>
 2093                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2094                                command.command,
 2095                                server.name(),
 2096                            );
 2097                            continue;
 2098                        }
 2099
 2100                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2101                        extend_formatting_transaction(
 2102                            buffer,
 2103                            formatting_transaction_id,
 2104                            cx,
 2105                            |_, _| {},
 2106                        )?;
 2107                        zlog::info!(logger => "Executing command {}", &command.command);
 2108
 2109                        lsp_store.update(cx, |this, _| {
 2110                            this.as_local_mut()
 2111                                .unwrap()
 2112                                .last_workspace_edits_by_language_server
 2113                                .remove(&server.server_id());
 2114                        })?;
 2115
 2116                        let execute_command_result = server
 2117                            .request::<lsp::request::ExecuteCommand>(
 2118                                lsp::ExecuteCommandParams {
 2119                                    command: command.command.clone(),
 2120                                    arguments: command.arguments.clone().unwrap_or_default(),
 2121                                    ..Default::default()
 2122                                },
 2123                                request_timeout,
 2124                            )
 2125                            .await
 2126                            .into_response();
 2127
 2128                        if execute_command_result.is_err() {
 2129                            zlog::error!(
 2130                                logger =>
 2131                                "Failed to execute command '{}' as part of {}",
 2132                                &command.command,
 2133                                describe_code_action(&action),
 2134                            );
 2135                            continue 'actions;
 2136                        }
 2137
 2138                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2139                            this.as_local_mut()
 2140                                .unwrap()
 2141                                .last_workspace_edits_by_language_server
 2142                                .remove(&server.server_id())
 2143                                .unwrap_or_default()
 2144                        })?;
 2145
 2146                        if let Some(transaction) =
 2147                            project_transaction_command.0.remove(&buffer.handle)
 2148                        {
 2149                            zlog::trace!(
 2150                                logger =>
 2151                                "Successfully captured {} edits that resulted from command {}",
 2152                                transaction.edit_ids.len(),
 2153                                &command.command,
 2154                            );
 2155                            let transaction_id_project_transaction = transaction.id;
 2156                            buffer.handle.update(cx, |buffer, _| {
 2157                                // it may have been removed from history if push_to_history was
 2158                                // false in deserialize_workspace_edit. If so push it so we
 2159                                // can merge it with the format transaction
 2160                                // and pop the combined transaction off the history stack
 2161                                // later if push_to_history is false
 2162                                if buffer.get_transaction(transaction.id).is_none() {
 2163                                    buffer.push_transaction(transaction, Instant::now());
 2164                                }
 2165                                buffer.merge_transactions(
 2166                                    transaction_id_project_transaction,
 2167                                    formatting_transaction_id,
 2168                                );
 2169                            });
 2170                        }
 2171
 2172                        if project_transaction_command.0.is_empty() {
 2173                            continue;
 2174                        }
 2175
 2176                        let mut extra_buffers = String::new();
 2177                        for buffer in project_transaction_command.0.keys() {
 2178                            buffer.read_with(cx, |b, cx| {
 2179                                let Some(path) = b.project_path(cx) else {
 2180                                    return;
 2181                                };
 2182
 2183                                if !extra_buffers.is_empty() {
 2184                                    extra_buffers.push_str(", ");
 2185                                }
 2186                                extra_buffers.push_str(path.path.as_unix_str());
 2187                            });
 2188                        }
 2189                        zlog::warn!(
 2190                            logger =>
 2191                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2192                            &command.command,
 2193                            extra_buffers,
 2194                        );
 2195                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2196                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2197                        // add it so it's included, and merge it into the format transaction when its created later
 2198                    }
 2199                }
 2200            }
 2201        }
 2202
 2203        Ok(())
 2204    }
 2205
 2206    pub async fn format_ranges_via_lsp(
 2207        this: &WeakEntity<LspStore>,
 2208        buffer_handle: &Entity<Buffer>,
 2209        ranges: &[Range<Anchor>],
 2210        abs_path: &Path,
 2211        language_server: &Arc<LanguageServer>,
 2212        settings: &LanguageSettings,
 2213        cx: &mut AsyncApp,
 2214    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2215        let capabilities = &language_server.capabilities();
 2216        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2217        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2218            anyhow::bail!(
 2219                "{} language server does not support range formatting",
 2220                language_server.name()
 2221            );
 2222        }
 2223
 2224        let uri = file_path_to_lsp_url(abs_path)?;
 2225        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2226
 2227        let request_timeout = cx.update(|app| {
 2228            ProjectSettings::get_global(app)
 2229                .global_lsp_settings
 2230                .get_request_timeout()
 2231        });
 2232        let lsp_edits = {
 2233            let mut lsp_ranges = Vec::new();
 2234            this.update(cx, |_this, cx| {
 2235                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2236                // not have been sent to the language server. This seems like a fairly systemic
 2237                // issue, though, the resolution probably is not specific to formatting.
 2238                //
 2239                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2240                // LSP.
 2241                let snapshot = buffer_handle.read(cx).snapshot();
 2242                for range in ranges {
 2243                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2244                }
 2245                anyhow::Ok(())
 2246            })??;
 2247
 2248            let mut edits = None;
 2249            for range in lsp_ranges {
 2250                if let Some(mut edit) = language_server
 2251                    .request::<lsp::request::RangeFormatting>(
 2252                        lsp::DocumentRangeFormattingParams {
 2253                            text_document: text_document.clone(),
 2254                            range,
 2255                            options: lsp_command::lsp_formatting_options(settings),
 2256                            work_done_progress_params: Default::default(),
 2257                        },
 2258                        request_timeout,
 2259                    )
 2260                    .await
 2261                    .into_response()?
 2262                {
 2263                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2264                }
 2265            }
 2266            edits
 2267        };
 2268
 2269        if let Some(lsp_edits) = lsp_edits {
 2270            this.update(cx, |this, cx| {
 2271                this.as_local_mut().unwrap().edits_from_lsp(
 2272                    buffer_handle,
 2273                    lsp_edits,
 2274                    language_server.server_id(),
 2275                    None,
 2276                    cx,
 2277                )
 2278            })?
 2279            .await
 2280        } else {
 2281            Ok(Vec::with_capacity(0))
 2282        }
 2283    }
 2284
 2285    async fn format_via_lsp(
 2286        this: &WeakEntity<LspStore>,
 2287        buffer: &Entity<Buffer>,
 2288        abs_path: &Path,
 2289        language_server: &Arc<LanguageServer>,
 2290        settings: &LanguageSettings,
 2291        cx: &mut AsyncApp,
 2292    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2293        let logger = zlog::scoped!("lsp_format");
 2294        zlog::debug!(logger => "Formatting via LSP");
 2295
 2296        let uri = file_path_to_lsp_url(abs_path)?;
 2297        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2298        let capabilities = &language_server.capabilities();
 2299
 2300        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2301        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2302
 2303        let request_timeout = cx.update(|app| {
 2304            ProjectSettings::get_global(app)
 2305                .global_lsp_settings
 2306                .get_request_timeout()
 2307        });
 2308
 2309        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2310            let _timer = zlog::time!(logger => "format-full");
 2311            language_server
 2312                .request::<lsp::request::Formatting>(
 2313                    lsp::DocumentFormattingParams {
 2314                        text_document,
 2315                        options: lsp_command::lsp_formatting_options(settings),
 2316                        work_done_progress_params: Default::default(),
 2317                    },
 2318                    request_timeout,
 2319                )
 2320                .await
 2321                .into_response()?
 2322        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2323            let _timer = zlog::time!(logger => "format-range");
 2324            let buffer_start = lsp::Position::new(0, 0);
 2325            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2326            language_server
 2327                .request::<lsp::request::RangeFormatting>(
 2328                    lsp::DocumentRangeFormattingParams {
 2329                        text_document: text_document.clone(),
 2330                        range: lsp::Range::new(buffer_start, buffer_end),
 2331                        options: lsp_command::lsp_formatting_options(settings),
 2332                        work_done_progress_params: Default::default(),
 2333                    },
 2334                    request_timeout,
 2335                )
 2336                .await
 2337                .into_response()?
 2338        } else {
 2339            None
 2340        };
 2341
 2342        if let Some(lsp_edits) = lsp_edits {
 2343            this.update(cx, |this, cx| {
 2344                this.as_local_mut().unwrap().edits_from_lsp(
 2345                    buffer,
 2346                    lsp_edits,
 2347                    language_server.server_id(),
 2348                    None,
 2349                    cx,
 2350                )
 2351            })?
 2352            .await
 2353        } else {
 2354            Ok(Vec::with_capacity(0))
 2355        }
 2356    }
 2357
 2358    async fn format_via_external_command(
 2359        buffer: &FormattableBuffer,
 2360        command: &str,
 2361        arguments: Option<&[String]>,
 2362        cx: &mut AsyncApp,
 2363    ) -> Result<Option<Diff>> {
 2364        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2365            let file = File::from_dyn(buffer.file())?;
 2366            let worktree = file.worktree.read(cx);
 2367            let mut worktree_path = worktree.abs_path().to_path_buf();
 2368            if worktree.root_entry()?.is_file() {
 2369                worktree_path.pop();
 2370            }
 2371            Some(worktree_path)
 2372        });
 2373
 2374        let mut child = util::command::new_smol_command(command);
 2375
 2376        if let Some(buffer_env) = buffer.env.as_ref() {
 2377            child.envs(buffer_env);
 2378        }
 2379
 2380        if let Some(working_dir_path) = working_dir_path {
 2381            child.current_dir(working_dir_path);
 2382        }
 2383
 2384        if let Some(arguments) = arguments {
 2385            child.args(arguments.iter().map(|arg| {
 2386                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2387                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2388                } else {
 2389                    arg.replace("{buffer_path}", "Untitled")
 2390                }
 2391            }));
 2392        }
 2393
 2394        let mut child = child
 2395            .stdin(smol::process::Stdio::piped())
 2396            .stdout(smol::process::Stdio::piped())
 2397            .stderr(smol::process::Stdio::piped())
 2398            .spawn()?;
 2399
 2400        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2401        let text = buffer
 2402            .handle
 2403            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2404        for chunk in text.chunks() {
 2405            stdin.write_all(chunk.as_bytes()).await?;
 2406        }
 2407        stdin.flush().await?;
 2408
 2409        let output = child.output().await?;
 2410        anyhow::ensure!(
 2411            output.status.success(),
 2412            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2413            output.status.code(),
 2414            String::from_utf8_lossy(&output.stdout),
 2415            String::from_utf8_lossy(&output.stderr),
 2416        );
 2417
 2418        let stdout = String::from_utf8(output.stdout)?;
 2419        Ok(Some(
 2420            buffer
 2421                .handle
 2422                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2423                .await,
 2424        ))
 2425    }
 2426
 2427    async fn try_resolve_code_action(
 2428        lang_server: &LanguageServer,
 2429        action: &mut CodeAction,
 2430        request_timeout: Duration,
 2431    ) -> anyhow::Result<()> {
 2432        match &mut action.lsp_action {
 2433            LspAction::Action(lsp_action) => {
 2434                if !action.resolved
 2435                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2436                    && lsp_action.data.is_some()
 2437                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2438                {
 2439                    **lsp_action = lang_server
 2440                        .request::<lsp::request::CodeActionResolveRequest>(
 2441                            *lsp_action.clone(),
 2442                            request_timeout,
 2443                        )
 2444                        .await
 2445                        .into_response()?;
 2446                }
 2447            }
 2448            LspAction::CodeLens(lens) => {
 2449                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2450                    *lens = lang_server
 2451                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2452                        .await
 2453                        .into_response()?;
 2454                }
 2455            }
 2456            LspAction::Command(_) => {}
 2457        }
 2458
 2459        action.resolved = true;
 2460        anyhow::Ok(())
 2461    }
 2462
 2463    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2464        let buffer = buffer_handle.read(cx);
 2465
 2466        let file = buffer.file().cloned();
 2467
 2468        let Some(file) = File::from_dyn(file.as_ref()) else {
 2469            return;
 2470        };
 2471        if !file.is_local() {
 2472            return;
 2473        }
 2474        let path = ProjectPath::from_file(file, cx);
 2475        let worktree_id = file.worktree_id(cx);
 2476        let language = buffer.language().cloned();
 2477
 2478        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2479            for (server_id, diagnostics) in
 2480                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2481            {
 2482                self.update_buffer_diagnostics(
 2483                    buffer_handle,
 2484                    server_id,
 2485                    None,
 2486                    None,
 2487                    None,
 2488                    Vec::new(),
 2489                    diagnostics,
 2490                    cx,
 2491                )
 2492                .log_err();
 2493            }
 2494        }
 2495        let Some(language) = language else {
 2496            return;
 2497        };
 2498        let Some(snapshot) = self
 2499            .worktree_store
 2500            .read(cx)
 2501            .worktree_for_id(worktree_id, cx)
 2502            .map(|worktree| worktree.read(cx).snapshot())
 2503        else {
 2504            return;
 2505        };
 2506        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2507
 2508        for server_id in
 2509            self.lsp_tree
 2510                .get(path, language.name(), language.manifest(), &delegate, cx)
 2511        {
 2512            let server = self
 2513                .language_servers
 2514                .get(&server_id)
 2515                .and_then(|server_state| {
 2516                    if let LanguageServerState::Running { server, .. } = server_state {
 2517                        Some(server.clone())
 2518                    } else {
 2519                        None
 2520                    }
 2521                });
 2522            let server = match server {
 2523                Some(server) => server,
 2524                None => continue,
 2525            };
 2526
 2527            buffer_handle.update(cx, |buffer, cx| {
 2528                buffer.set_completion_triggers(
 2529                    server.server_id(),
 2530                    server
 2531                        .capabilities()
 2532                        .completion_provider
 2533                        .as_ref()
 2534                        .and_then(|provider| {
 2535                            provider
 2536                                .trigger_characters
 2537                                .as_ref()
 2538                                .map(|characters| characters.iter().cloned().collect())
 2539                        })
 2540                        .unwrap_or_default(),
 2541                    cx,
 2542                );
 2543            });
 2544        }
 2545    }
 2546
 2547    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2548        buffer.update(cx, |buffer, cx| {
 2549            let Some(language) = buffer.language() else {
 2550                return;
 2551            };
 2552            let path = ProjectPath {
 2553                worktree_id: old_file.worktree_id(cx),
 2554                path: old_file.path.clone(),
 2555            };
 2556            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2557                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2558                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2559            }
 2560        });
 2561    }
 2562
 2563    fn update_buffer_diagnostics(
 2564        &mut self,
 2565        buffer: &Entity<Buffer>,
 2566        server_id: LanguageServerId,
 2567        registration_id: Option<Option<SharedString>>,
 2568        result_id: Option<SharedString>,
 2569        version: Option<i32>,
 2570        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2571        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2572        cx: &mut Context<LspStore>,
 2573    ) -> Result<()> {
 2574        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2575            Ordering::Equal
 2576                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2577                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2578                .then_with(|| a.severity.cmp(&b.severity))
 2579                .then_with(|| a.message.cmp(&b.message))
 2580        }
 2581
 2582        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2583        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2584        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2585
 2586        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2587            Ordering::Equal
 2588                .then_with(|| a.range.start.cmp(&b.range.start))
 2589                .then_with(|| b.range.end.cmp(&a.range.end))
 2590                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2591        });
 2592
 2593        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2594
 2595        let edits_since_save = std::cell::LazyCell::new(|| {
 2596            let saved_version = buffer.read(cx).saved_version();
 2597            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2598        });
 2599
 2600        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2601
 2602        for (new_diagnostic, entry) in diagnostics {
 2603            let start;
 2604            let end;
 2605            if new_diagnostic && entry.diagnostic.is_disk_based {
 2606                // Some diagnostics are based on files on disk instead of buffers'
 2607                // current contents. Adjust these diagnostics' ranges to reflect
 2608                // any unsaved edits.
 2609                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2610                // and were properly adjusted on reuse.
 2611                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2612                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2613            } else {
 2614                start = entry.range.start;
 2615                end = entry.range.end;
 2616            }
 2617
 2618            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2619                ..snapshot.clip_point_utf16(end, Bias::Right);
 2620
 2621            // Expand empty ranges by one codepoint
 2622            if range.start == range.end {
 2623                // This will be go to the next boundary when being clipped
 2624                range.end.column += 1;
 2625                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2626                if range.start == range.end && range.end.column > 0 {
 2627                    range.start.column -= 1;
 2628                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2629                }
 2630            }
 2631
 2632            sanitized_diagnostics.push(DiagnosticEntry {
 2633                range,
 2634                diagnostic: entry.diagnostic,
 2635            });
 2636        }
 2637        drop(edits_since_save);
 2638
 2639        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2640        buffer.update(cx, |buffer, cx| {
 2641            if let Some(registration_id) = registration_id {
 2642                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2643                    self.buffer_pull_diagnostics_result_ids
 2644                        .entry(server_id)
 2645                        .or_default()
 2646                        .entry(registration_id)
 2647                        .or_default()
 2648                        .insert(abs_path, result_id);
 2649                }
 2650            }
 2651
 2652            buffer.update_diagnostics(server_id, set, cx)
 2653        });
 2654
 2655        Ok(())
 2656    }
 2657
 2658    fn register_language_server_for_invisible_worktree(
 2659        &mut self,
 2660        worktree: &Entity<Worktree>,
 2661        language_server_id: LanguageServerId,
 2662        cx: &mut App,
 2663    ) {
 2664        let worktree = worktree.read(cx);
 2665        let worktree_id = worktree.id();
 2666        debug_assert!(!worktree.is_visible());
 2667        let Some(mut origin_seed) = self
 2668            .language_server_ids
 2669            .iter()
 2670            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2671        else {
 2672            return;
 2673        };
 2674        origin_seed.worktree_id = worktree_id;
 2675        self.language_server_ids
 2676            .entry(origin_seed)
 2677            .or_insert_with(|| UnifiedLanguageServer {
 2678                id: language_server_id,
 2679                project_roots: Default::default(),
 2680            });
 2681    }
 2682
 2683    fn register_buffer_with_language_servers(
 2684        &mut self,
 2685        buffer_handle: &Entity<Buffer>,
 2686        only_register_servers: HashSet<LanguageServerSelector>,
 2687        cx: &mut Context<LspStore>,
 2688    ) {
 2689        let buffer = buffer_handle.read(cx);
 2690        let buffer_id = buffer.remote_id();
 2691
 2692        let Some(file) = File::from_dyn(buffer.file()) else {
 2693            return;
 2694        };
 2695        if !file.is_local() {
 2696            return;
 2697        }
 2698
 2699        let abs_path = file.abs_path(cx);
 2700        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2701            return;
 2702        };
 2703        let initial_snapshot = buffer.text_snapshot();
 2704        let worktree_id = file.worktree_id(cx);
 2705
 2706        let Some(language) = buffer.language().cloned() else {
 2707            return;
 2708        };
 2709        let path: Arc<RelPath> = file
 2710            .path()
 2711            .parent()
 2712            .map(Arc::from)
 2713            .unwrap_or_else(|| file.path().clone());
 2714        let Some(worktree) = self
 2715            .worktree_store
 2716            .read(cx)
 2717            .worktree_for_id(worktree_id, cx)
 2718        else {
 2719            return;
 2720        };
 2721        let language_name = language.name();
 2722        let (reused, delegate, servers) = self
 2723            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2724            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2725            .unwrap_or_else(|| {
 2726                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2727                let delegate: Arc<dyn ManifestDelegate> =
 2728                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2729
 2730                let servers = self
 2731                    .lsp_tree
 2732                    .walk(
 2733                        ProjectPath { worktree_id, path },
 2734                        language.name(),
 2735                        language.manifest(),
 2736                        &delegate,
 2737                        cx,
 2738                    )
 2739                    .collect::<Vec<_>>();
 2740                (false, lsp_delegate, servers)
 2741            });
 2742        let servers_and_adapters = servers
 2743            .into_iter()
 2744            .filter_map(|server_node| {
 2745                if reused && server_node.server_id().is_none() {
 2746                    return None;
 2747                }
 2748                if !only_register_servers.is_empty() {
 2749                    if let Some(server_id) = server_node.server_id()
 2750                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2751                    {
 2752                        return None;
 2753                    }
 2754                    if let Some(name) = server_node.name()
 2755                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2756                    {
 2757                        return None;
 2758                    }
 2759                }
 2760
 2761                let server_id = server_node.server_id_or_init(|disposition| {
 2762                    let path = &disposition.path;
 2763
 2764                    {
 2765                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2766
 2767                        let server_id = self.get_or_insert_language_server(
 2768                            &worktree,
 2769                            delegate.clone(),
 2770                            disposition,
 2771                            &language_name,
 2772                            cx,
 2773                        );
 2774
 2775                        if let Some(state) = self.language_servers.get(&server_id)
 2776                            && let Ok(uri) = uri
 2777                        {
 2778                            state.add_workspace_folder(uri);
 2779                        };
 2780                        server_id
 2781                    }
 2782                })?;
 2783                let server_state = self.language_servers.get(&server_id)?;
 2784                if let LanguageServerState::Running {
 2785                    server, adapter, ..
 2786                } = server_state
 2787                {
 2788                    Some((server.clone(), adapter.clone()))
 2789                } else {
 2790                    None
 2791                }
 2792            })
 2793            .collect::<Vec<_>>();
 2794        for (server, adapter) in servers_and_adapters {
 2795            buffer_handle.update(cx, |buffer, cx| {
 2796                buffer.set_completion_triggers(
 2797                    server.server_id(),
 2798                    server
 2799                        .capabilities()
 2800                        .completion_provider
 2801                        .as_ref()
 2802                        .and_then(|provider| {
 2803                            provider
 2804                                .trigger_characters
 2805                                .as_ref()
 2806                                .map(|characters| characters.iter().cloned().collect())
 2807                        })
 2808                        .unwrap_or_default(),
 2809                    cx,
 2810                );
 2811            });
 2812
 2813            let snapshot = LspBufferSnapshot {
 2814                version: 0,
 2815                snapshot: initial_snapshot.clone(),
 2816            };
 2817
 2818            let mut registered = false;
 2819            self.buffer_snapshots
 2820                .entry(buffer_id)
 2821                .or_default()
 2822                .entry(server.server_id())
 2823                .or_insert_with(|| {
 2824                    registered = true;
 2825                    server.register_buffer(
 2826                        uri.clone(),
 2827                        adapter.language_id(&language.name()),
 2828                        0,
 2829                        initial_snapshot.text(),
 2830                    );
 2831
 2832                    vec![snapshot]
 2833                });
 2834
 2835            self.buffers_opened_in_servers
 2836                .entry(buffer_id)
 2837                .or_default()
 2838                .insert(server.server_id());
 2839            if registered {
 2840                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2841                    language_server_id: server.server_id(),
 2842                    name: None,
 2843                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2844                        proto::RegisteredForBuffer {
 2845                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2846                            buffer_id: buffer_id.to_proto(),
 2847                        },
 2848                    ),
 2849                });
 2850            }
 2851        }
 2852    }
 2853
 2854    fn reuse_existing_language_server<'lang_name>(
 2855        &self,
 2856        server_tree: &LanguageServerTree,
 2857        worktree: &Entity<Worktree>,
 2858        language_name: &'lang_name LanguageName,
 2859        cx: &mut App,
 2860    ) -> Option<(
 2861        Arc<LocalLspAdapterDelegate>,
 2862        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2863    )> {
 2864        if worktree.read(cx).is_visible() {
 2865            return None;
 2866        }
 2867
 2868        let worktree_store = self.worktree_store.read(cx);
 2869        let servers = server_tree
 2870            .instances
 2871            .iter()
 2872            .filter(|(worktree_id, _)| {
 2873                worktree_store
 2874                    .worktree_for_id(**worktree_id, cx)
 2875                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2876            })
 2877            .flat_map(|(worktree_id, servers)| {
 2878                servers
 2879                    .roots
 2880                    .iter()
 2881                    .flat_map(|(_, language_servers)| language_servers)
 2882                    .map(move |(_, (server_node, server_languages))| {
 2883                        (worktree_id, server_node, server_languages)
 2884                    })
 2885                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2886                    .map(|(worktree_id, server_node, _)| {
 2887                        (
 2888                            *worktree_id,
 2889                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2890                        )
 2891                    })
 2892            })
 2893            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2894                acc.entry(worktree_id)
 2895                    .or_insert_with(Vec::new)
 2896                    .push(server_node);
 2897                acc
 2898            })
 2899            .into_values()
 2900            .max_by_key(|servers| servers.len())?;
 2901
 2902        let worktree_id = worktree.read(cx).id();
 2903        let apply = move |tree: &mut LanguageServerTree| {
 2904            for server_node in &servers {
 2905                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2906            }
 2907            servers
 2908        };
 2909
 2910        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2911        Some((delegate, apply))
 2912    }
 2913
 2914    pub(crate) fn unregister_old_buffer_from_language_servers(
 2915        &mut self,
 2916        buffer: &Entity<Buffer>,
 2917        old_file: &File,
 2918        cx: &mut App,
 2919    ) {
 2920        let old_path = match old_file.as_local() {
 2921            Some(local) => local.abs_path(cx),
 2922            None => return,
 2923        };
 2924
 2925        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2926            debug_panic!("{old_path:?} is not parseable as an URI");
 2927            return;
 2928        };
 2929        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2930    }
 2931
 2932    pub(crate) fn unregister_buffer_from_language_servers(
 2933        &mut self,
 2934        buffer: &Entity<Buffer>,
 2935        file_url: &lsp::Uri,
 2936        cx: &mut App,
 2937    ) {
 2938        buffer.update(cx, |buffer, cx| {
 2939            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2940
 2941            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2942                if snapshots
 2943                    .as_mut()
 2944                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2945                {
 2946                    language_server.unregister_buffer(file_url.clone());
 2947                }
 2948            }
 2949        });
 2950    }
 2951
 2952    fn buffer_snapshot_for_lsp_version(
 2953        &mut self,
 2954        buffer: &Entity<Buffer>,
 2955        server_id: LanguageServerId,
 2956        version: Option<i32>,
 2957        cx: &App,
 2958    ) -> Result<TextBufferSnapshot> {
 2959        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2960
 2961        if let Some(version) = version {
 2962            let buffer_id = buffer.read(cx).remote_id();
 2963            let snapshots = if let Some(snapshots) = self
 2964                .buffer_snapshots
 2965                .get_mut(&buffer_id)
 2966                .and_then(|m| m.get_mut(&server_id))
 2967            {
 2968                snapshots
 2969            } else if version == 0 {
 2970                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2971                // We detect this case and treat it as if the version was `None`.
 2972                return Ok(buffer.read(cx).text_snapshot());
 2973            } else {
 2974                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2975            };
 2976
 2977            let found_snapshot = snapshots
 2978                    .binary_search_by_key(&version, |e| e.version)
 2979                    .map(|ix| snapshots[ix].snapshot.clone())
 2980                    .map_err(|_| {
 2981                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2982                    })?;
 2983
 2984            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2985            Ok(found_snapshot)
 2986        } else {
 2987            Ok((buffer.read(cx)).text_snapshot())
 2988        }
 2989    }
 2990
 2991    async fn get_server_code_actions_from_action_kinds(
 2992        lsp_store: &WeakEntity<LspStore>,
 2993        language_server_id: LanguageServerId,
 2994        code_action_kinds: Vec<lsp::CodeActionKind>,
 2995        buffer: &Entity<Buffer>,
 2996        cx: &mut AsyncApp,
 2997    ) -> Result<Vec<CodeAction>> {
 2998        let actions = lsp_store
 2999            .update(cx, move |this, cx| {
 3000                let request = GetCodeActions {
 3001                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3002                    kinds: Some(code_action_kinds),
 3003                };
 3004                let server = LanguageServerToQuery::Other(language_server_id);
 3005                this.request_lsp(buffer.clone(), server, request, cx)
 3006            })?
 3007            .await?;
 3008        Ok(actions)
 3009    }
 3010
 3011    pub async fn execute_code_actions_on_server(
 3012        lsp_store: &WeakEntity<LspStore>,
 3013        language_server: &Arc<LanguageServer>,
 3014        actions: Vec<CodeAction>,
 3015        push_to_history: bool,
 3016        project_transaction: &mut ProjectTransaction,
 3017        cx: &mut AsyncApp,
 3018    ) -> anyhow::Result<()> {
 3019        let request_timeout = cx.update(|app| {
 3020            ProjectSettings::get_global(app)
 3021                .global_lsp_settings
 3022                .get_request_timeout()
 3023        });
 3024
 3025        for mut action in actions {
 3026            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3027                .await
 3028                .context("resolving a formatting code action")?;
 3029
 3030            if let Some(edit) = action.lsp_action.edit() {
 3031                if edit.changes.is_none() && edit.document_changes.is_none() {
 3032                    continue;
 3033                }
 3034
 3035                let new = Self::deserialize_workspace_edit(
 3036                    lsp_store.upgrade().context("project dropped")?,
 3037                    edit.clone(),
 3038                    push_to_history,
 3039                    language_server.clone(),
 3040                    cx,
 3041                )
 3042                .await?;
 3043                project_transaction.0.extend(new.0);
 3044            }
 3045
 3046            let Some(command) = action.lsp_action.command() else {
 3047                continue;
 3048            };
 3049
 3050            let server_capabilities = language_server.capabilities();
 3051            let available_commands = server_capabilities
 3052                .execute_command_provider
 3053                .as_ref()
 3054                .map(|options| options.commands.as_slice())
 3055                .unwrap_or_default();
 3056            if !available_commands.contains(&command.command) {
 3057                log::warn!(
 3058                    "Cannot execute a command {} not listed in the language server capabilities",
 3059                    command.command
 3060                );
 3061                continue;
 3062            }
 3063
 3064            lsp_store.update(cx, |lsp_store, _| {
 3065                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3066                    mode.last_workspace_edits_by_language_server
 3067                        .remove(&language_server.server_id());
 3068                }
 3069            })?;
 3070
 3071            language_server
 3072                .request::<lsp::request::ExecuteCommand>(
 3073                    lsp::ExecuteCommandParams {
 3074                        command: command.command.clone(),
 3075                        arguments: command.arguments.clone().unwrap_or_default(),
 3076                        ..Default::default()
 3077                    },
 3078                    request_timeout,
 3079                )
 3080                .await
 3081                .into_response()
 3082                .context("execute command")?;
 3083
 3084            lsp_store.update(cx, |this, _| {
 3085                if let LspStoreMode::Local(mode) = &mut this.mode {
 3086                    project_transaction.0.extend(
 3087                        mode.last_workspace_edits_by_language_server
 3088                            .remove(&language_server.server_id())
 3089                            .unwrap_or_default()
 3090                            .0,
 3091                    )
 3092                }
 3093            })?;
 3094        }
 3095        Ok(())
 3096    }
 3097
 3098    pub async fn deserialize_text_edits(
 3099        this: Entity<LspStore>,
 3100        buffer_to_edit: Entity<Buffer>,
 3101        edits: Vec<lsp::TextEdit>,
 3102        push_to_history: bool,
 3103        _: Arc<CachedLspAdapter>,
 3104        language_server: Arc<LanguageServer>,
 3105        cx: &mut AsyncApp,
 3106    ) -> Result<Option<Transaction>> {
 3107        let edits = this
 3108            .update(cx, |this, cx| {
 3109                this.as_local_mut().unwrap().edits_from_lsp(
 3110                    &buffer_to_edit,
 3111                    edits,
 3112                    language_server.server_id(),
 3113                    None,
 3114                    cx,
 3115                )
 3116            })
 3117            .await?;
 3118
 3119        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3120            buffer.finalize_last_transaction();
 3121            buffer.start_transaction();
 3122            for (range, text) in edits {
 3123                buffer.edit([(range, text)], None, cx);
 3124            }
 3125
 3126            if buffer.end_transaction(cx).is_some() {
 3127                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3128                if !push_to_history {
 3129                    buffer.forget_transaction(transaction.id);
 3130                }
 3131                Some(transaction)
 3132            } else {
 3133                None
 3134            }
 3135        });
 3136
 3137        Ok(transaction)
 3138    }
 3139
 3140    #[allow(clippy::type_complexity)]
 3141    pub fn edits_from_lsp(
 3142        &mut self,
 3143        buffer: &Entity<Buffer>,
 3144        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3145        server_id: LanguageServerId,
 3146        version: Option<i32>,
 3147        cx: &mut Context<LspStore>,
 3148    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3149        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3150        cx.background_spawn(async move {
 3151            let snapshot = snapshot?;
 3152            let mut lsp_edits = lsp_edits
 3153                .into_iter()
 3154                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3155                .collect::<Vec<_>>();
 3156
 3157            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3158
 3159            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3160            let mut edits = Vec::new();
 3161            while let Some((range, mut new_text)) = lsp_edits.next() {
 3162                // Clip invalid ranges provided by the language server.
 3163                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3164                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3165
 3166                // Combine any LSP edits that are adjacent.
 3167                //
 3168                // Also, combine LSP edits that are separated from each other by only
 3169                // a newline. This is important because for some code actions,
 3170                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3171                // are separated by unchanged newline characters.
 3172                //
 3173                // In order for the diffing logic below to work properly, any edits that
 3174                // cancel each other out must be combined into one.
 3175                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3176                    if next_range.start.0 > range.end {
 3177                        if next_range.start.0.row > range.end.row + 1
 3178                            || next_range.start.0.column > 0
 3179                            || snapshot.clip_point_utf16(
 3180                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3181                                Bias::Left,
 3182                            ) > range.end
 3183                        {
 3184                            break;
 3185                        }
 3186                        new_text.push('\n');
 3187                    }
 3188                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3189                    new_text.push_str(next_text);
 3190                    lsp_edits.next();
 3191                }
 3192
 3193                // For multiline edits, perform a diff of the old and new text so that
 3194                // we can identify the changes more precisely, preserving the locations
 3195                // of any anchors positioned in the unchanged regions.
 3196                if range.end.row > range.start.row {
 3197                    let offset = range.start.to_offset(&snapshot);
 3198                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3199                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3200                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3201                        (
 3202                            snapshot.anchor_after(offset + range.start)
 3203                                ..snapshot.anchor_before(offset + range.end),
 3204                            replacement,
 3205                        )
 3206                    }));
 3207                } else if range.end == range.start {
 3208                    let anchor = snapshot.anchor_after(range.start);
 3209                    edits.push((anchor..anchor, new_text.into()));
 3210                } else {
 3211                    let edit_start = snapshot.anchor_after(range.start);
 3212                    let edit_end = snapshot.anchor_before(range.end);
 3213                    edits.push((edit_start..edit_end, new_text.into()));
 3214                }
 3215            }
 3216
 3217            Ok(edits)
 3218        })
 3219    }
 3220
 3221    pub(crate) async fn deserialize_workspace_edit(
 3222        this: Entity<LspStore>,
 3223        edit: lsp::WorkspaceEdit,
 3224        push_to_history: bool,
 3225        language_server: Arc<LanguageServer>,
 3226        cx: &mut AsyncApp,
 3227    ) -> Result<ProjectTransaction> {
 3228        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3229
 3230        let mut operations = Vec::new();
 3231        if let Some(document_changes) = edit.document_changes {
 3232            match document_changes {
 3233                lsp::DocumentChanges::Edits(edits) => {
 3234                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3235                }
 3236                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3237            }
 3238        } else if let Some(changes) = edit.changes {
 3239            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3240                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3241                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3242                        uri,
 3243                        version: None,
 3244                    },
 3245                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3246                })
 3247            }));
 3248        }
 3249
 3250        let mut project_transaction = ProjectTransaction::default();
 3251        for operation in operations {
 3252            match operation {
 3253                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3254                    let abs_path = op
 3255                        .uri
 3256                        .to_file_path()
 3257                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3258
 3259                    if let Some(parent_path) = abs_path.parent() {
 3260                        fs.create_dir(parent_path).await?;
 3261                    }
 3262                    if abs_path.ends_with("/") {
 3263                        fs.create_dir(&abs_path).await?;
 3264                    } else {
 3265                        fs.create_file(
 3266                            &abs_path,
 3267                            op.options
 3268                                .map(|options| fs::CreateOptions {
 3269                                    overwrite: options.overwrite.unwrap_or(false),
 3270                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3271                                })
 3272                                .unwrap_or_default(),
 3273                        )
 3274                        .await?;
 3275                    }
 3276                }
 3277
 3278                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3279                    let source_abs_path = op
 3280                        .old_uri
 3281                        .to_file_path()
 3282                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3283                    let target_abs_path = op
 3284                        .new_uri
 3285                        .to_file_path()
 3286                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3287
 3288                    let options = fs::RenameOptions {
 3289                        overwrite: op
 3290                            .options
 3291                            .as_ref()
 3292                            .and_then(|options| options.overwrite)
 3293                            .unwrap_or(false),
 3294                        ignore_if_exists: op
 3295                            .options
 3296                            .as_ref()
 3297                            .and_then(|options| options.ignore_if_exists)
 3298                            .unwrap_or(false),
 3299                        create_parents: true,
 3300                    };
 3301
 3302                    fs.rename(&source_abs_path, &target_abs_path, options)
 3303                        .await?;
 3304                }
 3305
 3306                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3307                    let abs_path = op
 3308                        .uri
 3309                        .to_file_path()
 3310                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3311                    let options = op
 3312                        .options
 3313                        .map(|options| fs::RemoveOptions {
 3314                            recursive: options.recursive.unwrap_or(false),
 3315                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3316                        })
 3317                        .unwrap_or_default();
 3318                    if abs_path.ends_with("/") {
 3319                        fs.remove_dir(&abs_path, options).await?;
 3320                    } else {
 3321                        fs.remove_file(&abs_path, options).await?;
 3322                    }
 3323                }
 3324
 3325                lsp::DocumentChangeOperation::Edit(op) => {
 3326                    let buffer_to_edit = this
 3327                        .update(cx, |this, cx| {
 3328                            this.open_local_buffer_via_lsp(
 3329                                op.text_document.uri.clone(),
 3330                                language_server.server_id(),
 3331                                cx,
 3332                            )
 3333                        })
 3334                        .await?;
 3335
 3336                    let edits = this
 3337                        .update(cx, |this, cx| {
 3338                            let path = buffer_to_edit.read(cx).project_path(cx);
 3339                            let active_entry = this.active_entry;
 3340                            let is_active_entry = path.is_some_and(|project_path| {
 3341                                this.worktree_store
 3342                                    .read(cx)
 3343                                    .entry_for_path(&project_path, cx)
 3344                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3345                            });
 3346                            let local = this.as_local_mut().unwrap();
 3347
 3348                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3349                            for edit in op.edits {
 3350                                match edit {
 3351                                    Edit::Plain(edit) => {
 3352                                        if !edits.contains(&edit) {
 3353                                            edits.push(edit)
 3354                                        }
 3355                                    }
 3356                                    Edit::Annotated(edit) => {
 3357                                        if !edits.contains(&edit.text_edit) {
 3358                                            edits.push(edit.text_edit)
 3359                                        }
 3360                                    }
 3361                                    Edit::Snippet(edit) => {
 3362                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3363                                        else {
 3364                                            continue;
 3365                                        };
 3366
 3367                                        if is_active_entry {
 3368                                            snippet_edits.push((edit.range, snippet));
 3369                                        } else {
 3370                                            // Since this buffer is not focused, apply a normal edit.
 3371                                            let new_edit = TextEdit {
 3372                                                range: edit.range,
 3373                                                new_text: snippet.text,
 3374                                            };
 3375                                            if !edits.contains(&new_edit) {
 3376                                                edits.push(new_edit);
 3377                                            }
 3378                                        }
 3379                                    }
 3380                                }
 3381                            }
 3382                            if !snippet_edits.is_empty() {
 3383                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3384                                let version = if let Some(buffer_version) = op.text_document.version
 3385                                {
 3386                                    local
 3387                                        .buffer_snapshot_for_lsp_version(
 3388                                            &buffer_to_edit,
 3389                                            language_server.server_id(),
 3390                                            Some(buffer_version),
 3391                                            cx,
 3392                                        )
 3393                                        .ok()
 3394                                        .map(|snapshot| snapshot.version)
 3395                                } else {
 3396                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3397                                };
 3398
 3399                                let most_recent_edit =
 3400                                    version.and_then(|version| version.most_recent());
 3401                                // Check if the edit that triggered that edit has been made by this participant.
 3402
 3403                                if let Some(most_recent_edit) = most_recent_edit {
 3404                                    cx.emit(LspStoreEvent::SnippetEdit {
 3405                                        buffer_id,
 3406                                        edits: snippet_edits,
 3407                                        most_recent_edit,
 3408                                    });
 3409                                }
 3410                            }
 3411
 3412                            local.edits_from_lsp(
 3413                                &buffer_to_edit,
 3414                                edits,
 3415                                language_server.server_id(),
 3416                                op.text_document.version,
 3417                                cx,
 3418                            )
 3419                        })
 3420                        .await?;
 3421
 3422                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3423                        buffer.finalize_last_transaction();
 3424                        buffer.start_transaction();
 3425                        for (range, text) in edits {
 3426                            buffer.edit([(range, text)], None, cx);
 3427                        }
 3428
 3429                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3430                            if push_to_history {
 3431                                buffer.finalize_last_transaction();
 3432                                buffer.get_transaction(transaction_id).cloned()
 3433                            } else {
 3434                                buffer.forget_transaction(transaction_id)
 3435                            }
 3436                        })
 3437                    });
 3438                    if let Some(transaction) = transaction {
 3439                        project_transaction.0.insert(buffer_to_edit, transaction);
 3440                    }
 3441                }
 3442            }
 3443        }
 3444
 3445        Ok(project_transaction)
 3446    }
 3447
 3448    async fn on_lsp_workspace_edit(
 3449        this: WeakEntity<LspStore>,
 3450        params: lsp::ApplyWorkspaceEditParams,
 3451        server_id: LanguageServerId,
 3452        cx: &mut AsyncApp,
 3453    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3454        let this = this.upgrade().context("project project closed")?;
 3455        let language_server = this
 3456            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3457            .context("language server not found")?;
 3458        let transaction = Self::deserialize_workspace_edit(
 3459            this.clone(),
 3460            params.edit,
 3461            true,
 3462            language_server.clone(),
 3463            cx,
 3464        )
 3465        .await
 3466        .log_err();
 3467        this.update(cx, |this, cx| {
 3468            if let Some(transaction) = transaction {
 3469                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3470
 3471                this.as_local_mut()
 3472                    .unwrap()
 3473                    .last_workspace_edits_by_language_server
 3474                    .insert(server_id, transaction);
 3475            }
 3476        });
 3477        Ok(lsp::ApplyWorkspaceEditResponse {
 3478            applied: true,
 3479            failed_change: None,
 3480            failure_reason: None,
 3481        })
 3482    }
 3483
 3484    fn remove_worktree(
 3485        &mut self,
 3486        id_to_remove: WorktreeId,
 3487        cx: &mut Context<LspStore>,
 3488    ) -> Vec<LanguageServerId> {
 3489        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3490        self.diagnostics.remove(&id_to_remove);
 3491        self.prettier_store.update(cx, |prettier_store, cx| {
 3492            prettier_store.remove_worktree(id_to_remove, cx);
 3493        });
 3494
 3495        let mut servers_to_remove = BTreeSet::default();
 3496        let mut servers_to_preserve = HashSet::default();
 3497        for (seed, state) in &self.language_server_ids {
 3498            if seed.worktree_id == id_to_remove {
 3499                servers_to_remove.insert(state.id);
 3500            } else {
 3501                servers_to_preserve.insert(state.id);
 3502            }
 3503        }
 3504        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3505        self.language_server_ids
 3506            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3507        for server_id_to_remove in &servers_to_remove {
 3508            self.language_server_watched_paths
 3509                .remove(server_id_to_remove);
 3510            self.language_server_paths_watched_for_rename
 3511                .remove(server_id_to_remove);
 3512            self.last_workspace_edits_by_language_server
 3513                .remove(server_id_to_remove);
 3514            self.language_servers.remove(server_id_to_remove);
 3515            self.buffer_pull_diagnostics_result_ids
 3516                .remove(server_id_to_remove);
 3517            self.workspace_pull_diagnostics_result_ids
 3518                .remove(server_id_to_remove);
 3519            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3520                buffer_servers.remove(server_id_to_remove);
 3521            }
 3522            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3523        }
 3524        servers_to_remove.into_iter().collect()
 3525    }
 3526
 3527    fn rebuild_watched_paths_inner<'a>(
 3528        &'a self,
 3529        language_server_id: LanguageServerId,
 3530        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3531        cx: &mut Context<LspStore>,
 3532    ) -> LanguageServerWatchedPathsBuilder {
 3533        let worktrees = self
 3534            .worktree_store
 3535            .read(cx)
 3536            .worktrees()
 3537            .filter_map(|worktree| {
 3538                self.language_servers_for_worktree(worktree.read(cx).id())
 3539                    .find(|server| server.server_id() == language_server_id)
 3540                    .map(|_| worktree)
 3541            })
 3542            .collect::<Vec<_>>();
 3543
 3544        let mut worktree_globs = HashMap::default();
 3545        let mut abs_globs = HashMap::default();
 3546        log::trace!(
 3547            "Processing new watcher paths for language server with id {}",
 3548            language_server_id
 3549        );
 3550
 3551        for watcher in watchers {
 3552            if let Some((worktree, literal_prefix, pattern)) =
 3553                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3554            {
 3555                worktree.update(cx, |worktree, _| {
 3556                    if let Some((tree, glob)) =
 3557                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3558                    {
 3559                        tree.add_path_prefix_to_scan(literal_prefix);
 3560                        worktree_globs
 3561                            .entry(tree.id())
 3562                            .or_insert_with(GlobSetBuilder::new)
 3563                            .add(glob);
 3564                    }
 3565                });
 3566            } else {
 3567                let (path, pattern) = match &watcher.glob_pattern {
 3568                    lsp::GlobPattern::String(s) => {
 3569                        let watcher_path = SanitizedPath::new(s);
 3570                        let path = glob_literal_prefix(watcher_path.as_path());
 3571                        let pattern = watcher_path
 3572                            .as_path()
 3573                            .strip_prefix(&path)
 3574                            .map(|p| p.to_string_lossy().into_owned())
 3575                            .unwrap_or_else(|e| {
 3576                                debug_panic!(
 3577                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3578                                    s,
 3579                                    path.display(),
 3580                                    e
 3581                                );
 3582                                watcher_path.as_path().to_string_lossy().into_owned()
 3583                            });
 3584                        (path, pattern)
 3585                    }
 3586                    lsp::GlobPattern::Relative(rp) => {
 3587                        let Ok(mut base_uri) = match &rp.base_uri {
 3588                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3589                            lsp::OneOf::Right(base_uri) => base_uri,
 3590                        }
 3591                        .to_file_path() else {
 3592                            continue;
 3593                        };
 3594
 3595                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3596                        let pattern = Path::new(&rp.pattern)
 3597                            .strip_prefix(&path)
 3598                            .map(|p| p.to_string_lossy().into_owned())
 3599                            .unwrap_or_else(|e| {
 3600                                debug_panic!(
 3601                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3602                                    rp.pattern,
 3603                                    path.display(),
 3604                                    e
 3605                                );
 3606                                rp.pattern.clone()
 3607                            });
 3608                        base_uri.push(path);
 3609                        (base_uri, pattern)
 3610                    }
 3611                };
 3612
 3613                if let Some(glob) = Glob::new(&pattern).log_err() {
 3614                    if !path
 3615                        .components()
 3616                        .any(|c| matches!(c, path::Component::Normal(_)))
 3617                    {
 3618                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3619                        // rather than adding a new watcher for `/`.
 3620                        for worktree in &worktrees {
 3621                            worktree_globs
 3622                                .entry(worktree.read(cx).id())
 3623                                .or_insert_with(GlobSetBuilder::new)
 3624                                .add(glob.clone());
 3625                        }
 3626                    } else {
 3627                        abs_globs
 3628                            .entry(path.into())
 3629                            .or_insert_with(GlobSetBuilder::new)
 3630                            .add(glob);
 3631                    }
 3632                }
 3633            }
 3634        }
 3635
 3636        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3637        for (worktree_id, builder) in worktree_globs {
 3638            if let Ok(globset) = builder.build() {
 3639                watch_builder.watch_worktree(worktree_id, globset);
 3640            }
 3641        }
 3642        for (abs_path, builder) in abs_globs {
 3643            if let Ok(globset) = builder.build() {
 3644                watch_builder.watch_abs_path(abs_path, globset);
 3645            }
 3646        }
 3647        watch_builder
 3648    }
 3649
 3650    fn worktree_and_path_for_file_watcher(
 3651        worktrees: &[Entity<Worktree>],
 3652        watcher: &FileSystemWatcher,
 3653        cx: &App,
 3654    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3655        worktrees.iter().find_map(|worktree| {
 3656            let tree = worktree.read(cx);
 3657            let worktree_root_path = tree.abs_path();
 3658            let path_style = tree.path_style();
 3659            match &watcher.glob_pattern {
 3660                lsp::GlobPattern::String(s) => {
 3661                    let watcher_path = SanitizedPath::new(s);
 3662                    let relative = watcher_path
 3663                        .as_path()
 3664                        .strip_prefix(&worktree_root_path)
 3665                        .ok()?;
 3666                    let literal_prefix = glob_literal_prefix(relative);
 3667                    Some((
 3668                        worktree.clone(),
 3669                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3670                        relative.to_string_lossy().into_owned(),
 3671                    ))
 3672                }
 3673                lsp::GlobPattern::Relative(rp) => {
 3674                    let base_uri = match &rp.base_uri {
 3675                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3676                        lsp::OneOf::Right(base_uri) => base_uri,
 3677                    }
 3678                    .to_file_path()
 3679                    .ok()?;
 3680                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3681                    let mut literal_prefix = relative.to_owned();
 3682                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3683                    Some((
 3684                        worktree.clone(),
 3685                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3686                        rp.pattern.clone(),
 3687                    ))
 3688                }
 3689            }
 3690        })
 3691    }
 3692
 3693    fn rebuild_watched_paths(
 3694        &mut self,
 3695        language_server_id: LanguageServerId,
 3696        cx: &mut Context<LspStore>,
 3697    ) {
 3698        let Some(registrations) = self
 3699            .language_server_dynamic_registrations
 3700            .get(&language_server_id)
 3701        else {
 3702            return;
 3703        };
 3704
 3705        let watch_builder = self.rebuild_watched_paths_inner(
 3706            language_server_id,
 3707            registrations.did_change_watched_files.values().flatten(),
 3708            cx,
 3709        );
 3710        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3711        self.language_server_watched_paths
 3712            .insert(language_server_id, watcher);
 3713
 3714        cx.notify();
 3715    }
 3716
 3717    fn on_lsp_did_change_watched_files(
 3718        &mut self,
 3719        language_server_id: LanguageServerId,
 3720        registration_id: &str,
 3721        params: DidChangeWatchedFilesRegistrationOptions,
 3722        cx: &mut Context<LspStore>,
 3723    ) {
 3724        let registrations = self
 3725            .language_server_dynamic_registrations
 3726            .entry(language_server_id)
 3727            .or_default();
 3728
 3729        registrations
 3730            .did_change_watched_files
 3731            .insert(registration_id.to_string(), params.watchers);
 3732
 3733        self.rebuild_watched_paths(language_server_id, cx);
 3734    }
 3735
 3736    fn on_lsp_unregister_did_change_watched_files(
 3737        &mut self,
 3738        language_server_id: LanguageServerId,
 3739        registration_id: &str,
 3740        cx: &mut Context<LspStore>,
 3741    ) {
 3742        let registrations = self
 3743            .language_server_dynamic_registrations
 3744            .entry(language_server_id)
 3745            .or_default();
 3746
 3747        if registrations
 3748            .did_change_watched_files
 3749            .remove(registration_id)
 3750            .is_some()
 3751        {
 3752            log::info!(
 3753                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3754                language_server_id,
 3755                registration_id
 3756            );
 3757        } else {
 3758            log::warn!(
 3759                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3760                language_server_id,
 3761                registration_id
 3762            );
 3763        }
 3764
 3765        self.rebuild_watched_paths(language_server_id, cx);
 3766    }
 3767
 3768    async fn initialization_options_for_adapter(
 3769        adapter: Arc<dyn LspAdapter>,
 3770        delegate: &Arc<dyn LspAdapterDelegate>,
 3771    ) -> Result<Option<serde_json::Value>> {
 3772        let Some(mut initialization_config) =
 3773            adapter.clone().initialization_options(delegate).await?
 3774        else {
 3775            return Ok(None);
 3776        };
 3777
 3778        for other_adapter in delegate.registered_lsp_adapters() {
 3779            if other_adapter.name() == adapter.name() {
 3780                continue;
 3781            }
 3782            if let Ok(Some(target_config)) = other_adapter
 3783                .clone()
 3784                .additional_initialization_options(adapter.name(), delegate)
 3785                .await
 3786            {
 3787                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3788            }
 3789        }
 3790
 3791        Ok(Some(initialization_config))
 3792    }
 3793
 3794    async fn workspace_configuration_for_adapter(
 3795        adapter: Arc<dyn LspAdapter>,
 3796        delegate: &Arc<dyn LspAdapterDelegate>,
 3797        toolchain: Option<Toolchain>,
 3798        requested_uri: Option<Uri>,
 3799        cx: &mut AsyncApp,
 3800    ) -> Result<serde_json::Value> {
 3801        let mut workspace_config = adapter
 3802            .clone()
 3803            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3804            .await?;
 3805
 3806        for other_adapter in delegate.registered_lsp_adapters() {
 3807            if other_adapter.name() == adapter.name() {
 3808                continue;
 3809            }
 3810            if let Ok(Some(target_config)) = other_adapter
 3811                .clone()
 3812                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3813                .await
 3814            {
 3815                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3816            }
 3817        }
 3818
 3819        Ok(workspace_config)
 3820    }
 3821
 3822    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3823        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3824            Some(server.clone())
 3825        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3826            Some(Arc::clone(server))
 3827        } else {
 3828            None
 3829        }
 3830    }
 3831}
 3832
 3833fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3834    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3835        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3836            language_server_id: server.server_id(),
 3837            name: Some(server.name()),
 3838            message: proto::update_language_server::Variant::MetadataUpdated(
 3839                proto::ServerMetadataUpdated {
 3840                    capabilities: Some(capabilities),
 3841                    binary: Some(proto::LanguageServerBinaryInfo {
 3842                        path: server.binary().path.to_string_lossy().into_owned(),
 3843                        arguments: server
 3844                            .binary()
 3845                            .arguments
 3846                            .iter()
 3847                            .map(|arg| arg.to_string_lossy().into_owned())
 3848                            .collect(),
 3849                    }),
 3850                    configuration: serde_json::to_string(server.configuration()).ok(),
 3851                    workspace_folders: server
 3852                        .workspace_folders()
 3853                        .iter()
 3854                        .map(|uri| uri.to_string())
 3855                        .collect(),
 3856                },
 3857            ),
 3858        });
 3859    }
 3860}
 3861
 3862#[derive(Debug)]
 3863pub struct FormattableBuffer {
 3864    handle: Entity<Buffer>,
 3865    abs_path: Option<PathBuf>,
 3866    env: Option<HashMap<String, String>>,
 3867    ranges: Option<Vec<Range<Anchor>>>,
 3868}
 3869
 3870pub struct RemoteLspStore {
 3871    upstream_client: Option<AnyProtoClient>,
 3872    upstream_project_id: u64,
 3873}
 3874
 3875pub(crate) enum LspStoreMode {
 3876    Local(LocalLspStore),   // ssh host and collab host
 3877    Remote(RemoteLspStore), // collab guest
 3878}
 3879
 3880impl LspStoreMode {
 3881    fn is_local(&self) -> bool {
 3882        matches!(self, LspStoreMode::Local(_))
 3883    }
 3884}
 3885
 3886pub struct LspStore {
 3887    mode: LspStoreMode,
 3888    last_formatting_failure: Option<String>,
 3889    downstream_client: Option<(AnyProtoClient, u64)>,
 3890    nonce: u128,
 3891    buffer_store: Entity<BufferStore>,
 3892    worktree_store: Entity<WorktreeStore>,
 3893    pub languages: Arc<LanguageRegistry>,
 3894    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3895    active_entry: Option<ProjectEntryId>,
 3896    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3897    _maintain_buffer_languages: Task<()>,
 3898    diagnostic_summaries:
 3899        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3900    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3901    semantic_token_config: SemanticTokenConfig,
 3902    lsp_data: HashMap<BufferId, BufferLspData>,
 3903    next_hint_id: Arc<AtomicUsize>,
 3904}
 3905
 3906#[derive(Debug)]
 3907pub struct BufferLspData {
 3908    buffer_version: Global,
 3909    document_colors: Option<DocumentColorData>,
 3910    code_lens: Option<CodeLensData>,
 3911    semantic_tokens: Option<SemanticTokensData>,
 3912    folding_ranges: Option<FoldingRangeData>,
 3913    inlay_hints: BufferInlayHints,
 3914    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3915    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3916}
 3917
 3918#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3919struct LspKey {
 3920    request_type: TypeId,
 3921    server_queried: Option<LanguageServerId>,
 3922}
 3923
 3924impl BufferLspData {
 3925    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3926        Self {
 3927            buffer_version: buffer.read(cx).version(),
 3928            document_colors: None,
 3929            code_lens: None,
 3930            semantic_tokens: None,
 3931            folding_ranges: None,
 3932            inlay_hints: BufferInlayHints::new(buffer, cx),
 3933            lsp_requests: HashMap::default(),
 3934            chunk_lsp_requests: HashMap::default(),
 3935        }
 3936    }
 3937
 3938    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3939        if let Some(document_colors) = &mut self.document_colors {
 3940            document_colors.remove_server_data(for_server);
 3941        }
 3942
 3943        if let Some(code_lens) = &mut self.code_lens {
 3944            code_lens.remove_server_data(for_server);
 3945        }
 3946
 3947        self.inlay_hints.remove_server_data(for_server);
 3948
 3949        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3950            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3951            semantic_tokens
 3952                .latest_invalidation_requests
 3953                .remove(&for_server);
 3954        }
 3955
 3956        if let Some(folding_ranges) = &mut self.folding_ranges {
 3957            folding_ranges.ranges.remove(&for_server);
 3958        }
 3959    }
 3960
 3961    #[cfg(any(test, feature = "test-support"))]
 3962    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3963        &self.inlay_hints
 3964    }
 3965}
 3966
 3967#[derive(Debug)]
 3968pub enum LspStoreEvent {
 3969    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3970    LanguageServerRemoved(LanguageServerId),
 3971    LanguageServerUpdate {
 3972        language_server_id: LanguageServerId,
 3973        name: Option<LanguageServerName>,
 3974        message: proto::update_language_server::Variant,
 3975    },
 3976    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3977    LanguageServerPrompt(LanguageServerPromptRequest),
 3978    LanguageDetected {
 3979        buffer: Entity<Buffer>,
 3980        new_language: Option<Arc<Language>>,
 3981    },
 3982    Notification(String),
 3983    RefreshInlayHints {
 3984        server_id: LanguageServerId,
 3985        request_id: Option<usize>,
 3986    },
 3987    RefreshSemanticTokens {
 3988        server_id: LanguageServerId,
 3989        request_id: Option<usize>,
 3990    },
 3991    RefreshCodeLens,
 3992    DiagnosticsUpdated {
 3993        server_id: LanguageServerId,
 3994        paths: Vec<ProjectPath>,
 3995    },
 3996    DiskBasedDiagnosticsStarted {
 3997        language_server_id: LanguageServerId,
 3998    },
 3999    DiskBasedDiagnosticsFinished {
 4000        language_server_id: LanguageServerId,
 4001    },
 4002    SnippetEdit {
 4003        buffer_id: BufferId,
 4004        edits: Vec<(lsp::Range, Snippet)>,
 4005        most_recent_edit: clock::Lamport,
 4006    },
 4007    WorkspaceEditApplied(ProjectTransaction),
 4008}
 4009
 4010#[derive(Clone, Debug, Serialize)]
 4011pub struct LanguageServerStatus {
 4012    pub name: LanguageServerName,
 4013    pub server_version: Option<SharedString>,
 4014    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4015    pub has_pending_diagnostic_updates: bool,
 4016    pub progress_tokens: HashSet<ProgressToken>,
 4017    pub worktree: Option<WorktreeId>,
 4018    pub binary: Option<LanguageServerBinary>,
 4019    pub configuration: Option<Value>,
 4020    pub workspace_folders: BTreeSet<Uri>,
 4021    pub process_id: Option<u32>,
 4022}
 4023
 4024#[derive(Clone, Debug)]
 4025struct CoreSymbol {
 4026    pub language_server_name: LanguageServerName,
 4027    pub source_worktree_id: WorktreeId,
 4028    pub source_language_server_id: LanguageServerId,
 4029    pub path: SymbolLocation,
 4030    pub name: String,
 4031    pub kind: lsp::SymbolKind,
 4032    pub range: Range<Unclipped<PointUtf16>>,
 4033    pub container_name: Option<String>,
 4034}
 4035
 4036#[derive(Clone, Debug, PartialEq, Eq)]
 4037pub enum SymbolLocation {
 4038    InProject(ProjectPath),
 4039    OutsideProject {
 4040        abs_path: Arc<Path>,
 4041        signature: [u8; 32],
 4042    },
 4043}
 4044
 4045impl SymbolLocation {
 4046    fn file_name(&self) -> Option<&str> {
 4047        match self {
 4048            Self::InProject(path) => path.path.file_name(),
 4049            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4050        }
 4051    }
 4052}
 4053
 4054impl LspStore {
 4055    pub fn init(client: &AnyProtoClient) {
 4056        client.add_entity_request_handler(Self::handle_lsp_query);
 4057        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4058        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4059        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4060        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4061        client.add_entity_message_handler(Self::handle_start_language_server);
 4062        client.add_entity_message_handler(Self::handle_update_language_server);
 4063        client.add_entity_message_handler(Self::handle_language_server_log);
 4064        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4065        client.add_entity_request_handler(Self::handle_format_buffers);
 4066        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4067        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4068        client.add_entity_request_handler(Self::handle_apply_code_action);
 4069        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4070        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4071        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4072        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4073        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4074        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4075        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4076        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4077        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4078        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4079        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4080        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4081        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4082        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4083        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4084        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4085        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4086        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4087
 4088        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4089        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4090        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4091        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4092        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4093        client.add_entity_request_handler(
 4094            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4095        );
 4096        client.add_entity_request_handler(
 4097            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4098        );
 4099        client.add_entity_request_handler(
 4100            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4101        );
 4102    }
 4103
 4104    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4105        match &self.mode {
 4106            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4107            _ => None,
 4108        }
 4109    }
 4110
 4111    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4112        match &self.mode {
 4113            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4114            _ => None,
 4115        }
 4116    }
 4117
 4118    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4119        match &mut self.mode {
 4120            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4121            _ => None,
 4122        }
 4123    }
 4124
 4125    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4126        match &self.mode {
 4127            LspStoreMode::Remote(RemoteLspStore {
 4128                upstream_client: Some(upstream_client),
 4129                upstream_project_id,
 4130                ..
 4131            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4132
 4133            LspStoreMode::Remote(RemoteLspStore {
 4134                upstream_client: None,
 4135                ..
 4136            }) => None,
 4137            LspStoreMode::Local(_) => None,
 4138        }
 4139    }
 4140
 4141    pub fn new_local(
 4142        buffer_store: Entity<BufferStore>,
 4143        worktree_store: Entity<WorktreeStore>,
 4144        prettier_store: Entity<PrettierStore>,
 4145        toolchain_store: Entity<LocalToolchainStore>,
 4146        environment: Entity<ProjectEnvironment>,
 4147        manifest_tree: Entity<ManifestTree>,
 4148        languages: Arc<LanguageRegistry>,
 4149        http_client: Arc<dyn HttpClient>,
 4150        fs: Arc<dyn Fs>,
 4151        cx: &mut Context<Self>,
 4152    ) -> Self {
 4153        let yarn = YarnPathStore::new(fs.clone(), cx);
 4154        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4155            .detach();
 4156        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4157            .detach();
 4158        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4159            .detach();
 4160        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4161            .detach();
 4162        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4163            .detach();
 4164        subscribe_to_binary_statuses(&languages, cx).detach();
 4165
 4166        let _maintain_workspace_config = {
 4167            let (sender, receiver) = watch::channel();
 4168            (Self::maintain_workspace_config(receiver, cx), sender)
 4169        };
 4170
 4171        Self {
 4172            mode: LspStoreMode::Local(LocalLspStore {
 4173                weak: cx.weak_entity(),
 4174                worktree_store: worktree_store.clone(),
 4175
 4176                supplementary_language_servers: Default::default(),
 4177                languages: languages.clone(),
 4178                language_server_ids: Default::default(),
 4179                language_servers: Default::default(),
 4180                last_workspace_edits_by_language_server: Default::default(),
 4181                language_server_watched_paths: Default::default(),
 4182                language_server_paths_watched_for_rename: Default::default(),
 4183                language_server_dynamic_registrations: Default::default(),
 4184                buffers_being_formatted: Default::default(),
 4185                buffers_to_refresh_hash_set: HashSet::default(),
 4186                buffers_to_refresh_queue: VecDeque::new(),
 4187                _background_diagnostics_worker: Task::ready(()).shared(),
 4188                buffer_snapshots: Default::default(),
 4189                prettier_store,
 4190                environment,
 4191                http_client,
 4192                fs,
 4193                yarn,
 4194                next_diagnostic_group_id: Default::default(),
 4195                diagnostics: Default::default(),
 4196                _subscription: cx.on_app_quit(|this, _| {
 4197                    this.as_local_mut()
 4198                        .unwrap()
 4199                        .shutdown_language_servers_on_quit()
 4200                }),
 4201                lsp_tree: LanguageServerTree::new(
 4202                    manifest_tree,
 4203                    languages.clone(),
 4204                    toolchain_store.clone(),
 4205                ),
 4206                toolchain_store,
 4207                registered_buffers: HashMap::default(),
 4208                buffers_opened_in_servers: HashMap::default(),
 4209                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4210                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4211                restricted_worktrees_tasks: HashMap::default(),
 4212                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4213                    .manifest_file_names(),
 4214            }),
 4215            last_formatting_failure: None,
 4216            downstream_client: None,
 4217            buffer_store,
 4218            worktree_store,
 4219            languages: languages.clone(),
 4220            language_server_statuses: Default::default(),
 4221            nonce: StdRng::from_os_rng().random(),
 4222            diagnostic_summaries: HashMap::default(),
 4223            lsp_server_capabilities: HashMap::default(),
 4224            semantic_token_config: SemanticTokenConfig::new(cx),
 4225            lsp_data: HashMap::default(),
 4226            next_hint_id: Arc::default(),
 4227            active_entry: None,
 4228            _maintain_workspace_config,
 4229            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4230        }
 4231    }
 4232
 4233    fn send_lsp_proto_request<R: LspCommand>(
 4234        &self,
 4235        buffer: Entity<Buffer>,
 4236        client: AnyProtoClient,
 4237        upstream_project_id: u64,
 4238        request: R,
 4239        cx: &mut Context<LspStore>,
 4240    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4241        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4242            return Task::ready(Ok(R::Response::default()));
 4243        }
 4244        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4245        cx.spawn(async move |this, cx| {
 4246            let response = client.request(message).await?;
 4247            let this = this.upgrade().context("project dropped")?;
 4248            request
 4249                .response_from_proto(response, this, buffer, cx.clone())
 4250                .await
 4251        })
 4252    }
 4253
 4254    pub(super) fn new_remote(
 4255        buffer_store: Entity<BufferStore>,
 4256        worktree_store: Entity<WorktreeStore>,
 4257        languages: Arc<LanguageRegistry>,
 4258        upstream_client: AnyProtoClient,
 4259        project_id: u64,
 4260        cx: &mut Context<Self>,
 4261    ) -> Self {
 4262        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4263            .detach();
 4264        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4265            .detach();
 4266        subscribe_to_binary_statuses(&languages, cx).detach();
 4267        let _maintain_workspace_config = {
 4268            let (sender, receiver) = watch::channel();
 4269            (Self::maintain_workspace_config(receiver, cx), sender)
 4270        };
 4271        Self {
 4272            mode: LspStoreMode::Remote(RemoteLspStore {
 4273                upstream_client: Some(upstream_client),
 4274                upstream_project_id: project_id,
 4275            }),
 4276            downstream_client: None,
 4277            last_formatting_failure: None,
 4278            buffer_store,
 4279            worktree_store,
 4280            languages: languages.clone(),
 4281            language_server_statuses: Default::default(),
 4282            nonce: StdRng::from_os_rng().random(),
 4283            diagnostic_summaries: HashMap::default(),
 4284            lsp_server_capabilities: HashMap::default(),
 4285            semantic_token_config: SemanticTokenConfig::new(cx),
 4286            next_hint_id: Arc::default(),
 4287            lsp_data: HashMap::default(),
 4288            active_entry: None,
 4289
 4290            _maintain_workspace_config,
 4291            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4292        }
 4293    }
 4294
 4295    fn on_buffer_store_event(
 4296        &mut self,
 4297        _: Entity<BufferStore>,
 4298        event: &BufferStoreEvent,
 4299        cx: &mut Context<Self>,
 4300    ) {
 4301        match event {
 4302            BufferStoreEvent::BufferAdded(buffer) => {
 4303                self.on_buffer_added(buffer, cx).log_err();
 4304            }
 4305            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4306                let buffer_id = buffer.read(cx).remote_id();
 4307                if let Some(local) = self.as_local_mut()
 4308                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4309                {
 4310                    local.reset_buffer(buffer, old_file, cx);
 4311
 4312                    if local.registered_buffers.contains_key(&buffer_id) {
 4313                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4314                    }
 4315                }
 4316
 4317                self.detect_language_for_buffer(buffer, cx);
 4318                if let Some(local) = self.as_local_mut() {
 4319                    local.initialize_buffer(buffer, cx);
 4320                    if local.registered_buffers.contains_key(&buffer_id) {
 4321                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4322                    }
 4323                }
 4324            }
 4325            _ => {}
 4326        }
 4327    }
 4328
 4329    fn on_worktree_store_event(
 4330        &mut self,
 4331        _: Entity<WorktreeStore>,
 4332        event: &WorktreeStoreEvent,
 4333        cx: &mut Context<Self>,
 4334    ) {
 4335        match event {
 4336            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4337                if !worktree.read(cx).is_local() {
 4338                    return;
 4339                }
 4340                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4341                    worktree::Event::UpdatedEntries(changes) => {
 4342                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4343                    }
 4344                    worktree::Event::UpdatedGitRepositories(_)
 4345                    | worktree::Event::DeletedEntry(_) => {}
 4346                })
 4347                .detach()
 4348            }
 4349            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4350            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4351                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4352            }
 4353            WorktreeStoreEvent::WorktreeReleased(..)
 4354            | WorktreeStoreEvent::WorktreeOrderChanged
 4355            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4356            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4357            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4358        }
 4359    }
 4360
 4361    fn on_prettier_store_event(
 4362        &mut self,
 4363        _: Entity<PrettierStore>,
 4364        event: &PrettierStoreEvent,
 4365        cx: &mut Context<Self>,
 4366    ) {
 4367        match event {
 4368            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4369                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4370            }
 4371            PrettierStoreEvent::LanguageServerAdded {
 4372                new_server_id,
 4373                name,
 4374                prettier_server,
 4375            } => {
 4376                self.register_supplementary_language_server(
 4377                    *new_server_id,
 4378                    name.clone(),
 4379                    prettier_server.clone(),
 4380                    cx,
 4381                );
 4382            }
 4383        }
 4384    }
 4385
 4386    fn on_toolchain_store_event(
 4387        &mut self,
 4388        _: Entity<LocalToolchainStore>,
 4389        event: &ToolchainStoreEvent,
 4390        _: &mut Context<Self>,
 4391    ) {
 4392        if let ToolchainStoreEvent::ToolchainActivated = event {
 4393            self.request_workspace_config_refresh()
 4394        }
 4395    }
 4396
 4397    fn request_workspace_config_refresh(&mut self) {
 4398        *self._maintain_workspace_config.1.borrow_mut() = ();
 4399    }
 4400
 4401    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4402        self.as_local().map(|local| local.prettier_store.clone())
 4403    }
 4404
 4405    fn on_buffer_event(
 4406        &mut self,
 4407        buffer: Entity<Buffer>,
 4408        event: &language::BufferEvent,
 4409        cx: &mut Context<Self>,
 4410    ) {
 4411        match event {
 4412            language::BufferEvent::Edited => {
 4413                self.on_buffer_edited(buffer, cx);
 4414            }
 4415
 4416            language::BufferEvent::Saved => {
 4417                self.on_buffer_saved(buffer, cx);
 4418            }
 4419
 4420            _ => {}
 4421        }
 4422    }
 4423
 4424    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4425        buffer
 4426            .read(cx)
 4427            .set_language_registry(self.languages.clone());
 4428
 4429        cx.subscribe(buffer, |this, buffer, event, cx| {
 4430            this.on_buffer_event(buffer, event, cx);
 4431        })
 4432        .detach();
 4433
 4434        self.detect_language_for_buffer(buffer, cx);
 4435        if let Some(local) = self.as_local_mut() {
 4436            local.initialize_buffer(buffer, cx);
 4437        }
 4438
 4439        Ok(())
 4440    }
 4441
 4442    pub fn refresh_background_diagnostics_for_buffers(
 4443        &mut self,
 4444        buffers: HashSet<BufferId>,
 4445        cx: &mut Context<Self>,
 4446    ) -> Shared<Task<()>> {
 4447        let Some(local) = self.as_local_mut() else {
 4448            return Task::ready(()).shared();
 4449        };
 4450        for buffer in buffers {
 4451            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4452                local.buffers_to_refresh_queue.push_back(buffer);
 4453                if local.buffers_to_refresh_queue.len() == 1 {
 4454                    local._background_diagnostics_worker =
 4455                        Self::background_diagnostics_worker(cx).shared();
 4456                }
 4457            }
 4458        }
 4459
 4460        local._background_diagnostics_worker.clone()
 4461    }
 4462
 4463    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4464        let buffer_store = self.buffer_store.clone();
 4465        let local = self.as_local_mut()?;
 4466        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4467            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4468            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4469                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4470            }
 4471        }
 4472        None
 4473    }
 4474
 4475    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4476        cx.spawn(async move |this, cx| {
 4477            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4478                task.await.log_err();
 4479            }
 4480        })
 4481    }
 4482
 4483    pub(crate) fn register_buffer_with_language_servers(
 4484        &mut self,
 4485        buffer: &Entity<Buffer>,
 4486        only_register_servers: HashSet<LanguageServerSelector>,
 4487        ignore_refcounts: bool,
 4488        cx: &mut Context<Self>,
 4489    ) -> OpenLspBufferHandle {
 4490        let buffer_id = buffer.read(cx).remote_id();
 4491        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4492        if let Some(local) = self.as_local_mut() {
 4493            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4494            if !ignore_refcounts {
 4495                *refcount += 1;
 4496            }
 4497
 4498            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4499            // 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
 4500            // 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
 4501            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4502            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4503                return handle;
 4504            };
 4505            if !file.is_local() {
 4506                return handle;
 4507            }
 4508
 4509            if ignore_refcounts || *refcount == 1 {
 4510                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4511            }
 4512            if !ignore_refcounts {
 4513                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4514                    let refcount = {
 4515                        let local = lsp_store.as_local_mut().unwrap();
 4516                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4517                            debug_panic!("bad refcounting");
 4518                            return;
 4519                        };
 4520
 4521                        *refcount -= 1;
 4522                        *refcount
 4523                    };
 4524                    if refcount == 0 {
 4525                        lsp_store.lsp_data.remove(&buffer_id);
 4526                        let local = lsp_store.as_local_mut().unwrap();
 4527                        local.registered_buffers.remove(&buffer_id);
 4528
 4529                        local.buffers_opened_in_servers.remove(&buffer_id);
 4530                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4531                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4532
 4533                            let buffer_abs_path = file.abs_path(cx);
 4534                            for (_, buffer_pull_diagnostics_result_ids) in
 4535                                &mut local.buffer_pull_diagnostics_result_ids
 4536                            {
 4537                                buffer_pull_diagnostics_result_ids.retain(
 4538                                    |_, buffer_result_ids| {
 4539                                        buffer_result_ids.remove(&buffer_abs_path);
 4540                                        !buffer_result_ids.is_empty()
 4541                                    },
 4542                                );
 4543                            }
 4544
 4545                            let diagnostic_updates = local
 4546                                .language_servers
 4547                                .keys()
 4548                                .cloned()
 4549                                .map(|server_id| DocumentDiagnosticsUpdate {
 4550                                    diagnostics: DocumentDiagnostics {
 4551                                        document_abs_path: buffer_abs_path.clone(),
 4552                                        version: None,
 4553                                        diagnostics: Vec::new(),
 4554                                    },
 4555                                    result_id: None,
 4556                                    registration_id: None,
 4557                                    server_id,
 4558                                    disk_based_sources: Cow::Borrowed(&[]),
 4559                                })
 4560                                .collect::<Vec<_>>();
 4561
 4562                            lsp_store
 4563                                .merge_diagnostic_entries(
 4564                                    diagnostic_updates,
 4565                                    |_, diagnostic, _| {
 4566                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4567                                    },
 4568                                    cx,
 4569                                )
 4570                                .context("Clearing diagnostics for the closed buffer")
 4571                                .log_err();
 4572                        }
 4573                    }
 4574                })
 4575                .detach();
 4576            }
 4577        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4578            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4579            cx.background_spawn(async move {
 4580                upstream_client
 4581                    .request(proto::RegisterBufferWithLanguageServers {
 4582                        project_id: upstream_project_id,
 4583                        buffer_id,
 4584                        only_servers: only_register_servers
 4585                            .into_iter()
 4586                            .map(|selector| {
 4587                                let selector = match selector {
 4588                                    LanguageServerSelector::Id(language_server_id) => {
 4589                                        proto::language_server_selector::Selector::ServerId(
 4590                                            language_server_id.to_proto(),
 4591                                        )
 4592                                    }
 4593                                    LanguageServerSelector::Name(language_server_name) => {
 4594                                        proto::language_server_selector::Selector::Name(
 4595                                            language_server_name.to_string(),
 4596                                        )
 4597                                    }
 4598                                };
 4599                                proto::LanguageServerSelector {
 4600                                    selector: Some(selector),
 4601                                }
 4602                            })
 4603                            .collect(),
 4604                    })
 4605                    .await
 4606            })
 4607            .detach();
 4608        } else {
 4609            // Our remote connection got closed
 4610        }
 4611        handle
 4612    }
 4613
 4614    fn maintain_buffer_languages(
 4615        languages: Arc<LanguageRegistry>,
 4616        cx: &mut Context<Self>,
 4617    ) -> Task<()> {
 4618        let mut subscription = languages.subscribe();
 4619        let mut prev_reload_count = languages.reload_count();
 4620        cx.spawn(async move |this, cx| {
 4621            while let Some(()) = subscription.next().await {
 4622                if let Some(this) = this.upgrade() {
 4623                    // If the language registry has been reloaded, then remove and
 4624                    // re-assign the languages on all open buffers.
 4625                    let reload_count = languages.reload_count();
 4626                    if reload_count > prev_reload_count {
 4627                        prev_reload_count = reload_count;
 4628                        this.update(cx, |this, cx| {
 4629                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4630                                for buffer in buffer_store.buffers() {
 4631                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4632                                    {
 4633                                        buffer.update(cx, |buffer, cx| {
 4634                                            buffer.set_language_async(None, cx)
 4635                                        });
 4636                                        if let Some(local) = this.as_local_mut() {
 4637                                            local.reset_buffer(&buffer, &f, cx);
 4638
 4639                                            if local
 4640                                                .registered_buffers
 4641                                                .contains_key(&buffer.read(cx).remote_id())
 4642                                                && let Some(file_url) =
 4643                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4644                                            {
 4645                                                local.unregister_buffer_from_language_servers(
 4646                                                    &buffer, &file_url, cx,
 4647                                                );
 4648                                            }
 4649                                        }
 4650                                    }
 4651                                }
 4652                            });
 4653                        });
 4654                    }
 4655
 4656                    this.update(cx, |this, cx| {
 4657                        let mut plain_text_buffers = Vec::new();
 4658                        let mut buffers_with_unknown_injections = Vec::new();
 4659                        for handle in this.buffer_store.read(cx).buffers() {
 4660                            let buffer = handle.read(cx);
 4661                            if buffer.language().is_none()
 4662                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4663                            {
 4664                                plain_text_buffers.push(handle);
 4665                            } else if buffer.contains_unknown_injections() {
 4666                                buffers_with_unknown_injections.push(handle);
 4667                            }
 4668                        }
 4669
 4670                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4671                        // and reused later in the invisible worktrees.
 4672                        plain_text_buffers.sort_by_key(|buffer| {
 4673                            Reverse(
 4674                                File::from_dyn(buffer.read(cx).file())
 4675                                    .map(|file| file.worktree.read(cx).is_visible()),
 4676                            )
 4677                        });
 4678
 4679                        for buffer in plain_text_buffers {
 4680                            this.detect_language_for_buffer(&buffer, cx);
 4681                            if let Some(local) = this.as_local_mut() {
 4682                                local.initialize_buffer(&buffer, cx);
 4683                                if local
 4684                                    .registered_buffers
 4685                                    .contains_key(&buffer.read(cx).remote_id())
 4686                                {
 4687                                    local.register_buffer_with_language_servers(
 4688                                        &buffer,
 4689                                        HashSet::default(),
 4690                                        cx,
 4691                                    );
 4692                                }
 4693                            }
 4694                        }
 4695
 4696                        for buffer in buffers_with_unknown_injections {
 4697                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4698                        }
 4699                    });
 4700                }
 4701            }
 4702        })
 4703    }
 4704
 4705    fn detect_language_for_buffer(
 4706        &mut self,
 4707        buffer_handle: &Entity<Buffer>,
 4708        cx: &mut Context<Self>,
 4709    ) -> Option<language::AvailableLanguage> {
 4710        // If the buffer has a language, set it and start the language server if we haven't already.
 4711        let buffer = buffer_handle.read(cx);
 4712        let file = buffer.file()?;
 4713
 4714        let content = buffer.as_rope();
 4715        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4716        if let Some(available_language) = &available_language {
 4717            if let Some(Ok(Ok(new_language))) = self
 4718                .languages
 4719                .load_language(available_language)
 4720                .now_or_never()
 4721            {
 4722                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4723            }
 4724        } else {
 4725            cx.emit(LspStoreEvent::LanguageDetected {
 4726                buffer: buffer_handle.clone(),
 4727                new_language: None,
 4728            });
 4729        }
 4730
 4731        available_language
 4732    }
 4733
 4734    pub(crate) fn set_language_for_buffer(
 4735        &mut self,
 4736        buffer_entity: &Entity<Buffer>,
 4737        new_language: Arc<Language>,
 4738        cx: &mut Context<Self>,
 4739    ) {
 4740        let buffer = buffer_entity.read(cx);
 4741        let buffer_file = buffer.file().cloned();
 4742        let buffer_id = buffer.remote_id();
 4743        if let Some(local_store) = self.as_local_mut()
 4744            && local_store.registered_buffers.contains_key(&buffer_id)
 4745            && let Some(abs_path) =
 4746                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4747            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4748        {
 4749            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4750        }
 4751        buffer_entity.update(cx, |buffer, cx| {
 4752            if buffer
 4753                .language()
 4754                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4755            {
 4756                buffer.set_language_async(Some(new_language.clone()), cx);
 4757            }
 4758        });
 4759
 4760        let settings =
 4761            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4762        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4763
 4764        let worktree_id = if let Some(file) = buffer_file {
 4765            let worktree = file.worktree.clone();
 4766
 4767            if let Some(local) = self.as_local_mut()
 4768                && local.registered_buffers.contains_key(&buffer_id)
 4769            {
 4770                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4771            }
 4772            Some(worktree.read(cx).id())
 4773        } else {
 4774            None
 4775        };
 4776
 4777        if settings.prettier.allowed
 4778            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4779        {
 4780            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4781            if let Some(prettier_store) = prettier_store {
 4782                prettier_store.update(cx, |prettier_store, cx| {
 4783                    prettier_store.install_default_prettier(
 4784                        worktree_id,
 4785                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4786                        cx,
 4787                    )
 4788                })
 4789            }
 4790        }
 4791
 4792        cx.emit(LspStoreEvent::LanguageDetected {
 4793            buffer: buffer_entity.clone(),
 4794            new_language: Some(new_language),
 4795        })
 4796    }
 4797
 4798    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4799        self.buffer_store.clone()
 4800    }
 4801
 4802    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4803        self.active_entry = active_entry;
 4804    }
 4805
 4806    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4807        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4808            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4809        {
 4810            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4811                summaries
 4812                    .iter()
 4813                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4814            });
 4815            if let Some(summary) = summaries.next() {
 4816                client
 4817                    .send(proto::UpdateDiagnosticSummary {
 4818                        project_id: downstream_project_id,
 4819                        worktree_id: worktree.id().to_proto(),
 4820                        summary: Some(summary),
 4821                        more_summaries: summaries.collect(),
 4822                    })
 4823                    .log_err();
 4824            }
 4825        }
 4826    }
 4827
 4828    fn is_capable_for_proto_request<R>(
 4829        &self,
 4830        buffer: &Entity<Buffer>,
 4831        request: &R,
 4832        cx: &App,
 4833    ) -> bool
 4834    where
 4835        R: LspCommand,
 4836    {
 4837        self.check_if_capable_for_proto_request(
 4838            buffer,
 4839            |capabilities| {
 4840                request.check_capabilities(AdapterServerCapabilities {
 4841                    server_capabilities: capabilities.clone(),
 4842                    code_action_kinds: None,
 4843                })
 4844            },
 4845            cx,
 4846        )
 4847    }
 4848
 4849    fn check_if_capable_for_proto_request<F>(
 4850        &self,
 4851        buffer: &Entity<Buffer>,
 4852        check: F,
 4853        cx: &App,
 4854    ) -> bool
 4855    where
 4856        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4857    {
 4858        let Some(language) = buffer.read(cx).language().cloned() else {
 4859            return false;
 4860        };
 4861        let registered_language_servers = self
 4862            .languages
 4863            .lsp_adapters(&language.name())
 4864            .into_iter()
 4865            .map(|lsp_adapter| lsp_adapter.name())
 4866            .collect::<HashSet<_>>();
 4867        self.language_server_statuses
 4868            .iter()
 4869            .filter_map(|(server_id, server_status)| {
 4870                // Include servers that are either registered for this language OR
 4871                // available to be loaded (for SSH remote mode where adapters like
 4872                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4873                // but only loaded on the server side)
 4874                let is_relevant = registered_language_servers.contains(&server_status.name)
 4875                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4876                is_relevant.then_some(server_id)
 4877            })
 4878            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4879            .any(check)
 4880    }
 4881
 4882    fn all_capable_for_proto_request<F>(
 4883        &self,
 4884        buffer: &Entity<Buffer>,
 4885        mut check: F,
 4886        cx: &App,
 4887    ) -> Vec<lsp::LanguageServerId>
 4888    where
 4889        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4890    {
 4891        let Some(language) = buffer.read(cx).language().cloned() else {
 4892            return Vec::default();
 4893        };
 4894        let registered_language_servers = self
 4895            .languages
 4896            .lsp_adapters(&language.name())
 4897            .into_iter()
 4898            .map(|lsp_adapter| lsp_adapter.name())
 4899            .collect::<HashSet<_>>();
 4900        self.language_server_statuses
 4901            .iter()
 4902            .filter_map(|(server_id, server_status)| {
 4903                // Include servers that are either registered for this language OR
 4904                // available to be loaded (for SSH remote mode where adapters like
 4905                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4906                // but only loaded on the server side)
 4907                let is_relevant = registered_language_servers.contains(&server_status.name)
 4908                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4909                is_relevant.then_some((server_id, &server_status.name))
 4910            })
 4911            .filter_map(|(server_id, server_name)| {
 4912                self.lsp_server_capabilities
 4913                    .get(server_id)
 4914                    .map(|c| (server_id, server_name, c))
 4915            })
 4916            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4917            .map(|(server_id, _, _)| *server_id)
 4918            .collect()
 4919    }
 4920
 4921    pub fn request_lsp<R>(
 4922        &mut self,
 4923        buffer: Entity<Buffer>,
 4924        server: LanguageServerToQuery,
 4925        request: R,
 4926        cx: &mut Context<Self>,
 4927    ) -> Task<Result<R::Response>>
 4928    where
 4929        R: LspCommand,
 4930        <R::LspRequest as lsp::request::Request>::Result: Send,
 4931        <R::LspRequest as lsp::request::Request>::Params: Send,
 4932    {
 4933        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4934            return self.send_lsp_proto_request(
 4935                buffer,
 4936                upstream_client,
 4937                upstream_project_id,
 4938                request,
 4939                cx,
 4940            );
 4941        }
 4942
 4943        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4944            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4945                local
 4946                    .language_servers_for_buffer(buffer, cx)
 4947                    .find(|(_, server)| {
 4948                        request.check_capabilities(server.adapter_server_capabilities())
 4949                    })
 4950                    .map(|(_, server)| server.clone())
 4951            }),
 4952            LanguageServerToQuery::Other(id) => self
 4953                .language_server_for_local_buffer(buffer, id, cx)
 4954                .and_then(|(_, server)| {
 4955                    request
 4956                        .check_capabilities(server.adapter_server_capabilities())
 4957                        .then(|| Arc::clone(server))
 4958                }),
 4959        }) else {
 4960            return Task::ready(Ok(Default::default()));
 4961        };
 4962
 4963        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4964
 4965        let Some(file) = file else {
 4966            return Task::ready(Ok(Default::default()));
 4967        };
 4968
 4969        let lsp_params = match request.to_lsp_params_or_response(
 4970            &file.abs_path(cx),
 4971            buffer.read(cx),
 4972            &language_server,
 4973            cx,
 4974        ) {
 4975            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4976            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4977            Err(err) => {
 4978                let message = format!(
 4979                    "{} via {} failed: {}",
 4980                    request.display_name(),
 4981                    language_server.name(),
 4982                    err
 4983                );
 4984                // rust-analyzer likes to error with this when its still loading up
 4985                if !message.ends_with("content modified") {
 4986                    log::warn!("{message}");
 4987                }
 4988                return Task::ready(Err(anyhow!(message)));
 4989            }
 4990        };
 4991
 4992        let status = request.status();
 4993        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4994            return Task::ready(Ok(Default::default()));
 4995        }
 4996
 4997        let request_timeout = ProjectSettings::get_global(cx)
 4998            .global_lsp_settings
 4999            .get_request_timeout();
 5000
 5001        cx.spawn(async move |this, cx| {
 5002            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5003
 5004            let id = lsp_request.id();
 5005            let _cleanup = if status.is_some() {
 5006                cx.update(|cx| {
 5007                    this.update(cx, |this, cx| {
 5008                        this.on_lsp_work_start(
 5009                            language_server.server_id(),
 5010                            ProgressToken::Number(id),
 5011                            LanguageServerProgress {
 5012                                is_disk_based_diagnostics_progress: false,
 5013                                is_cancellable: false,
 5014                                title: None,
 5015                                message: status.clone(),
 5016                                percentage: None,
 5017                                last_update_at: cx.background_executor().now(),
 5018                            },
 5019                            cx,
 5020                        );
 5021                    })
 5022                })
 5023                .log_err();
 5024
 5025                Some(defer(|| {
 5026                    cx.update(|cx| {
 5027                        this.update(cx, |this, cx| {
 5028                            this.on_lsp_work_end(
 5029                                language_server.server_id(),
 5030                                ProgressToken::Number(id),
 5031                                cx,
 5032                            );
 5033                        })
 5034                    })
 5035                    .log_err();
 5036                }))
 5037            } else {
 5038                None
 5039            };
 5040
 5041            let result = lsp_request.await.into_response();
 5042
 5043            let response = result.map_err(|err| {
 5044                let message = format!(
 5045                    "{} via {} failed: {}",
 5046                    request.display_name(),
 5047                    language_server.name(),
 5048                    err
 5049                );
 5050                // rust-analyzer likes to error with this when its still loading up
 5051                if !message.ends_with("content modified") {
 5052                    log::warn!("{message}");
 5053                }
 5054                anyhow::anyhow!(message)
 5055            })?;
 5056
 5057            request
 5058                .response_from_lsp(
 5059                    response,
 5060                    this.upgrade().context("no app context")?,
 5061                    buffer,
 5062                    language_server.server_id(),
 5063                    cx.clone(),
 5064                )
 5065                .await
 5066        })
 5067    }
 5068
 5069    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5070        let mut language_formatters_to_check = Vec::new();
 5071        for buffer in self.buffer_store.read(cx).buffers() {
 5072            let buffer = buffer.read(cx);
 5073            let buffer_file = File::from_dyn(buffer.file());
 5074            let buffer_language = buffer.language();
 5075            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5076            if buffer_language.is_some() {
 5077                language_formatters_to_check.push((
 5078                    buffer_file.map(|f| f.worktree_id(cx)),
 5079                    settings.into_owned(),
 5080                ));
 5081            }
 5082        }
 5083
 5084        self.request_workspace_config_refresh();
 5085
 5086        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5087            prettier_store.update(cx, |prettier_store, cx| {
 5088                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5089            })
 5090        }
 5091
 5092        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5093            .global_lsp_settings
 5094            .semantic_token_rules
 5095            .clone();
 5096        self.semantic_token_config
 5097            .update_rules(new_semantic_token_rules);
 5098
 5099        let new_global_semantic_tokens_mode =
 5100            all_language_settings(None, cx).defaults.semantic_tokens;
 5101        if self
 5102            .semantic_token_config
 5103            .update_global_mode(new_global_semantic_tokens_mode)
 5104        {
 5105            self.restart_all_language_servers(cx);
 5106        }
 5107
 5108        cx.notify();
 5109    }
 5110
 5111    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5112        let buffer_store = self.buffer_store.clone();
 5113        let Some(local) = self.as_local_mut() else {
 5114            return;
 5115        };
 5116        let mut adapters = BTreeMap::default();
 5117        let get_adapter = {
 5118            let languages = local.languages.clone();
 5119            let environment = local.environment.clone();
 5120            let weak = local.weak.clone();
 5121            let worktree_store = local.worktree_store.clone();
 5122            let http_client = local.http_client.clone();
 5123            let fs = local.fs.clone();
 5124            move |worktree_id, cx: &mut App| {
 5125                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5126                Some(LocalLspAdapterDelegate::new(
 5127                    languages.clone(),
 5128                    &environment,
 5129                    weak.clone(),
 5130                    &worktree,
 5131                    http_client.clone(),
 5132                    fs.clone(),
 5133                    cx,
 5134                ))
 5135            }
 5136        };
 5137
 5138        let mut messages_to_report = Vec::new();
 5139        let (new_tree, to_stop) = {
 5140            let mut rebase = local.lsp_tree.rebase();
 5141            let buffers = buffer_store
 5142                .read(cx)
 5143                .buffers()
 5144                .filter_map(|buffer| {
 5145                    let raw_buffer = buffer.read(cx);
 5146                    if !local
 5147                        .registered_buffers
 5148                        .contains_key(&raw_buffer.remote_id())
 5149                    {
 5150                        return None;
 5151                    }
 5152                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5153                    let language = raw_buffer.language().cloned()?;
 5154                    Some((file, language, raw_buffer.remote_id()))
 5155                })
 5156                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5157            for (file, language, buffer_id) in buffers {
 5158                let worktree_id = file.worktree_id(cx);
 5159                let Some(worktree) = local
 5160                    .worktree_store
 5161                    .read(cx)
 5162                    .worktree_for_id(worktree_id, cx)
 5163                else {
 5164                    continue;
 5165                };
 5166
 5167                if let Some((_, apply)) = local.reuse_existing_language_server(
 5168                    rebase.server_tree(),
 5169                    &worktree,
 5170                    &language.name(),
 5171                    cx,
 5172                ) {
 5173                    (apply)(rebase.server_tree());
 5174                } else if let Some(lsp_delegate) = adapters
 5175                    .entry(worktree_id)
 5176                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5177                    .clone()
 5178                {
 5179                    let delegate =
 5180                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5181                    let path = file
 5182                        .path()
 5183                        .parent()
 5184                        .map(Arc::from)
 5185                        .unwrap_or_else(|| file.path().clone());
 5186                    let worktree_path = ProjectPath { worktree_id, path };
 5187                    let abs_path = file.abs_path(cx);
 5188                    let nodes = rebase
 5189                        .walk(
 5190                            worktree_path,
 5191                            language.name(),
 5192                            language.manifest(),
 5193                            delegate.clone(),
 5194                            cx,
 5195                        )
 5196                        .collect::<Vec<_>>();
 5197                    for node in nodes {
 5198                        let server_id = node.server_id_or_init(|disposition| {
 5199                            let path = &disposition.path;
 5200                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5201                            let key = LanguageServerSeed {
 5202                                worktree_id,
 5203                                name: disposition.server_name.clone(),
 5204                                settings: LanguageServerSeedSettings {
 5205                                    binary: disposition.settings.binary.clone(),
 5206                                    initialization_options: disposition
 5207                                        .settings
 5208                                        .initialization_options
 5209                                        .clone(),
 5210                                },
 5211                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5212                                    path.worktree_id,
 5213                                    &path.path,
 5214                                    language.name(),
 5215                                ),
 5216                            };
 5217                            local.language_server_ids.remove(&key);
 5218
 5219                            let server_id = local.get_or_insert_language_server(
 5220                                &worktree,
 5221                                lsp_delegate.clone(),
 5222                                disposition,
 5223                                &language.name(),
 5224                                cx,
 5225                            );
 5226                            if let Some(state) = local.language_servers.get(&server_id)
 5227                                && let Ok(uri) = uri
 5228                            {
 5229                                state.add_workspace_folder(uri);
 5230                            };
 5231                            server_id
 5232                        });
 5233
 5234                        if let Some(language_server_id) = server_id {
 5235                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5236                                language_server_id,
 5237                                name: node.name(),
 5238                                message:
 5239                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5240                                        proto::RegisteredForBuffer {
 5241                                            buffer_abs_path: abs_path
 5242                                                .to_string_lossy()
 5243                                                .into_owned(),
 5244                                            buffer_id: buffer_id.to_proto(),
 5245                                        },
 5246                                    ),
 5247                            });
 5248                        }
 5249                    }
 5250                } else {
 5251                    continue;
 5252                }
 5253            }
 5254            rebase.finish()
 5255        };
 5256        for message in messages_to_report {
 5257            cx.emit(message);
 5258        }
 5259        local.lsp_tree = new_tree;
 5260        for (id, _) in to_stop {
 5261            self.stop_local_language_server(id, cx).detach();
 5262        }
 5263    }
 5264
 5265    pub fn apply_code_action(
 5266        &self,
 5267        buffer_handle: Entity<Buffer>,
 5268        mut action: CodeAction,
 5269        push_to_history: bool,
 5270        cx: &mut Context<Self>,
 5271    ) -> Task<Result<ProjectTransaction>> {
 5272        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5273            let request = proto::ApplyCodeAction {
 5274                project_id,
 5275                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5276                action: Some(Self::serialize_code_action(&action)),
 5277            };
 5278            let buffer_store = self.buffer_store();
 5279            cx.spawn(async move |_, cx| {
 5280                let response = upstream_client
 5281                    .request(request)
 5282                    .await?
 5283                    .transaction
 5284                    .context("missing transaction")?;
 5285
 5286                buffer_store
 5287                    .update(cx, |buffer_store, cx| {
 5288                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5289                    })
 5290                    .await
 5291            })
 5292        } else if self.mode.is_local() {
 5293            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5294                let request_timeout = ProjectSettings::get_global(cx)
 5295                    .global_lsp_settings
 5296                    .get_request_timeout();
 5297                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5298                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5299            }) else {
 5300                return Task::ready(Ok(ProjectTransaction::default()));
 5301            };
 5302
 5303            cx.spawn(async move |this, cx| {
 5304                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5305                    .await
 5306                    .context("resolving a code action")?;
 5307                if let Some(edit) = action.lsp_action.edit()
 5308                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5309                        return LocalLspStore::deserialize_workspace_edit(
 5310                            this.upgrade().context("no app present")?,
 5311                            edit.clone(),
 5312                            push_to_history,
 5313
 5314                            lang_server.clone(),
 5315                            cx,
 5316                        )
 5317                        .await;
 5318                    }
 5319
 5320                let Some(command) = action.lsp_action.command() else {
 5321                    return Ok(ProjectTransaction::default())
 5322                };
 5323
 5324                let server_capabilities = lang_server.capabilities();
 5325                let available_commands = server_capabilities
 5326                    .execute_command_provider
 5327                    .as_ref()
 5328                    .map(|options| options.commands.as_slice())
 5329                    .unwrap_or_default();
 5330
 5331                if !available_commands.contains(&command.command) {
 5332                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5333                    return Ok(ProjectTransaction::default())
 5334                }
 5335
 5336                let request_timeout = cx.update(|app|
 5337                    ProjectSettings::get_global(app)
 5338                    .global_lsp_settings
 5339                    .get_request_timeout()
 5340                );
 5341
 5342                this.update(cx, |this, _| {
 5343                    this.as_local_mut()
 5344                        .unwrap()
 5345                        .last_workspace_edits_by_language_server
 5346                        .remove(&lang_server.server_id());
 5347                })?;
 5348
 5349                let _result = lang_server
 5350                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5351                        command: command.command.clone(),
 5352                        arguments: command.arguments.clone().unwrap_or_default(),
 5353                        ..lsp::ExecuteCommandParams::default()
 5354                    }, request_timeout)
 5355                    .await.into_response()
 5356                    .context("execute command")?;
 5357
 5358                return this.update(cx, |this, _| {
 5359                    this.as_local_mut()
 5360                        .unwrap()
 5361                        .last_workspace_edits_by_language_server
 5362                        .remove(&lang_server.server_id())
 5363                        .unwrap_or_default()
 5364                });
 5365            })
 5366        } else {
 5367            Task::ready(Err(anyhow!("no upstream client and not local")))
 5368        }
 5369    }
 5370
 5371    pub fn apply_code_action_kind(
 5372        &mut self,
 5373        buffers: HashSet<Entity<Buffer>>,
 5374        kind: CodeActionKind,
 5375        push_to_history: bool,
 5376        cx: &mut Context<Self>,
 5377    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5378        if self.as_local().is_some() {
 5379            cx.spawn(async move |lsp_store, cx| {
 5380                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5381                let result = LocalLspStore::execute_code_action_kind_locally(
 5382                    lsp_store.clone(),
 5383                    buffers,
 5384                    kind,
 5385                    push_to_history,
 5386                    cx,
 5387                )
 5388                .await;
 5389                lsp_store.update(cx, |lsp_store, _| {
 5390                    lsp_store.update_last_formatting_failure(&result);
 5391                })?;
 5392                result
 5393            })
 5394        } else if let Some((client, project_id)) = self.upstream_client() {
 5395            let buffer_store = self.buffer_store();
 5396            cx.spawn(async move |lsp_store, cx| {
 5397                let result = client
 5398                    .request(proto::ApplyCodeActionKind {
 5399                        project_id,
 5400                        kind: kind.as_str().to_owned(),
 5401                        buffer_ids: buffers
 5402                            .iter()
 5403                            .map(|buffer| {
 5404                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5405                            })
 5406                            .collect(),
 5407                    })
 5408                    .await
 5409                    .and_then(|result| result.transaction.context("missing transaction"));
 5410                lsp_store.update(cx, |lsp_store, _| {
 5411                    lsp_store.update_last_formatting_failure(&result);
 5412                })?;
 5413
 5414                let transaction_response = result?;
 5415                buffer_store
 5416                    .update(cx, |buffer_store, cx| {
 5417                        buffer_store.deserialize_project_transaction(
 5418                            transaction_response,
 5419                            push_to_history,
 5420                            cx,
 5421                        )
 5422                    })
 5423                    .await
 5424            })
 5425        } else {
 5426            Task::ready(Ok(ProjectTransaction::default()))
 5427        }
 5428    }
 5429
 5430    pub fn resolved_hint(
 5431        &mut self,
 5432        buffer_id: BufferId,
 5433        id: InlayId,
 5434        cx: &mut Context<Self>,
 5435    ) -> Option<ResolvedHint> {
 5436        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5437
 5438        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5439        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5440        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5441        let (server_id, resolve_data) = match &hint.resolve_state {
 5442            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5443            ResolveState::Resolving => {
 5444                return Some(ResolvedHint::Resolving(
 5445                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5446                ));
 5447            }
 5448            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5449        };
 5450
 5451        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5452        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5453        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5454            id,
 5455            cx.spawn(async move |lsp_store, cx| {
 5456                let resolved_hint = resolve_task.await;
 5457                lsp_store
 5458                    .update(cx, |lsp_store, _| {
 5459                        if let Some(old_inlay_hint) = lsp_store
 5460                            .lsp_data
 5461                            .get_mut(&buffer_id)
 5462                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5463                        {
 5464                            match resolved_hint {
 5465                                Ok(resolved_hint) => {
 5466                                    *old_inlay_hint = resolved_hint;
 5467                                }
 5468                                Err(e) => {
 5469                                    old_inlay_hint.resolve_state =
 5470                                        ResolveState::CanResolve(server_id, resolve_data);
 5471                                    log::error!("Inlay hint resolve failed: {e:#}");
 5472                                }
 5473                            }
 5474                        }
 5475                    })
 5476                    .ok();
 5477            })
 5478            .shared(),
 5479        );
 5480        debug_assert!(
 5481            previous_task.is_none(),
 5482            "Did not change hint's resolve state after spawning its resolve"
 5483        );
 5484        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5485        None
 5486    }
 5487
 5488    pub(crate) fn linked_edits(
 5489        &mut self,
 5490        buffer: &Entity<Buffer>,
 5491        position: Anchor,
 5492        cx: &mut Context<Self>,
 5493    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5494        let snapshot = buffer.read(cx).snapshot();
 5495        let scope = snapshot.language_scope_at(position);
 5496        let Some(server_id) = self
 5497            .as_local()
 5498            .and_then(|local| {
 5499                buffer.update(cx, |buffer, cx| {
 5500                    local
 5501                        .language_servers_for_buffer(buffer, cx)
 5502                        .filter(|(_, server)| {
 5503                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5504                        })
 5505                        .filter(|(adapter, _)| {
 5506                            scope
 5507                                .as_ref()
 5508                                .map(|scope| scope.language_allowed(&adapter.name))
 5509                                .unwrap_or(true)
 5510                        })
 5511                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5512                        .next()
 5513                })
 5514            })
 5515            .or_else(|| {
 5516                self.upstream_client()
 5517                    .is_some()
 5518                    .then_some(LanguageServerToQuery::FirstCapable)
 5519            })
 5520            .filter(|_| {
 5521                maybe!({
 5522                    let language = buffer.read(cx).language_at(position)?;
 5523                    Some(
 5524                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5525                            .linked_edits,
 5526                    )
 5527                }) == Some(true)
 5528            })
 5529        else {
 5530            return Task::ready(Ok(Vec::new()));
 5531        };
 5532
 5533        self.request_lsp(
 5534            buffer.clone(),
 5535            server_id,
 5536            LinkedEditingRange { position },
 5537            cx,
 5538        )
 5539    }
 5540
 5541    fn apply_on_type_formatting(
 5542        &mut self,
 5543        buffer: Entity<Buffer>,
 5544        position: Anchor,
 5545        trigger: String,
 5546        cx: &mut Context<Self>,
 5547    ) -> Task<Result<Option<Transaction>>> {
 5548        if let Some((client, project_id)) = self.upstream_client() {
 5549            if !self.check_if_capable_for_proto_request(
 5550                &buffer,
 5551                |capabilities| {
 5552                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5553                },
 5554                cx,
 5555            ) {
 5556                return Task::ready(Ok(None));
 5557            }
 5558            let request = proto::OnTypeFormatting {
 5559                project_id,
 5560                buffer_id: buffer.read(cx).remote_id().into(),
 5561                position: Some(serialize_anchor(&position)),
 5562                trigger,
 5563                version: serialize_version(&buffer.read(cx).version()),
 5564            };
 5565            cx.background_spawn(async move {
 5566                client
 5567                    .request(request)
 5568                    .await?
 5569                    .transaction
 5570                    .map(language::proto::deserialize_transaction)
 5571                    .transpose()
 5572            })
 5573        } else if let Some(local) = self.as_local_mut() {
 5574            let buffer_id = buffer.read(cx).remote_id();
 5575            local.buffers_being_formatted.insert(buffer_id);
 5576            cx.spawn(async move |this, cx| {
 5577                let _cleanup = defer({
 5578                    let this = this.clone();
 5579                    let mut cx = cx.clone();
 5580                    move || {
 5581                        this.update(&mut cx, |this, _| {
 5582                            if let Some(local) = this.as_local_mut() {
 5583                                local.buffers_being_formatted.remove(&buffer_id);
 5584                            }
 5585                        })
 5586                        .ok();
 5587                    }
 5588                });
 5589
 5590                buffer
 5591                    .update(cx, |buffer, _| {
 5592                        buffer.wait_for_edits(Some(position.timestamp))
 5593                    })
 5594                    .await?;
 5595                this.update(cx, |this, cx| {
 5596                    let position = position.to_point_utf16(buffer.read(cx));
 5597                    this.on_type_format(buffer, position, trigger, false, cx)
 5598                })?
 5599                .await
 5600            })
 5601        } else {
 5602            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5603        }
 5604    }
 5605
 5606    pub fn on_type_format<T: ToPointUtf16>(
 5607        &mut self,
 5608        buffer: Entity<Buffer>,
 5609        position: T,
 5610        trigger: String,
 5611        push_to_history: bool,
 5612        cx: &mut Context<Self>,
 5613    ) -> Task<Result<Option<Transaction>>> {
 5614        let position = position.to_point_utf16(buffer.read(cx));
 5615        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5616    }
 5617
 5618    fn on_type_format_impl(
 5619        &mut self,
 5620        buffer: Entity<Buffer>,
 5621        position: PointUtf16,
 5622        trigger: String,
 5623        push_to_history: bool,
 5624        cx: &mut Context<Self>,
 5625    ) -> Task<Result<Option<Transaction>>> {
 5626        let options = buffer.update(cx, |buffer, cx| {
 5627            lsp_command::lsp_formatting_options(
 5628                language_settings(
 5629                    buffer.language_at(position).map(|l| l.name()),
 5630                    buffer.file(),
 5631                    cx,
 5632                )
 5633                .as_ref(),
 5634            )
 5635        });
 5636
 5637        cx.spawn(async move |this, cx| {
 5638            if let Some(waiter) =
 5639                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5640            {
 5641                waiter.await?;
 5642            }
 5643            cx.update(|cx| {
 5644                this.update(cx, |this, cx| {
 5645                    this.request_lsp(
 5646                        buffer.clone(),
 5647                        LanguageServerToQuery::FirstCapable,
 5648                        OnTypeFormatting {
 5649                            position,
 5650                            trigger,
 5651                            options,
 5652                            push_to_history,
 5653                        },
 5654                        cx,
 5655                    )
 5656                })
 5657            })?
 5658            .await
 5659        })
 5660    }
 5661
 5662    pub fn definitions(
 5663        &mut self,
 5664        buffer: &Entity<Buffer>,
 5665        position: PointUtf16,
 5666        cx: &mut Context<Self>,
 5667    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5668        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5669            let request = GetDefinitions { position };
 5670            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5671                return Task::ready(Ok(None));
 5672            }
 5673
 5674            let request_timeout = ProjectSettings::get_global(cx)
 5675                .global_lsp_settings
 5676                .get_request_timeout();
 5677
 5678            let request_task = upstream_client.request_lsp(
 5679                project_id,
 5680                None,
 5681                request_timeout,
 5682                cx.background_executor().clone(),
 5683                request.to_proto(project_id, buffer.read(cx)),
 5684            );
 5685            let buffer = buffer.clone();
 5686            cx.spawn(async move |weak_lsp_store, cx| {
 5687                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5688                    return Ok(None);
 5689                };
 5690                let Some(responses) = request_task.await? else {
 5691                    return Ok(None);
 5692                };
 5693                let actions = join_all(responses.payload.into_iter().map(|response| {
 5694                    GetDefinitions { position }.response_from_proto(
 5695                        response.response,
 5696                        lsp_store.clone(),
 5697                        buffer.clone(),
 5698                        cx.clone(),
 5699                    )
 5700                }))
 5701                .await;
 5702
 5703                Ok(Some(
 5704                    actions
 5705                        .into_iter()
 5706                        .collect::<Result<Vec<Vec<_>>>>()?
 5707                        .into_iter()
 5708                        .flatten()
 5709                        .dedup()
 5710                        .collect(),
 5711                ))
 5712            })
 5713        } else {
 5714            let definitions_task = self.request_multiple_lsp_locally(
 5715                buffer,
 5716                Some(position),
 5717                GetDefinitions { position },
 5718                cx,
 5719            );
 5720            cx.background_spawn(async move {
 5721                Ok(Some(
 5722                    definitions_task
 5723                        .await
 5724                        .into_iter()
 5725                        .flat_map(|(_, definitions)| definitions)
 5726                        .dedup()
 5727                        .collect(),
 5728                ))
 5729            })
 5730        }
 5731    }
 5732
 5733    pub fn declarations(
 5734        &mut self,
 5735        buffer: &Entity<Buffer>,
 5736        position: PointUtf16,
 5737        cx: &mut Context<Self>,
 5738    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5739        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5740            let request = GetDeclarations { position };
 5741            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5742                return Task::ready(Ok(None));
 5743            }
 5744            let request_timeout = ProjectSettings::get_global(cx)
 5745                .global_lsp_settings
 5746                .get_request_timeout();
 5747            let request_task = upstream_client.request_lsp(
 5748                project_id,
 5749                None,
 5750                request_timeout,
 5751                cx.background_executor().clone(),
 5752                request.to_proto(project_id, buffer.read(cx)),
 5753            );
 5754            let buffer = buffer.clone();
 5755            cx.spawn(async move |weak_lsp_store, cx| {
 5756                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5757                    return Ok(None);
 5758                };
 5759                let Some(responses) = request_task.await? else {
 5760                    return Ok(None);
 5761                };
 5762                let actions = join_all(responses.payload.into_iter().map(|response| {
 5763                    GetDeclarations { position }.response_from_proto(
 5764                        response.response,
 5765                        lsp_store.clone(),
 5766                        buffer.clone(),
 5767                        cx.clone(),
 5768                    )
 5769                }))
 5770                .await;
 5771
 5772                Ok(Some(
 5773                    actions
 5774                        .into_iter()
 5775                        .collect::<Result<Vec<Vec<_>>>>()?
 5776                        .into_iter()
 5777                        .flatten()
 5778                        .dedup()
 5779                        .collect(),
 5780                ))
 5781            })
 5782        } else {
 5783            let declarations_task = self.request_multiple_lsp_locally(
 5784                buffer,
 5785                Some(position),
 5786                GetDeclarations { position },
 5787                cx,
 5788            );
 5789            cx.background_spawn(async move {
 5790                Ok(Some(
 5791                    declarations_task
 5792                        .await
 5793                        .into_iter()
 5794                        .flat_map(|(_, declarations)| declarations)
 5795                        .dedup()
 5796                        .collect(),
 5797                ))
 5798            })
 5799        }
 5800    }
 5801
 5802    pub fn type_definitions(
 5803        &mut self,
 5804        buffer: &Entity<Buffer>,
 5805        position: PointUtf16,
 5806        cx: &mut Context<Self>,
 5807    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5808        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5809            let request = GetTypeDefinitions { position };
 5810            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5811                return Task::ready(Ok(None));
 5812            }
 5813            let request_timeout = ProjectSettings::get_global(cx)
 5814                .global_lsp_settings
 5815                .get_request_timeout();
 5816            let request_task = upstream_client.request_lsp(
 5817                project_id,
 5818                None,
 5819                request_timeout,
 5820                cx.background_executor().clone(),
 5821                request.to_proto(project_id, buffer.read(cx)),
 5822            );
 5823            let buffer = buffer.clone();
 5824            cx.spawn(async move |weak_lsp_store, cx| {
 5825                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5826                    return Ok(None);
 5827                };
 5828                let Some(responses) = request_task.await? else {
 5829                    return Ok(None);
 5830                };
 5831                let actions = join_all(responses.payload.into_iter().map(|response| {
 5832                    GetTypeDefinitions { position }.response_from_proto(
 5833                        response.response,
 5834                        lsp_store.clone(),
 5835                        buffer.clone(),
 5836                        cx.clone(),
 5837                    )
 5838                }))
 5839                .await;
 5840
 5841                Ok(Some(
 5842                    actions
 5843                        .into_iter()
 5844                        .collect::<Result<Vec<Vec<_>>>>()?
 5845                        .into_iter()
 5846                        .flatten()
 5847                        .dedup()
 5848                        .collect(),
 5849                ))
 5850            })
 5851        } else {
 5852            let type_definitions_task = self.request_multiple_lsp_locally(
 5853                buffer,
 5854                Some(position),
 5855                GetTypeDefinitions { position },
 5856                cx,
 5857            );
 5858            cx.background_spawn(async move {
 5859                Ok(Some(
 5860                    type_definitions_task
 5861                        .await
 5862                        .into_iter()
 5863                        .flat_map(|(_, type_definitions)| type_definitions)
 5864                        .dedup()
 5865                        .collect(),
 5866                ))
 5867            })
 5868        }
 5869    }
 5870
 5871    pub fn implementations(
 5872        &mut self,
 5873        buffer: &Entity<Buffer>,
 5874        position: PointUtf16,
 5875        cx: &mut Context<Self>,
 5876    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5877        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5878            let request = GetImplementations { position };
 5879            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5880                return Task::ready(Ok(None));
 5881            }
 5882
 5883            let request_timeout = ProjectSettings::get_global(cx)
 5884                .global_lsp_settings
 5885                .get_request_timeout();
 5886            let request_task = upstream_client.request_lsp(
 5887                project_id,
 5888                None,
 5889                request_timeout,
 5890                cx.background_executor().clone(),
 5891                request.to_proto(project_id, buffer.read(cx)),
 5892            );
 5893            let buffer = buffer.clone();
 5894            cx.spawn(async move |weak_lsp_store, cx| {
 5895                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5896                    return Ok(None);
 5897                };
 5898                let Some(responses) = request_task.await? else {
 5899                    return Ok(None);
 5900                };
 5901                let actions = join_all(responses.payload.into_iter().map(|response| {
 5902                    GetImplementations { position }.response_from_proto(
 5903                        response.response,
 5904                        lsp_store.clone(),
 5905                        buffer.clone(),
 5906                        cx.clone(),
 5907                    )
 5908                }))
 5909                .await;
 5910
 5911                Ok(Some(
 5912                    actions
 5913                        .into_iter()
 5914                        .collect::<Result<Vec<Vec<_>>>>()?
 5915                        .into_iter()
 5916                        .flatten()
 5917                        .dedup()
 5918                        .collect(),
 5919                ))
 5920            })
 5921        } else {
 5922            let implementations_task = self.request_multiple_lsp_locally(
 5923                buffer,
 5924                Some(position),
 5925                GetImplementations { position },
 5926                cx,
 5927            );
 5928            cx.background_spawn(async move {
 5929                Ok(Some(
 5930                    implementations_task
 5931                        .await
 5932                        .into_iter()
 5933                        .flat_map(|(_, implementations)| implementations)
 5934                        .dedup()
 5935                        .collect(),
 5936                ))
 5937            })
 5938        }
 5939    }
 5940
 5941    pub fn references(
 5942        &mut self,
 5943        buffer: &Entity<Buffer>,
 5944        position: PointUtf16,
 5945        cx: &mut Context<Self>,
 5946    ) -> Task<Result<Option<Vec<Location>>>> {
 5947        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5948            let request = GetReferences { position };
 5949            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5950                return Task::ready(Ok(None));
 5951            }
 5952
 5953            let request_timeout = ProjectSettings::get_global(cx)
 5954                .global_lsp_settings
 5955                .get_request_timeout();
 5956            let request_task = upstream_client.request_lsp(
 5957                project_id,
 5958                None,
 5959                request_timeout,
 5960                cx.background_executor().clone(),
 5961                request.to_proto(project_id, buffer.read(cx)),
 5962            );
 5963            let buffer = buffer.clone();
 5964            cx.spawn(async move |weak_lsp_store, cx| {
 5965                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5966                    return Ok(None);
 5967                };
 5968                let Some(responses) = request_task.await? else {
 5969                    return Ok(None);
 5970                };
 5971
 5972                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5973                    GetReferences { position }.response_from_proto(
 5974                        lsp_response.response,
 5975                        lsp_store.clone(),
 5976                        buffer.clone(),
 5977                        cx.clone(),
 5978                    )
 5979                }))
 5980                .await
 5981                .into_iter()
 5982                .collect::<Result<Vec<Vec<_>>>>()?
 5983                .into_iter()
 5984                .flatten()
 5985                .dedup()
 5986                .collect();
 5987                Ok(Some(locations))
 5988            })
 5989        } else {
 5990            let references_task = self.request_multiple_lsp_locally(
 5991                buffer,
 5992                Some(position),
 5993                GetReferences { position },
 5994                cx,
 5995            );
 5996            cx.background_spawn(async move {
 5997                Ok(Some(
 5998                    references_task
 5999                        .await
 6000                        .into_iter()
 6001                        .flat_map(|(_, references)| references)
 6002                        .dedup()
 6003                        .collect(),
 6004                ))
 6005            })
 6006        }
 6007    }
 6008
 6009    pub fn code_actions(
 6010        &mut self,
 6011        buffer: &Entity<Buffer>,
 6012        range: Range<Anchor>,
 6013        kinds: Option<Vec<CodeActionKind>>,
 6014        cx: &mut Context<Self>,
 6015    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6016        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6017            let request = GetCodeActions {
 6018                range: range.clone(),
 6019                kinds: kinds.clone(),
 6020            };
 6021            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6022                return Task::ready(Ok(None));
 6023            }
 6024            let request_timeout = ProjectSettings::get_global(cx)
 6025                .global_lsp_settings
 6026                .get_request_timeout();
 6027            let request_task = upstream_client.request_lsp(
 6028                project_id,
 6029                None,
 6030                request_timeout,
 6031                cx.background_executor().clone(),
 6032                request.to_proto(project_id, buffer.read(cx)),
 6033            );
 6034            let buffer = buffer.clone();
 6035            cx.spawn(async move |weak_lsp_store, cx| {
 6036                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6037                    return Ok(None);
 6038                };
 6039                let Some(responses) = request_task.await? else {
 6040                    return Ok(None);
 6041                };
 6042                let actions = join_all(responses.payload.into_iter().map(|response| {
 6043                    GetCodeActions {
 6044                        range: range.clone(),
 6045                        kinds: kinds.clone(),
 6046                    }
 6047                    .response_from_proto(
 6048                        response.response,
 6049                        lsp_store.clone(),
 6050                        buffer.clone(),
 6051                        cx.clone(),
 6052                    )
 6053                }))
 6054                .await;
 6055
 6056                Ok(Some(
 6057                    actions
 6058                        .into_iter()
 6059                        .collect::<Result<Vec<Vec<_>>>>()?
 6060                        .into_iter()
 6061                        .flatten()
 6062                        .collect(),
 6063                ))
 6064            })
 6065        } else {
 6066            let all_actions_task = self.request_multiple_lsp_locally(
 6067                buffer,
 6068                Some(range.start),
 6069                GetCodeActions { range, kinds },
 6070                cx,
 6071            );
 6072            cx.background_spawn(async move {
 6073                Ok(Some(
 6074                    all_actions_task
 6075                        .await
 6076                        .into_iter()
 6077                        .flat_map(|(_, actions)| actions)
 6078                        .collect(),
 6079                ))
 6080            })
 6081        }
 6082    }
 6083
 6084    #[inline(never)]
 6085    pub fn completions(
 6086        &self,
 6087        buffer: &Entity<Buffer>,
 6088        position: PointUtf16,
 6089        context: CompletionContext,
 6090        cx: &mut Context<Self>,
 6091    ) -> Task<Result<Vec<CompletionResponse>>> {
 6092        let language_registry = self.languages.clone();
 6093
 6094        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6095            let snapshot = buffer.read(cx).snapshot();
 6096            let offset = position.to_offset(&snapshot);
 6097            let scope = snapshot.language_scope_at(offset);
 6098            let capable_lsps = self.all_capable_for_proto_request(
 6099                buffer,
 6100                |server_name, capabilities| {
 6101                    capabilities.completion_provider.is_some()
 6102                        && scope
 6103                            .as_ref()
 6104                            .map(|scope| scope.language_allowed(server_name))
 6105                            .unwrap_or(true)
 6106                },
 6107                cx,
 6108            );
 6109            if capable_lsps.is_empty() {
 6110                return Task::ready(Ok(Vec::new()));
 6111            }
 6112
 6113            let language = buffer.read(cx).language().cloned();
 6114
 6115            // In the future, we should provide project guests with the names of LSP adapters,
 6116            // so that they can use the correct LSP adapter when computing labels. For now,
 6117            // guests just use the first LSP adapter associated with the buffer's language.
 6118            let lsp_adapter = language.as_ref().and_then(|language| {
 6119                language_registry
 6120                    .lsp_adapters(&language.name())
 6121                    .first()
 6122                    .cloned()
 6123            });
 6124
 6125            let buffer = buffer.clone();
 6126
 6127            cx.spawn(async move |this, cx| {
 6128                let requests = join_all(
 6129                    capable_lsps
 6130                        .into_iter()
 6131                        .map(|id| {
 6132                            let request = GetCompletions {
 6133                                position,
 6134                                context: context.clone(),
 6135                                server_id: Some(id),
 6136                            };
 6137                            let buffer = buffer.clone();
 6138                            let language = language.clone();
 6139                            let lsp_adapter = lsp_adapter.clone();
 6140                            let upstream_client = upstream_client.clone();
 6141                            let response = this
 6142                                .update(cx, |this, cx| {
 6143                                    this.send_lsp_proto_request(
 6144                                        buffer,
 6145                                        upstream_client,
 6146                                        project_id,
 6147                                        request,
 6148                                        cx,
 6149                                    )
 6150                                })
 6151                                .log_err();
 6152                            async move {
 6153                                let response = response?.await.log_err()?;
 6154
 6155                                let completions = populate_labels_for_completions(
 6156                                    response.completions,
 6157                                    language,
 6158                                    lsp_adapter,
 6159                                )
 6160                                .await;
 6161
 6162                                Some(CompletionResponse {
 6163                                    completions,
 6164                                    display_options: CompletionDisplayOptions::default(),
 6165                                    is_incomplete: response.is_incomplete,
 6166                                })
 6167                            }
 6168                        })
 6169                        .collect::<Vec<_>>(),
 6170                );
 6171                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6172            })
 6173        } else if let Some(local) = self.as_local() {
 6174            let snapshot = buffer.read(cx).snapshot();
 6175            let offset = position.to_offset(&snapshot);
 6176            let scope = snapshot.language_scope_at(offset);
 6177            let language = snapshot.language().cloned();
 6178            let completion_settings = language_settings(
 6179                language.as_ref().map(|language| language.name()),
 6180                buffer.read(cx).file(),
 6181                cx,
 6182            )
 6183            .completions
 6184            .clone();
 6185            if !completion_settings.lsp {
 6186                return Task::ready(Ok(Vec::new()));
 6187            }
 6188
 6189            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6190                local
 6191                    .language_servers_for_buffer(buffer, cx)
 6192                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6193                    .filter(|(adapter, _)| {
 6194                        scope
 6195                            .as_ref()
 6196                            .map(|scope| scope.language_allowed(&adapter.name))
 6197                            .unwrap_or(true)
 6198                    })
 6199                    .map(|(_, server)| server.server_id())
 6200                    .collect()
 6201            });
 6202
 6203            let buffer = buffer.clone();
 6204            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6205            let lsp_timeout = if lsp_timeout > 0 {
 6206                Some(Duration::from_millis(lsp_timeout))
 6207            } else {
 6208                None
 6209            };
 6210            cx.spawn(async move |this,  cx| {
 6211                let mut tasks = Vec::with_capacity(server_ids.len());
 6212                this.update(cx, |lsp_store, cx| {
 6213                    for server_id in server_ids {
 6214                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6215                        let lsp_timeout = lsp_timeout
 6216                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6217                        let mut timeout = cx.background_spawn(async move {
 6218                            match lsp_timeout {
 6219                                Some(lsp_timeout) => {
 6220                                    lsp_timeout.await;
 6221                                    true
 6222                                },
 6223                                None => false,
 6224                            }
 6225                        }).fuse();
 6226                        let mut lsp_request = lsp_store.request_lsp(
 6227                            buffer.clone(),
 6228                            LanguageServerToQuery::Other(server_id),
 6229                            GetCompletions {
 6230                                position,
 6231                                context: context.clone(),
 6232                                server_id: Some(server_id),
 6233                            },
 6234                            cx,
 6235                        ).fuse();
 6236                        let new_task = cx.background_spawn(async move {
 6237                            select_biased! {
 6238                                response = lsp_request => anyhow::Ok(Some(response?)),
 6239                                timeout_happened = timeout => {
 6240                                    if timeout_happened {
 6241                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6242                                        Ok(None)
 6243                                    } else {
 6244                                        let completions = lsp_request.await?;
 6245                                        Ok(Some(completions))
 6246                                    }
 6247                                },
 6248                            }
 6249                        });
 6250                        tasks.push((lsp_adapter, new_task));
 6251                    }
 6252                })?;
 6253
 6254                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6255                    let completion_response = task.await.ok()??;
 6256                    let completions = populate_labels_for_completions(
 6257                            completion_response.completions,
 6258                            language.clone(),
 6259                            lsp_adapter,
 6260                        )
 6261                        .await;
 6262                    Some(CompletionResponse {
 6263                        completions,
 6264                        display_options: CompletionDisplayOptions::default(),
 6265                        is_incomplete: completion_response.is_incomplete,
 6266                    })
 6267                });
 6268
 6269                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6270
 6271                Ok(responses.into_iter().flatten().collect())
 6272            })
 6273        } else {
 6274            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6275        }
 6276    }
 6277
 6278    pub fn resolve_completions(
 6279        &self,
 6280        buffer: Entity<Buffer>,
 6281        completion_indices: Vec<usize>,
 6282        completions: Rc<RefCell<Box<[Completion]>>>,
 6283        cx: &mut Context<Self>,
 6284    ) -> Task<Result<bool>> {
 6285        let client = self.upstream_client();
 6286        let buffer_id = buffer.read(cx).remote_id();
 6287        let buffer_snapshot = buffer.read(cx).snapshot();
 6288
 6289        if !self.check_if_capable_for_proto_request(
 6290            &buffer,
 6291            GetCompletions::can_resolve_completions,
 6292            cx,
 6293        ) {
 6294            return Task::ready(Ok(false));
 6295        }
 6296        cx.spawn(async move |lsp_store, cx| {
 6297            let request_timeout = cx.update(|app| {
 6298                ProjectSettings::get_global(app)
 6299                    .global_lsp_settings
 6300                    .get_request_timeout()
 6301            });
 6302
 6303            let mut did_resolve = false;
 6304            if let Some((client, project_id)) = client {
 6305                for completion_index in completion_indices {
 6306                    let server_id = {
 6307                        let completion = &completions.borrow()[completion_index];
 6308                        completion.source.server_id()
 6309                    };
 6310                    if let Some(server_id) = server_id {
 6311                        if Self::resolve_completion_remote(
 6312                            project_id,
 6313                            server_id,
 6314                            buffer_id,
 6315                            completions.clone(),
 6316                            completion_index,
 6317                            client.clone(),
 6318                        )
 6319                        .await
 6320                        .log_err()
 6321                        .is_some()
 6322                        {
 6323                            did_resolve = true;
 6324                        }
 6325                    } else {
 6326                        resolve_word_completion(
 6327                            &buffer_snapshot,
 6328                            &mut completions.borrow_mut()[completion_index],
 6329                        );
 6330                    }
 6331                }
 6332            } else {
 6333                for completion_index in completion_indices {
 6334                    let server_id = {
 6335                        let completion = &completions.borrow()[completion_index];
 6336                        completion.source.server_id()
 6337                    };
 6338                    if let Some(server_id) = server_id {
 6339                        let server_and_adapter = lsp_store
 6340                            .read_with(cx, |lsp_store, _| {
 6341                                let server = lsp_store.language_server_for_id(server_id)?;
 6342                                let adapter =
 6343                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6344                                Some((server, adapter))
 6345                            })
 6346                            .ok()
 6347                            .flatten();
 6348                        let Some((server, adapter)) = server_and_adapter else {
 6349                            continue;
 6350                        };
 6351
 6352                        let resolved = Self::resolve_completion_local(
 6353                            server,
 6354                            completions.clone(),
 6355                            completion_index,
 6356                            request_timeout,
 6357                        )
 6358                        .await
 6359                        .log_err()
 6360                        .is_some();
 6361                        if resolved {
 6362                            Self::regenerate_completion_labels(
 6363                                adapter,
 6364                                &buffer_snapshot,
 6365                                completions.clone(),
 6366                                completion_index,
 6367                            )
 6368                            .await
 6369                            .log_err();
 6370                            did_resolve = true;
 6371                        }
 6372                    } else {
 6373                        resolve_word_completion(
 6374                            &buffer_snapshot,
 6375                            &mut completions.borrow_mut()[completion_index],
 6376                        );
 6377                    }
 6378                }
 6379            }
 6380
 6381            Ok(did_resolve)
 6382        })
 6383    }
 6384
 6385    async fn resolve_completion_local(
 6386        server: Arc<lsp::LanguageServer>,
 6387        completions: Rc<RefCell<Box<[Completion]>>>,
 6388        completion_index: usize,
 6389        request_timeout: Duration,
 6390    ) -> Result<()> {
 6391        let server_id = server.server_id();
 6392        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6393            return Ok(());
 6394        }
 6395
 6396        let request = {
 6397            let completion = &completions.borrow()[completion_index];
 6398            match &completion.source {
 6399                CompletionSource::Lsp {
 6400                    lsp_completion,
 6401                    resolved,
 6402                    server_id: completion_server_id,
 6403                    ..
 6404                } => {
 6405                    if *resolved {
 6406                        return Ok(());
 6407                    }
 6408                    anyhow::ensure!(
 6409                        server_id == *completion_server_id,
 6410                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6411                    );
 6412                    server.request::<lsp::request::ResolveCompletionItem>(
 6413                        *lsp_completion.clone(),
 6414                        request_timeout,
 6415                    )
 6416                }
 6417                CompletionSource::BufferWord { .. }
 6418                | CompletionSource::Dap { .. }
 6419                | CompletionSource::Custom => {
 6420                    return Ok(());
 6421                }
 6422            }
 6423        };
 6424        let resolved_completion = request
 6425            .await
 6426            .into_response()
 6427            .context("resolve completion")?;
 6428
 6429        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6430        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6431
 6432        let mut completions = completions.borrow_mut();
 6433        let completion = &mut completions[completion_index];
 6434        if let CompletionSource::Lsp {
 6435            lsp_completion,
 6436            resolved,
 6437            server_id: completion_server_id,
 6438            ..
 6439        } = &mut completion.source
 6440        {
 6441            if *resolved {
 6442                return Ok(());
 6443            }
 6444            anyhow::ensure!(
 6445                server_id == *completion_server_id,
 6446                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6447            );
 6448            **lsp_completion = resolved_completion;
 6449            *resolved = true;
 6450        }
 6451        Ok(())
 6452    }
 6453
 6454    async fn regenerate_completion_labels(
 6455        adapter: Arc<CachedLspAdapter>,
 6456        snapshot: &BufferSnapshot,
 6457        completions: Rc<RefCell<Box<[Completion]>>>,
 6458        completion_index: usize,
 6459    ) -> Result<()> {
 6460        let completion_item = completions.borrow()[completion_index]
 6461            .source
 6462            .lsp_completion(true)
 6463            .map(Cow::into_owned);
 6464        if let Some(lsp_documentation) = completion_item
 6465            .as_ref()
 6466            .and_then(|completion_item| completion_item.documentation.clone())
 6467        {
 6468            let mut completions = completions.borrow_mut();
 6469            let completion = &mut completions[completion_index];
 6470            completion.documentation = Some(lsp_documentation.into());
 6471        } else {
 6472            let mut completions = completions.borrow_mut();
 6473            let completion = &mut completions[completion_index];
 6474            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6475        }
 6476
 6477        let mut new_label = match completion_item {
 6478            Some(completion_item) => {
 6479                // Some language servers always return `detail` lazily via resolve, regardless of
 6480                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6481                // See: https://github.com/yioneko/vtsls/issues/213
 6482                let language = snapshot.language();
 6483                match language {
 6484                    Some(language) => {
 6485                        adapter
 6486                            .labels_for_completions(
 6487                                std::slice::from_ref(&completion_item),
 6488                                language,
 6489                            )
 6490                            .await?
 6491                    }
 6492                    None => Vec::new(),
 6493                }
 6494                .pop()
 6495                .flatten()
 6496                .unwrap_or_else(|| {
 6497                    CodeLabel::fallback_for_completion(
 6498                        &completion_item,
 6499                        language.map(|language| language.as_ref()),
 6500                    )
 6501                })
 6502            }
 6503            None => CodeLabel::plain(
 6504                completions.borrow()[completion_index].new_text.clone(),
 6505                None,
 6506            ),
 6507        };
 6508        ensure_uniform_list_compatible_label(&mut new_label);
 6509
 6510        let mut completions = completions.borrow_mut();
 6511        let completion = &mut completions[completion_index];
 6512        if completion.label.filter_text() == new_label.filter_text() {
 6513            completion.label = new_label;
 6514        } else {
 6515            log::error!(
 6516                "Resolved completion changed display label from {} to {}. \
 6517                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6518                completion.label.text(),
 6519                new_label.text(),
 6520                completion.label.filter_text(),
 6521                new_label.filter_text()
 6522            );
 6523        }
 6524
 6525        Ok(())
 6526    }
 6527
 6528    async fn resolve_completion_remote(
 6529        project_id: u64,
 6530        server_id: LanguageServerId,
 6531        buffer_id: BufferId,
 6532        completions: Rc<RefCell<Box<[Completion]>>>,
 6533        completion_index: usize,
 6534        client: AnyProtoClient,
 6535    ) -> Result<()> {
 6536        let lsp_completion = {
 6537            let completion = &completions.borrow()[completion_index];
 6538            match &completion.source {
 6539                CompletionSource::Lsp {
 6540                    lsp_completion,
 6541                    resolved,
 6542                    server_id: completion_server_id,
 6543                    ..
 6544                } => {
 6545                    anyhow::ensure!(
 6546                        server_id == *completion_server_id,
 6547                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6548                    );
 6549                    if *resolved {
 6550                        return Ok(());
 6551                    }
 6552                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6553                }
 6554                CompletionSource::Custom
 6555                | CompletionSource::Dap { .. }
 6556                | CompletionSource::BufferWord { .. } => {
 6557                    return Ok(());
 6558                }
 6559            }
 6560        };
 6561        let request = proto::ResolveCompletionDocumentation {
 6562            project_id,
 6563            language_server_id: server_id.0 as u64,
 6564            lsp_completion,
 6565            buffer_id: buffer_id.into(),
 6566        };
 6567
 6568        let response = client
 6569            .request(request)
 6570            .await
 6571            .context("completion documentation resolve proto request")?;
 6572        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6573
 6574        let documentation = if response.documentation.is_empty() {
 6575            CompletionDocumentation::Undocumented
 6576        } else if response.documentation_is_markdown {
 6577            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6578        } else if response.documentation.lines().count() <= 1 {
 6579            CompletionDocumentation::SingleLine(response.documentation.into())
 6580        } else {
 6581            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6582        };
 6583
 6584        let mut completions = completions.borrow_mut();
 6585        let completion = &mut completions[completion_index];
 6586        completion.documentation = Some(documentation);
 6587        if let CompletionSource::Lsp {
 6588            insert_range,
 6589            lsp_completion,
 6590            resolved,
 6591            server_id: completion_server_id,
 6592            lsp_defaults: _,
 6593        } = &mut completion.source
 6594        {
 6595            let completion_insert_range = response
 6596                .old_insert_start
 6597                .and_then(deserialize_anchor)
 6598                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6599            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6600
 6601            if *resolved {
 6602                return Ok(());
 6603            }
 6604            anyhow::ensure!(
 6605                server_id == *completion_server_id,
 6606                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6607            );
 6608            **lsp_completion = resolved_lsp_completion;
 6609            *resolved = true;
 6610        }
 6611
 6612        let replace_range = response
 6613            .old_replace_start
 6614            .and_then(deserialize_anchor)
 6615            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6616        if let Some((old_replace_start, old_replace_end)) = replace_range
 6617            && !response.new_text.is_empty()
 6618        {
 6619            completion.new_text = response.new_text;
 6620            completion.replace_range = old_replace_start..old_replace_end;
 6621        }
 6622
 6623        Ok(())
 6624    }
 6625
 6626    pub fn apply_additional_edits_for_completion(
 6627        &self,
 6628        buffer_handle: Entity<Buffer>,
 6629        completions: Rc<RefCell<Box<[Completion]>>>,
 6630        completion_index: usize,
 6631        push_to_history: bool,
 6632        cx: &mut Context<Self>,
 6633    ) -> Task<Result<Option<Transaction>>> {
 6634        if let Some((client, project_id)) = self.upstream_client() {
 6635            let buffer = buffer_handle.read(cx);
 6636            let buffer_id = buffer.remote_id();
 6637            cx.spawn(async move |_, cx| {
 6638                let request = {
 6639                    let completion = completions.borrow()[completion_index].clone();
 6640                    proto::ApplyCompletionAdditionalEdits {
 6641                        project_id,
 6642                        buffer_id: buffer_id.into(),
 6643                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6644                            replace_range: completion.replace_range,
 6645                            new_text: completion.new_text,
 6646                            source: completion.source,
 6647                        })),
 6648                    }
 6649                };
 6650
 6651                let Some(transaction) = client.request(request).await?.transaction else {
 6652                    return Ok(None);
 6653                };
 6654
 6655                let transaction = language::proto::deserialize_transaction(transaction)?;
 6656                buffer_handle
 6657                    .update(cx, |buffer, _| {
 6658                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6659                    })
 6660                    .await?;
 6661                if push_to_history {
 6662                    buffer_handle.update(cx, |buffer, _| {
 6663                        buffer.push_transaction(transaction.clone(), Instant::now());
 6664                        buffer.finalize_last_transaction();
 6665                    });
 6666                }
 6667                Ok(Some(transaction))
 6668            })
 6669        } else {
 6670            let request_timeout = ProjectSettings::get_global(cx)
 6671                .global_lsp_settings
 6672                .get_request_timeout();
 6673
 6674            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6675                let completion = &completions.borrow()[completion_index];
 6676                let server_id = completion.source.server_id()?;
 6677                Some(
 6678                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6679                        .1
 6680                        .clone(),
 6681                )
 6682            }) else {
 6683                return Task::ready(Ok(None));
 6684            };
 6685
 6686            cx.spawn(async move |this, cx| {
 6687                Self::resolve_completion_local(
 6688                    server.clone(),
 6689                    completions.clone(),
 6690                    completion_index,
 6691                    request_timeout,
 6692                )
 6693                .await
 6694                .context("resolving completion")?;
 6695                let completion = completions.borrow()[completion_index].clone();
 6696                let additional_text_edits = completion
 6697                    .source
 6698                    .lsp_completion(true)
 6699                    .as_ref()
 6700                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6701                if let Some(edits) = additional_text_edits {
 6702                    let edits = this
 6703                        .update(cx, |this, cx| {
 6704                            this.as_local_mut().unwrap().edits_from_lsp(
 6705                                &buffer_handle,
 6706                                edits,
 6707                                server.server_id(),
 6708                                None,
 6709                                cx,
 6710                            )
 6711                        })?
 6712                        .await?;
 6713
 6714                    buffer_handle.update(cx, |buffer, cx| {
 6715                        buffer.finalize_last_transaction();
 6716                        buffer.start_transaction();
 6717
 6718                        for (range, text) in edits {
 6719                            let primary = &completion.replace_range;
 6720
 6721                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6722                            // and the primary completion is just an insertion (empty range), then this is likely
 6723                            // an auto-import scenario and should not be considered overlapping
 6724                            // https://github.com/zed-industries/zed/issues/26136
 6725                            let is_file_start_auto_import = {
 6726                                let snapshot = buffer.snapshot();
 6727                                let primary_start_point = primary.start.to_point(&snapshot);
 6728                                let range_start_point = range.start.to_point(&snapshot);
 6729
 6730                                let result = primary_start_point.row == 0
 6731                                    && primary_start_point.column == 0
 6732                                    && range_start_point.row == 0
 6733                                    && range_start_point.column == 0;
 6734
 6735                                result
 6736                            };
 6737
 6738                            let has_overlap = if is_file_start_auto_import {
 6739                                false
 6740                            } else {
 6741                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6742                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6743                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6744                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6745                                let result = start_within || end_within;
 6746                                result
 6747                            };
 6748
 6749                            //Skip additional edits which overlap with the primary completion edit
 6750                            //https://github.com/zed-industries/zed/pull/1871
 6751                            if !has_overlap {
 6752                                buffer.edit([(range, text)], None, cx);
 6753                            }
 6754                        }
 6755
 6756                        let transaction = if buffer.end_transaction(cx).is_some() {
 6757                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6758                            if !push_to_history {
 6759                                buffer.forget_transaction(transaction.id);
 6760                            }
 6761                            Some(transaction)
 6762                        } else {
 6763                            None
 6764                        };
 6765                        Ok(transaction)
 6766                    })
 6767                } else {
 6768                    Ok(None)
 6769                }
 6770            })
 6771        }
 6772    }
 6773
 6774    pub fn pull_diagnostics(
 6775        &mut self,
 6776        buffer: Entity<Buffer>,
 6777        cx: &mut Context<Self>,
 6778    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6779        let buffer_id = buffer.read(cx).remote_id();
 6780
 6781        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6782            let mut suitable_capabilities = None;
 6783            // Are we capable for proto request?
 6784            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6785                &buffer,
 6786                |capabilities| {
 6787                    if let Some(caps) = &capabilities.diagnostic_provider {
 6788                        suitable_capabilities = Some(caps.clone());
 6789                        true
 6790                    } else {
 6791                        false
 6792                    }
 6793                },
 6794                cx,
 6795            );
 6796            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6797            let Some(dynamic_caps) = suitable_capabilities else {
 6798                return Task::ready(Ok(None));
 6799            };
 6800            assert!(any_server_has_diagnostics_provider);
 6801
 6802            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6803            let request = GetDocumentDiagnostics {
 6804                previous_result_id: None,
 6805                identifier,
 6806                registration_id: None,
 6807            };
 6808            let request_timeout = ProjectSettings::get_global(cx)
 6809                .global_lsp_settings
 6810                .get_request_timeout();
 6811            let request_task = client.request_lsp(
 6812                upstream_project_id,
 6813                None,
 6814                request_timeout,
 6815                cx.background_executor().clone(),
 6816                request.to_proto(upstream_project_id, buffer.read(cx)),
 6817            );
 6818            cx.background_spawn(async move {
 6819                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6820                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6821                // Do not attempt to further process the dummy responses here.
 6822                let _response = request_task.await?;
 6823                Ok(None)
 6824            })
 6825        } else {
 6826            let servers = buffer.update(cx, |buffer, cx| {
 6827                self.running_language_servers_for_local_buffer(buffer, cx)
 6828                    .map(|(_, server)| server.clone())
 6829                    .collect::<Vec<_>>()
 6830            });
 6831
 6832            let pull_diagnostics = servers
 6833                .into_iter()
 6834                .flat_map(|server| {
 6835                    let result = maybe!({
 6836                        let local = self.as_local()?;
 6837                        let server_id = server.server_id();
 6838                        let providers_with_identifiers = local
 6839                            .language_server_dynamic_registrations
 6840                            .get(&server_id)
 6841                            .into_iter()
 6842                            .flat_map(|registrations| registrations.diagnostics.clone())
 6843                            .collect::<Vec<_>>();
 6844                        Some(
 6845                            providers_with_identifiers
 6846                                .into_iter()
 6847                                .map(|(registration_id, dynamic_caps)| {
 6848                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6849                                    let registration_id = registration_id.map(SharedString::from);
 6850                                    let result_id = self.result_id_for_buffer_pull(
 6851                                        server_id,
 6852                                        buffer_id,
 6853                                        &registration_id,
 6854                                        cx,
 6855                                    );
 6856                                    self.request_lsp(
 6857                                        buffer.clone(),
 6858                                        LanguageServerToQuery::Other(server_id),
 6859                                        GetDocumentDiagnostics {
 6860                                            previous_result_id: result_id,
 6861                                            registration_id,
 6862                                            identifier,
 6863                                        },
 6864                                        cx,
 6865                                    )
 6866                                })
 6867                                .collect::<Vec<_>>(),
 6868                        )
 6869                    });
 6870
 6871                    result.unwrap_or_default()
 6872                })
 6873                .collect::<Vec<_>>();
 6874
 6875            cx.background_spawn(async move {
 6876                let mut responses = Vec::new();
 6877                for diagnostics in join_all(pull_diagnostics).await {
 6878                    responses.extend(diagnostics?);
 6879                }
 6880                Ok(Some(responses))
 6881            })
 6882        }
 6883    }
 6884
 6885    pub fn applicable_inlay_chunks(
 6886        &mut self,
 6887        buffer: &Entity<Buffer>,
 6888        ranges: &[Range<text::Anchor>],
 6889        cx: &mut Context<Self>,
 6890    ) -> Vec<Range<BufferRow>> {
 6891        let buffer_snapshot = buffer.read(cx).snapshot();
 6892        let ranges = ranges
 6893            .iter()
 6894            .map(|range| range.to_point(&buffer_snapshot))
 6895            .collect::<Vec<_>>();
 6896
 6897        self.latest_lsp_data(buffer, cx)
 6898            .inlay_hints
 6899            .applicable_chunks(ranges.as_slice())
 6900            .map(|chunk| chunk.row_range())
 6901            .collect()
 6902    }
 6903
 6904    pub fn invalidate_inlay_hints<'a>(
 6905        &'a mut self,
 6906        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6907    ) {
 6908        for buffer_id in for_buffers {
 6909            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6910                lsp_data.inlay_hints.clear();
 6911            }
 6912        }
 6913    }
 6914
 6915    pub fn inlay_hints(
 6916        &mut self,
 6917        invalidate: InvalidationStrategy,
 6918        buffer: Entity<Buffer>,
 6919        ranges: Vec<Range<text::Anchor>>,
 6920        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6921        cx: &mut Context<Self>,
 6922    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6923        let next_hint_id = self.next_hint_id.clone();
 6924        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6925        let query_version = lsp_data.buffer_version.clone();
 6926        let mut lsp_refresh_requested = false;
 6927        let for_server = if let InvalidationStrategy::RefreshRequested {
 6928            server_id,
 6929            request_id,
 6930        } = invalidate
 6931        {
 6932            let invalidated = lsp_data
 6933                .inlay_hints
 6934                .invalidate_for_server_refresh(server_id, request_id);
 6935            lsp_refresh_requested = invalidated;
 6936            Some(server_id)
 6937        } else {
 6938            None
 6939        };
 6940        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6941        let known_chunks = known_chunks
 6942            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6943            .map(|(_, known_chunks)| known_chunks)
 6944            .unwrap_or_default();
 6945
 6946        let buffer_snapshot = buffer.read(cx).snapshot();
 6947        let ranges = ranges
 6948            .iter()
 6949            .map(|range| range.to_point(&buffer_snapshot))
 6950            .collect::<Vec<_>>();
 6951
 6952        let mut hint_fetch_tasks = Vec::new();
 6953        let mut cached_inlay_hints = None;
 6954        let mut ranges_to_query = None;
 6955        let applicable_chunks = existing_inlay_hints
 6956            .applicable_chunks(ranges.as_slice())
 6957            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6958            .collect::<Vec<_>>();
 6959        if applicable_chunks.is_empty() {
 6960            return HashMap::default();
 6961        }
 6962
 6963        for row_chunk in applicable_chunks {
 6964            match (
 6965                existing_inlay_hints
 6966                    .cached_hints(&row_chunk)
 6967                    .filter(|_| !lsp_refresh_requested)
 6968                    .cloned(),
 6969                existing_inlay_hints
 6970                    .fetched_hints(&row_chunk)
 6971                    .as_ref()
 6972                    .filter(|_| !lsp_refresh_requested)
 6973                    .cloned(),
 6974            ) {
 6975                (None, None) => {
 6976                    let chunk_range = row_chunk.anchor_range();
 6977                    ranges_to_query
 6978                        .get_or_insert_with(Vec::new)
 6979                        .push((row_chunk, chunk_range));
 6980                }
 6981                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6982                (Some(cached_hints), None) => {
 6983                    for (server_id, cached_hints) in cached_hints {
 6984                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6985                            cached_inlay_hints
 6986                                .get_or_insert_with(HashMap::default)
 6987                                .entry(row_chunk.row_range())
 6988                                .or_insert_with(HashMap::default)
 6989                                .entry(server_id)
 6990                                .or_insert_with(Vec::new)
 6991                                .extend(cached_hints);
 6992                        }
 6993                    }
 6994                }
 6995                (Some(cached_hints), Some(fetched_hints)) => {
 6996                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6997                    for (server_id, cached_hints) in cached_hints {
 6998                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6999                            cached_inlay_hints
 7000                                .get_or_insert_with(HashMap::default)
 7001                                .entry(row_chunk.row_range())
 7002                                .or_insert_with(HashMap::default)
 7003                                .entry(server_id)
 7004                                .or_insert_with(Vec::new)
 7005                                .extend(cached_hints);
 7006                        }
 7007                    }
 7008                }
 7009            }
 7010        }
 7011
 7012        if hint_fetch_tasks.is_empty()
 7013            && ranges_to_query
 7014                .as_ref()
 7015                .is_none_or(|ranges| ranges.is_empty())
 7016            && let Some(cached_inlay_hints) = cached_inlay_hints
 7017        {
 7018            cached_inlay_hints
 7019                .into_iter()
 7020                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7021                .collect()
 7022        } else {
 7023            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7024                let next_hint_id = next_hint_id.clone();
 7025                let buffer = buffer.clone();
 7026                let query_version = query_version.clone();
 7027                let new_inlay_hints = cx
 7028                    .spawn(async move |lsp_store, cx| {
 7029                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7030                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7031                        })?;
 7032                        new_fetch_task
 7033                            .await
 7034                            .and_then(|new_hints_by_server| {
 7035                                lsp_store.update(cx, |lsp_store, cx| {
 7036                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7037                                    let update_cache = lsp_data.buffer_version == query_version;
 7038                                    if new_hints_by_server.is_empty() {
 7039                                        if update_cache {
 7040                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7041                                        }
 7042                                        HashMap::default()
 7043                                    } else {
 7044                                        new_hints_by_server
 7045                                            .into_iter()
 7046                                            .map(|(server_id, new_hints)| {
 7047                                                let new_hints = new_hints
 7048                                                    .into_iter()
 7049                                                    .map(|new_hint| {
 7050                                                        (
 7051                                                            InlayId::Hint(next_hint_id.fetch_add(
 7052                                                                1,
 7053                                                                atomic::Ordering::AcqRel,
 7054                                                            )),
 7055                                                            new_hint,
 7056                                                        )
 7057                                                    })
 7058                                                    .collect::<Vec<_>>();
 7059                                                if update_cache {
 7060                                                    lsp_data.inlay_hints.insert_new_hints(
 7061                                                        chunk,
 7062                                                        server_id,
 7063                                                        new_hints.clone(),
 7064                                                    );
 7065                                                }
 7066                                                (server_id, new_hints)
 7067                                            })
 7068                                            .collect()
 7069                                    }
 7070                                })
 7071                            })
 7072                            .map_err(Arc::new)
 7073                    })
 7074                    .shared();
 7075
 7076                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7077                *fetch_task = Some(new_inlay_hints.clone());
 7078                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7079            }
 7080
 7081            cached_inlay_hints
 7082                .unwrap_or_default()
 7083                .into_iter()
 7084                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7085                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7086                    (
 7087                        chunk.row_range(),
 7088                        cx.spawn(async move |_, _| {
 7089                            hints_fetch.await.map_err(|e| {
 7090                                if e.error_code() != ErrorCode::Internal {
 7091                                    anyhow!(e.error_code())
 7092                                } else {
 7093                                    anyhow!("{e:#}")
 7094                                }
 7095                            })
 7096                        }),
 7097                    )
 7098                }))
 7099                .collect()
 7100        }
 7101    }
 7102
 7103    fn fetch_inlay_hints(
 7104        &mut self,
 7105        for_server: Option<LanguageServerId>,
 7106        buffer: &Entity<Buffer>,
 7107        range: Range<Anchor>,
 7108        cx: &mut Context<Self>,
 7109    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7110        let request = InlayHints {
 7111            range: range.clone(),
 7112        };
 7113        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7114            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7115                return Task::ready(Ok(HashMap::default()));
 7116            }
 7117            let request_timeout = ProjectSettings::get_global(cx)
 7118                .global_lsp_settings
 7119                .get_request_timeout();
 7120            let request_task = upstream_client.request_lsp(
 7121                project_id,
 7122                for_server.map(|id| id.to_proto()),
 7123                request_timeout,
 7124                cx.background_executor().clone(),
 7125                request.to_proto(project_id, buffer.read(cx)),
 7126            );
 7127            let buffer = buffer.clone();
 7128            cx.spawn(async move |weak_lsp_store, cx| {
 7129                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7130                    return Ok(HashMap::default());
 7131                };
 7132                let Some(responses) = request_task.await? else {
 7133                    return Ok(HashMap::default());
 7134                };
 7135
 7136                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7137                    let lsp_store = lsp_store.clone();
 7138                    let buffer = buffer.clone();
 7139                    let cx = cx.clone();
 7140                    let request = request.clone();
 7141                    async move {
 7142                        (
 7143                            LanguageServerId::from_proto(response.server_id),
 7144                            request
 7145                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7146                                .await,
 7147                        )
 7148                    }
 7149                }))
 7150                .await;
 7151
 7152                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7153                let mut has_errors = false;
 7154                let inlay_hints = inlay_hints
 7155                    .into_iter()
 7156                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7157                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7158                        Err(e) => {
 7159                            has_errors = true;
 7160                            log::error!("{e:#}");
 7161                            None
 7162                        }
 7163                    })
 7164                    .map(|(server_id, mut new_hints)| {
 7165                        new_hints.retain(|hint| {
 7166                            hint.position.is_valid(&buffer_snapshot)
 7167                                && range.start.is_valid(&buffer_snapshot)
 7168                                && range.end.is_valid(&buffer_snapshot)
 7169                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7170                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7171                        });
 7172                        (server_id, new_hints)
 7173                    })
 7174                    .collect::<HashMap<_, _>>();
 7175                anyhow::ensure!(
 7176                    !has_errors || !inlay_hints.is_empty(),
 7177                    "Failed to fetch inlay hints"
 7178                );
 7179                Ok(inlay_hints)
 7180            })
 7181        } else {
 7182            let inlay_hints_task = match for_server {
 7183                Some(server_id) => {
 7184                    let server_task = self.request_lsp(
 7185                        buffer.clone(),
 7186                        LanguageServerToQuery::Other(server_id),
 7187                        request,
 7188                        cx,
 7189                    );
 7190                    cx.background_spawn(async move {
 7191                        let mut responses = Vec::new();
 7192                        match server_task.await {
 7193                            Ok(response) => responses.push((server_id, response)),
 7194                            // rust-analyzer likes to error with this when its still loading up
 7195                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7196                            Err(e) => log::error!(
 7197                                "Error handling response for inlay hints request: {e:#}"
 7198                            ),
 7199                        }
 7200                        responses
 7201                    })
 7202                }
 7203                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7204            };
 7205            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7206            cx.background_spawn(async move {
 7207                Ok(inlay_hints_task
 7208                    .await
 7209                    .into_iter()
 7210                    .map(|(server_id, mut new_hints)| {
 7211                        new_hints.retain(|hint| {
 7212                            hint.position.is_valid(&buffer_snapshot)
 7213                                && range.start.is_valid(&buffer_snapshot)
 7214                                && range.end.is_valid(&buffer_snapshot)
 7215                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7216                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7217                        });
 7218                        (server_id, new_hints)
 7219                    })
 7220                    .collect())
 7221            })
 7222        }
 7223    }
 7224
 7225    fn diagnostic_registration_exists(
 7226        &self,
 7227        server_id: LanguageServerId,
 7228        registration_id: &Option<SharedString>,
 7229    ) -> bool {
 7230        let Some(local) = self.as_local() else {
 7231            return false;
 7232        };
 7233        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7234        else {
 7235            return false;
 7236        };
 7237        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7238        registrations.diagnostics.contains_key(&registration_key)
 7239    }
 7240
 7241    pub fn pull_diagnostics_for_buffer(
 7242        &mut self,
 7243        buffer: Entity<Buffer>,
 7244        cx: &mut Context<Self>,
 7245    ) -> Task<anyhow::Result<()>> {
 7246        let diagnostics = self.pull_diagnostics(buffer, cx);
 7247        cx.spawn(async move |lsp_store, cx| {
 7248            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7249                return Ok(());
 7250            };
 7251            lsp_store.update(cx, |lsp_store, cx| {
 7252                if lsp_store.as_local().is_none() {
 7253                    return;
 7254                }
 7255
 7256                let mut unchanged_buffers = HashMap::default();
 7257                let server_diagnostics_updates = diagnostics
 7258                    .into_iter()
 7259                    .filter_map(|diagnostics_set| match diagnostics_set {
 7260                        LspPullDiagnostics::Response {
 7261                            server_id,
 7262                            uri,
 7263                            diagnostics,
 7264                            registration_id,
 7265                        } => Some((server_id, uri, diagnostics, registration_id)),
 7266                        LspPullDiagnostics::Default => None,
 7267                    })
 7268                    .filter(|(server_id, _, _, registration_id)| {
 7269                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7270                    })
 7271                    .fold(
 7272                        HashMap::default(),
 7273                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7274                            let (result_id, diagnostics) = match diagnostics {
 7275                                PulledDiagnostics::Unchanged { result_id } => {
 7276                                    unchanged_buffers
 7277                                        .entry(new_registration_id.clone())
 7278                                        .or_insert_with(HashSet::default)
 7279                                        .insert(uri.clone());
 7280                                    (Some(result_id), Vec::new())
 7281                                }
 7282                                PulledDiagnostics::Changed {
 7283                                    result_id,
 7284                                    diagnostics,
 7285                                } => (result_id, diagnostics),
 7286                            };
 7287                            let disk_based_sources = Cow::Owned(
 7288                                lsp_store
 7289                                    .language_server_adapter_for_id(server_id)
 7290                                    .as_ref()
 7291                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7292                                    .unwrap_or(&[])
 7293                                    .to_vec(),
 7294                            );
 7295                            acc.entry(server_id)
 7296                                .or_insert_with(HashMap::default)
 7297                                .entry(new_registration_id.clone())
 7298                                .or_insert_with(Vec::new)
 7299                                .push(DocumentDiagnosticsUpdate {
 7300                                    server_id,
 7301                                    diagnostics: lsp::PublishDiagnosticsParams {
 7302                                        uri,
 7303                                        diagnostics,
 7304                                        version: None,
 7305                                    },
 7306                                    result_id: result_id.map(SharedString::new),
 7307                                    disk_based_sources,
 7308                                    registration_id: new_registration_id,
 7309                                });
 7310                            acc
 7311                        },
 7312                    );
 7313
 7314                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7315                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7316                        lsp_store
 7317                            .merge_lsp_diagnostics(
 7318                                DiagnosticSourceKind::Pulled,
 7319                                diagnostic_updates,
 7320                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7321                                    DiagnosticSourceKind::Pulled => {
 7322                                        old_diagnostic.registration_id != registration_id
 7323                                            || unchanged_buffers
 7324                                                .get(&old_diagnostic.registration_id)
 7325                                                .is_some_and(|unchanged_buffers| {
 7326                                                    unchanged_buffers.contains(&document_uri)
 7327                                                })
 7328                                    }
 7329                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7330                                        true
 7331                                    }
 7332                                },
 7333                                cx,
 7334                            )
 7335                            .log_err();
 7336                    }
 7337                }
 7338            })
 7339        })
 7340    }
 7341
 7342    pub fn signature_help<T: ToPointUtf16>(
 7343        &mut self,
 7344        buffer: &Entity<Buffer>,
 7345        position: T,
 7346        cx: &mut Context<Self>,
 7347    ) -> Task<Option<Vec<SignatureHelp>>> {
 7348        let position = position.to_point_utf16(buffer.read(cx));
 7349
 7350        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7351            let request = GetSignatureHelp { position };
 7352            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7353                return Task::ready(None);
 7354            }
 7355            let request_timeout = ProjectSettings::get_global(cx)
 7356                .global_lsp_settings
 7357                .get_request_timeout();
 7358            let request_task = client.request_lsp(
 7359                upstream_project_id,
 7360                None,
 7361                request_timeout,
 7362                cx.background_executor().clone(),
 7363                request.to_proto(upstream_project_id, buffer.read(cx)),
 7364            );
 7365            let buffer = buffer.clone();
 7366            cx.spawn(async move |weak_lsp_store, cx| {
 7367                let lsp_store = weak_lsp_store.upgrade()?;
 7368                let signatures = join_all(
 7369                    request_task
 7370                        .await
 7371                        .log_err()
 7372                        .flatten()
 7373                        .map(|response| response.payload)
 7374                        .unwrap_or_default()
 7375                        .into_iter()
 7376                        .map(|response| {
 7377                            let response = GetSignatureHelp { position }.response_from_proto(
 7378                                response.response,
 7379                                lsp_store.clone(),
 7380                                buffer.clone(),
 7381                                cx.clone(),
 7382                            );
 7383                            async move { response.await.log_err().flatten() }
 7384                        }),
 7385                )
 7386                .await
 7387                .into_iter()
 7388                .flatten()
 7389                .collect();
 7390                Some(signatures)
 7391            })
 7392        } else {
 7393            let all_actions_task = self.request_multiple_lsp_locally(
 7394                buffer,
 7395                Some(position),
 7396                GetSignatureHelp { position },
 7397                cx,
 7398            );
 7399            cx.background_spawn(async move {
 7400                Some(
 7401                    all_actions_task
 7402                        .await
 7403                        .into_iter()
 7404                        .flat_map(|(_, actions)| actions)
 7405                        .collect::<Vec<_>>(),
 7406                )
 7407            })
 7408        }
 7409    }
 7410
 7411    pub fn hover(
 7412        &mut self,
 7413        buffer: &Entity<Buffer>,
 7414        position: PointUtf16,
 7415        cx: &mut Context<Self>,
 7416    ) -> Task<Option<Vec<Hover>>> {
 7417        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7418            let request = GetHover { position };
 7419            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7420                return Task::ready(None);
 7421            }
 7422            let request_timeout = ProjectSettings::get_global(cx)
 7423                .global_lsp_settings
 7424                .get_request_timeout();
 7425            let request_task = client.request_lsp(
 7426                upstream_project_id,
 7427                None,
 7428                request_timeout,
 7429                cx.background_executor().clone(),
 7430                request.to_proto(upstream_project_id, buffer.read(cx)),
 7431            );
 7432            let buffer = buffer.clone();
 7433            cx.spawn(async move |weak_lsp_store, cx| {
 7434                let lsp_store = weak_lsp_store.upgrade()?;
 7435                let hovers = join_all(
 7436                    request_task
 7437                        .await
 7438                        .log_err()
 7439                        .flatten()
 7440                        .map(|response| response.payload)
 7441                        .unwrap_or_default()
 7442                        .into_iter()
 7443                        .map(|response| {
 7444                            let response = GetHover { position }.response_from_proto(
 7445                                response.response,
 7446                                lsp_store.clone(),
 7447                                buffer.clone(),
 7448                                cx.clone(),
 7449                            );
 7450                            async move {
 7451                                response
 7452                                    .await
 7453                                    .log_err()
 7454                                    .flatten()
 7455                                    .and_then(remove_empty_hover_blocks)
 7456                            }
 7457                        }),
 7458                )
 7459                .await
 7460                .into_iter()
 7461                .flatten()
 7462                .collect();
 7463                Some(hovers)
 7464            })
 7465        } else {
 7466            let all_actions_task = self.request_multiple_lsp_locally(
 7467                buffer,
 7468                Some(position),
 7469                GetHover { position },
 7470                cx,
 7471            );
 7472            cx.background_spawn(async move {
 7473                Some(
 7474                    all_actions_task
 7475                        .await
 7476                        .into_iter()
 7477                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7478                        .collect::<Vec<Hover>>(),
 7479                )
 7480            })
 7481        }
 7482    }
 7483
 7484    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7485        let language_registry = self.languages.clone();
 7486
 7487        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7488            let request = upstream_client.request(proto::GetProjectSymbols {
 7489                project_id: *project_id,
 7490                query: query.to_string(),
 7491            });
 7492            cx.foreground_executor().spawn(async move {
 7493                let response = request.await?;
 7494                let mut symbols = Vec::new();
 7495                let core_symbols = response
 7496                    .symbols
 7497                    .into_iter()
 7498                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7499                    .collect::<Vec<_>>();
 7500                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7501                    .await;
 7502                Ok(symbols)
 7503            })
 7504        } else if let Some(local) = self.as_local() {
 7505            struct WorkspaceSymbolsResult {
 7506                server_id: LanguageServerId,
 7507                lsp_adapter: Arc<CachedLspAdapter>,
 7508                worktree: WeakEntity<Worktree>,
 7509                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7510            }
 7511
 7512            let mut requests = Vec::new();
 7513            let mut requested_servers = BTreeSet::new();
 7514            let request_timeout = ProjectSettings::get_global(cx)
 7515                .global_lsp_settings
 7516                .get_request_timeout();
 7517
 7518            for (seed, state) in local.language_server_ids.iter() {
 7519                let Some(worktree_handle) = self
 7520                    .worktree_store
 7521                    .read(cx)
 7522                    .worktree_for_id(seed.worktree_id, cx)
 7523                else {
 7524                    continue;
 7525                };
 7526
 7527                let worktree = worktree_handle.read(cx);
 7528                if !worktree.is_visible() {
 7529                    continue;
 7530                }
 7531
 7532                if !requested_servers.insert(state.id) {
 7533                    continue;
 7534                }
 7535
 7536                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7537                    Some(LanguageServerState::Running {
 7538                        adapter, server, ..
 7539                    }) => (adapter.clone(), server),
 7540
 7541                    _ => continue,
 7542                };
 7543
 7544                let supports_workspace_symbol_request =
 7545                    match server.capabilities().workspace_symbol_provider {
 7546                        Some(OneOf::Left(supported)) => supported,
 7547                        Some(OneOf::Right(_)) => true,
 7548                        None => false,
 7549                    };
 7550
 7551                if !supports_workspace_symbol_request {
 7552                    continue;
 7553                }
 7554
 7555                let worktree_handle = worktree_handle.clone();
 7556                let server_id = server.server_id();
 7557                requests.push(
 7558                    server
 7559                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7560                            lsp::WorkspaceSymbolParams {
 7561                                query: query.to_string(),
 7562                                ..Default::default()
 7563                            },
 7564                            request_timeout,
 7565                        )
 7566                        .map(move |response| {
 7567                            let lsp_symbols = response
 7568                                .into_response()
 7569                                .context("workspace symbols request")
 7570                                .log_err()
 7571                                .flatten()
 7572                                .map(|symbol_response| match symbol_response {
 7573                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7574                                        flat_responses
 7575                                            .into_iter()
 7576                                            .map(|lsp_symbol| {
 7577                                                (
 7578                                                    lsp_symbol.name,
 7579                                                    lsp_symbol.kind,
 7580                                                    lsp_symbol.location,
 7581                                                    lsp_symbol.container_name,
 7582                                                )
 7583                                            })
 7584                                            .collect::<Vec<_>>()
 7585                                    }
 7586                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7587                                        nested_responses
 7588                                            .into_iter()
 7589                                            .filter_map(|lsp_symbol| {
 7590                                                let location = match lsp_symbol.location {
 7591                                                    OneOf::Left(location) => location,
 7592                                                    OneOf::Right(_) => {
 7593                                                        log::error!(
 7594                                                            "Unexpected: client capabilities \
 7595                                                            forbid symbol resolutions in \
 7596                                                            workspace.symbol.resolveSupport"
 7597                                                        );
 7598                                                        return None;
 7599                                                    }
 7600                                                };
 7601                                                Some((
 7602                                                    lsp_symbol.name,
 7603                                                    lsp_symbol.kind,
 7604                                                    location,
 7605                                                    lsp_symbol.container_name,
 7606                                                ))
 7607                                            })
 7608                                            .collect::<Vec<_>>()
 7609                                    }
 7610                                })
 7611                                .unwrap_or_default();
 7612
 7613                            WorkspaceSymbolsResult {
 7614                                server_id,
 7615                                lsp_adapter,
 7616                                worktree: worktree_handle.downgrade(),
 7617                                lsp_symbols,
 7618                            }
 7619                        }),
 7620                );
 7621            }
 7622
 7623            cx.spawn(async move |this, cx| {
 7624                let responses = futures::future::join_all(requests).await;
 7625                let this = match this.upgrade() {
 7626                    Some(this) => this,
 7627                    None => return Ok(Vec::new()),
 7628                };
 7629
 7630                let mut symbols = Vec::new();
 7631                for result in responses {
 7632                    let core_symbols = this.update(cx, |this, cx| {
 7633                        result
 7634                            .lsp_symbols
 7635                            .into_iter()
 7636                            .filter_map(
 7637                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7638                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7639                                    let source_worktree = result.worktree.upgrade()?;
 7640                                    let source_worktree_id = source_worktree.read(cx).id();
 7641
 7642                                    let path = if let Some((tree, rel_path)) =
 7643                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7644                                    {
 7645                                        let worktree_id = tree.read(cx).id();
 7646                                        SymbolLocation::InProject(ProjectPath {
 7647                                            worktree_id,
 7648                                            path: rel_path,
 7649                                        })
 7650                                    } else {
 7651                                        SymbolLocation::OutsideProject {
 7652                                            signature: this.symbol_signature(&abs_path),
 7653                                            abs_path: abs_path.into(),
 7654                                        }
 7655                                    };
 7656
 7657                                    Some(CoreSymbol {
 7658                                        source_language_server_id: result.server_id,
 7659                                        language_server_name: result.lsp_adapter.name.clone(),
 7660                                        source_worktree_id,
 7661                                        path,
 7662                                        kind: symbol_kind,
 7663                                        name: symbol_name,
 7664                                        range: range_from_lsp(symbol_location.range),
 7665                                        container_name,
 7666                                    })
 7667                                },
 7668                            )
 7669                            .collect::<Vec<_>>()
 7670                    });
 7671
 7672                    populate_labels_for_symbols(
 7673                        core_symbols,
 7674                        &language_registry,
 7675                        Some(result.lsp_adapter),
 7676                        &mut symbols,
 7677                    )
 7678                    .await;
 7679                }
 7680
 7681                Ok(symbols)
 7682            })
 7683        } else {
 7684            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7685        }
 7686    }
 7687
 7688    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7689        let mut summary = DiagnosticSummary::default();
 7690        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7691            summary.error_count += path_summary.error_count;
 7692            summary.warning_count += path_summary.warning_count;
 7693        }
 7694        summary
 7695    }
 7696
 7697    /// Returns the diagnostic summary for a specific project path.
 7698    pub fn diagnostic_summary_for_path(
 7699        &self,
 7700        project_path: &ProjectPath,
 7701        _: &App,
 7702    ) -> DiagnosticSummary {
 7703        if let Some(summaries) = self
 7704            .diagnostic_summaries
 7705            .get(&project_path.worktree_id)
 7706            .and_then(|map| map.get(&project_path.path))
 7707        {
 7708            let (error_count, warning_count) = summaries.iter().fold(
 7709                (0, 0),
 7710                |(error_count, warning_count), (_language_server_id, summary)| {
 7711                    (
 7712                        error_count + summary.error_count,
 7713                        warning_count + summary.warning_count,
 7714                    )
 7715                },
 7716            );
 7717
 7718            DiagnosticSummary {
 7719                error_count,
 7720                warning_count,
 7721            }
 7722        } else {
 7723            DiagnosticSummary::default()
 7724        }
 7725    }
 7726
 7727    pub fn diagnostic_summaries<'a>(
 7728        &'a self,
 7729        include_ignored: bool,
 7730        cx: &'a App,
 7731    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7732        self.worktree_store
 7733            .read(cx)
 7734            .visible_worktrees(cx)
 7735            .filter_map(|worktree| {
 7736                let worktree = worktree.read(cx);
 7737                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7738            })
 7739            .flat_map(move |(worktree, summaries)| {
 7740                let worktree_id = worktree.id();
 7741                summaries
 7742                    .iter()
 7743                    .filter(move |(path, _)| {
 7744                        include_ignored
 7745                            || worktree
 7746                                .entry_for_path(path.as_ref())
 7747                                .is_some_and(|entry| !entry.is_ignored)
 7748                    })
 7749                    .flat_map(move |(path, summaries)| {
 7750                        summaries.iter().map(move |(server_id, summary)| {
 7751                            (
 7752                                ProjectPath {
 7753                                    worktree_id,
 7754                                    path: path.clone(),
 7755                                },
 7756                                *server_id,
 7757                                *summary,
 7758                            )
 7759                        })
 7760                    })
 7761            })
 7762    }
 7763
 7764    pub fn on_buffer_edited(
 7765        &mut self,
 7766        buffer: Entity<Buffer>,
 7767        cx: &mut Context<Self>,
 7768    ) -> Option<()> {
 7769        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7770            Some(
 7771                self.as_local()?
 7772                    .language_servers_for_buffer(buffer, cx)
 7773                    .map(|i| i.1.clone())
 7774                    .collect(),
 7775            )
 7776        })?;
 7777
 7778        let buffer = buffer.read(cx);
 7779        let file = File::from_dyn(buffer.file())?;
 7780        let abs_path = file.as_local()?.abs_path(cx);
 7781        let uri = lsp::Uri::from_file_path(&abs_path)
 7782            .ok()
 7783            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7784            .log_err()?;
 7785        let next_snapshot = buffer.text_snapshot();
 7786        for language_server in language_servers {
 7787            let language_server = language_server.clone();
 7788
 7789            let buffer_snapshots = self
 7790                .as_local_mut()?
 7791                .buffer_snapshots
 7792                .get_mut(&buffer.remote_id())
 7793                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7794            let previous_snapshot = buffer_snapshots.last()?;
 7795
 7796            let build_incremental_change = || {
 7797                buffer
 7798                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7799                        previous_snapshot.snapshot.version(),
 7800                    )
 7801                    .map(|edit| {
 7802                        let edit_start = edit.new.start.0;
 7803                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7804                        let new_text = next_snapshot
 7805                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7806                            .collect();
 7807                        lsp::TextDocumentContentChangeEvent {
 7808                            range: Some(lsp::Range::new(
 7809                                point_to_lsp(edit_start),
 7810                                point_to_lsp(edit_end),
 7811                            )),
 7812                            range_length: None,
 7813                            text: new_text,
 7814                        }
 7815                    })
 7816                    .collect()
 7817            };
 7818
 7819            let document_sync_kind = language_server
 7820                .capabilities()
 7821                .text_document_sync
 7822                .as_ref()
 7823                .and_then(|sync| match sync {
 7824                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7825                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7826                });
 7827
 7828            let content_changes: Vec<_> = match document_sync_kind {
 7829                Some(lsp::TextDocumentSyncKind::FULL) => {
 7830                    vec![lsp::TextDocumentContentChangeEvent {
 7831                        range: None,
 7832                        range_length: None,
 7833                        text: next_snapshot.text(),
 7834                    }]
 7835                }
 7836                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7837                _ => {
 7838                    #[cfg(any(test, feature = "test-support"))]
 7839                    {
 7840                        build_incremental_change()
 7841                    }
 7842
 7843                    #[cfg(not(any(test, feature = "test-support")))]
 7844                    {
 7845                        continue;
 7846                    }
 7847                }
 7848            };
 7849
 7850            let next_version = previous_snapshot.version + 1;
 7851            buffer_snapshots.push(LspBufferSnapshot {
 7852                version: next_version,
 7853                snapshot: next_snapshot.clone(),
 7854            });
 7855
 7856            language_server
 7857                .notify::<lsp::notification::DidChangeTextDocument>(
 7858                    lsp::DidChangeTextDocumentParams {
 7859                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7860                            uri.clone(),
 7861                            next_version,
 7862                        ),
 7863                        content_changes,
 7864                    },
 7865                )
 7866                .ok();
 7867            self.pull_workspace_diagnostics(language_server.server_id());
 7868        }
 7869
 7870        None
 7871    }
 7872
 7873    pub fn on_buffer_saved(
 7874        &mut self,
 7875        buffer: Entity<Buffer>,
 7876        cx: &mut Context<Self>,
 7877    ) -> Option<()> {
 7878        let file = File::from_dyn(buffer.read(cx).file())?;
 7879        let worktree_id = file.worktree_id(cx);
 7880        let abs_path = file.as_local()?.abs_path(cx);
 7881        let text_document = lsp::TextDocumentIdentifier {
 7882            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7883        };
 7884        let local = self.as_local()?;
 7885
 7886        for server in local.language_servers_for_worktree(worktree_id) {
 7887            if let Some(include_text) = include_text(server.as_ref()) {
 7888                let text = if include_text {
 7889                    Some(buffer.read(cx).text())
 7890                } else {
 7891                    None
 7892                };
 7893                server
 7894                    .notify::<lsp::notification::DidSaveTextDocument>(
 7895                        lsp::DidSaveTextDocumentParams {
 7896                            text_document: text_document.clone(),
 7897                            text,
 7898                        },
 7899                    )
 7900                    .ok();
 7901            }
 7902        }
 7903
 7904        let language_servers = buffer.update(cx, |buffer, cx| {
 7905            local.language_server_ids_for_buffer(buffer, cx)
 7906        });
 7907        for language_server_id in language_servers {
 7908            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7909        }
 7910
 7911        None
 7912    }
 7913
 7914    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7915        maybe!(async move {
 7916            let mut refreshed_servers = HashSet::default();
 7917            let servers = lsp_store
 7918                .update(cx, |lsp_store, cx| {
 7919                    let local = lsp_store.as_local()?;
 7920
 7921                    let servers = local
 7922                        .language_server_ids
 7923                        .iter()
 7924                        .filter_map(|(seed, state)| {
 7925                            let worktree = lsp_store
 7926                                .worktree_store
 7927                                .read(cx)
 7928                                .worktree_for_id(seed.worktree_id, cx);
 7929                            let delegate: Arc<dyn LspAdapterDelegate> =
 7930                                worktree.map(|worktree| {
 7931                                    LocalLspAdapterDelegate::new(
 7932                                        local.languages.clone(),
 7933                                        &local.environment,
 7934                                        cx.weak_entity(),
 7935                                        &worktree,
 7936                                        local.http_client.clone(),
 7937                                        local.fs.clone(),
 7938                                        cx,
 7939                                    )
 7940                                })?;
 7941                            let server_id = state.id;
 7942
 7943                            let states = local.language_servers.get(&server_id)?;
 7944
 7945                            match states {
 7946                                LanguageServerState::Starting { .. } => None,
 7947                                LanguageServerState::Running {
 7948                                    adapter, server, ..
 7949                                } => {
 7950                                    let adapter = adapter.clone();
 7951                                    let server = server.clone();
 7952                                    refreshed_servers.insert(server.name());
 7953                                    let toolchain = seed.toolchain.clone();
 7954                                    Some(cx.spawn(async move |_, cx| {
 7955                                        let settings =
 7956                                            LocalLspStore::workspace_configuration_for_adapter(
 7957                                                adapter.adapter.clone(),
 7958                                                &delegate,
 7959                                                toolchain,
 7960                                                None,
 7961                                                cx,
 7962                                            )
 7963                                            .await
 7964                                            .ok()?;
 7965                                        server
 7966                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7967                                                lsp::DidChangeConfigurationParams { settings },
 7968                                            )
 7969                                            .ok()?;
 7970                                        Some(())
 7971                                    }))
 7972                                }
 7973                            }
 7974                        })
 7975                        .collect::<Vec<_>>();
 7976
 7977                    Some(servers)
 7978                })
 7979                .ok()
 7980                .flatten()?;
 7981
 7982            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7983            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7984            // to stop and unregister its language server wrapper.
 7985            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7986            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7987            let _: Vec<Option<()>> = join_all(servers).await;
 7988
 7989            Some(())
 7990        })
 7991        .await;
 7992    }
 7993
 7994    fn maintain_workspace_config(
 7995        external_refresh_requests: watch::Receiver<()>,
 7996        cx: &mut Context<Self>,
 7997    ) -> Task<Result<()>> {
 7998        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7999        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8000
 8001        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8002            *settings_changed_tx.borrow_mut() = ();
 8003        });
 8004
 8005        let mut joint_future =
 8006            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8007        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8008        // - 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).
 8009        // - 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.
 8010        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8011        // - 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,
 8012        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8013        cx.spawn(async move |this, cx| {
 8014            while let Some(()) = joint_future.next().await {
 8015                this.update(cx, |this, cx| {
 8016                    this.refresh_server_tree(cx);
 8017                })
 8018                .ok();
 8019
 8020                Self::refresh_workspace_configurations(&this, cx).await;
 8021            }
 8022
 8023            drop(settings_observation);
 8024            anyhow::Ok(())
 8025        })
 8026    }
 8027
 8028    pub fn running_language_servers_for_local_buffer<'a>(
 8029        &'a self,
 8030        buffer: &Buffer,
 8031        cx: &mut App,
 8032    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8033        let local = self.as_local();
 8034        let language_server_ids = local
 8035            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8036            .unwrap_or_default();
 8037
 8038        language_server_ids
 8039            .into_iter()
 8040            .filter_map(
 8041                move |server_id| match local?.language_servers.get(&server_id)? {
 8042                    LanguageServerState::Running {
 8043                        adapter, server, ..
 8044                    } => Some((adapter, server)),
 8045                    _ => None,
 8046                },
 8047            )
 8048    }
 8049
 8050    pub fn language_servers_for_local_buffer(
 8051        &self,
 8052        buffer: &Buffer,
 8053        cx: &mut App,
 8054    ) -> Vec<LanguageServerId> {
 8055        let local = self.as_local();
 8056        local
 8057            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8058            .unwrap_or_default()
 8059    }
 8060
 8061    pub fn language_server_for_local_buffer<'a>(
 8062        &'a self,
 8063        buffer: &'a Buffer,
 8064        server_id: LanguageServerId,
 8065        cx: &'a mut App,
 8066    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8067        self.as_local()?
 8068            .language_servers_for_buffer(buffer, cx)
 8069            .find(|(_, s)| s.server_id() == server_id)
 8070    }
 8071
 8072    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8073        self.diagnostic_summaries.remove(&id_to_remove);
 8074        if let Some(local) = self.as_local_mut() {
 8075            let to_remove = local.remove_worktree(id_to_remove, cx);
 8076            for server in to_remove {
 8077                self.language_server_statuses.remove(&server);
 8078            }
 8079        }
 8080    }
 8081
 8082    pub fn shared(
 8083        &mut self,
 8084        project_id: u64,
 8085        downstream_client: AnyProtoClient,
 8086        _: &mut Context<Self>,
 8087    ) {
 8088        self.downstream_client = Some((downstream_client.clone(), project_id));
 8089
 8090        for (server_id, status) in &self.language_server_statuses {
 8091            if let Some(server) = self.language_server_for_id(*server_id) {
 8092                downstream_client
 8093                    .send(proto::StartLanguageServer {
 8094                        project_id,
 8095                        server: Some(proto::LanguageServer {
 8096                            id: server_id.to_proto(),
 8097                            name: status.name.to_string(),
 8098                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8099                        }),
 8100                        capabilities: serde_json::to_string(&server.capabilities())
 8101                            .expect("serializing server LSP capabilities"),
 8102                    })
 8103                    .log_err();
 8104            }
 8105        }
 8106    }
 8107
 8108    pub fn disconnected_from_host(&mut self) {
 8109        self.downstream_client.take();
 8110    }
 8111
 8112    pub fn disconnected_from_ssh_remote(&mut self) {
 8113        if let LspStoreMode::Remote(RemoteLspStore {
 8114            upstream_client, ..
 8115        }) = &mut self.mode
 8116        {
 8117            upstream_client.take();
 8118        }
 8119    }
 8120
 8121    pub(crate) fn set_language_server_statuses_from_proto(
 8122        &mut self,
 8123        project: WeakEntity<Project>,
 8124        language_servers: Vec<proto::LanguageServer>,
 8125        server_capabilities: Vec<String>,
 8126        cx: &mut Context<Self>,
 8127    ) {
 8128        let lsp_logs = cx
 8129            .try_global::<GlobalLogStore>()
 8130            .map(|lsp_store| lsp_store.0.clone());
 8131
 8132        self.language_server_statuses = language_servers
 8133            .into_iter()
 8134            .zip(server_capabilities)
 8135            .map(|(server, server_capabilities)| {
 8136                let server_id = LanguageServerId(server.id as usize);
 8137                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8138                    self.lsp_server_capabilities
 8139                        .insert(server_id, server_capabilities);
 8140                }
 8141
 8142                let name = LanguageServerName::from_proto(server.name);
 8143                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8144
 8145                if let Some(lsp_logs) = &lsp_logs {
 8146                    lsp_logs.update(cx, |lsp_logs, cx| {
 8147                        lsp_logs.add_language_server(
 8148                            // Only remote clients get their language servers set from proto
 8149                            LanguageServerKind::Remote {
 8150                                project: project.clone(),
 8151                            },
 8152                            server_id,
 8153                            Some(name.clone()),
 8154                            worktree,
 8155                            None,
 8156                            cx,
 8157                        );
 8158                    });
 8159                }
 8160
 8161                (
 8162                    server_id,
 8163                    LanguageServerStatus {
 8164                        name,
 8165                        server_version: None,
 8166                        pending_work: Default::default(),
 8167                        has_pending_diagnostic_updates: false,
 8168                        progress_tokens: Default::default(),
 8169                        worktree,
 8170                        binary: None,
 8171                        configuration: None,
 8172                        workspace_folders: BTreeSet::new(),
 8173                        process_id: None,
 8174                    },
 8175                )
 8176            })
 8177            .collect();
 8178    }
 8179
 8180    #[cfg(feature = "test-support")]
 8181    pub fn update_diagnostic_entries(
 8182        &mut self,
 8183        server_id: LanguageServerId,
 8184        abs_path: PathBuf,
 8185        result_id: Option<SharedString>,
 8186        version: Option<i32>,
 8187        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8188        cx: &mut Context<Self>,
 8189    ) -> anyhow::Result<()> {
 8190        self.merge_diagnostic_entries(
 8191            vec![DocumentDiagnosticsUpdate {
 8192                diagnostics: DocumentDiagnostics {
 8193                    diagnostics,
 8194                    document_abs_path: abs_path,
 8195                    version,
 8196                },
 8197                result_id,
 8198                server_id,
 8199                disk_based_sources: Cow::Borrowed(&[]),
 8200                registration_id: None,
 8201            }],
 8202            |_, _, _| false,
 8203            cx,
 8204        )?;
 8205        Ok(())
 8206    }
 8207
 8208    pub fn merge_diagnostic_entries<'a>(
 8209        &mut self,
 8210        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8211        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8212        cx: &mut Context<Self>,
 8213    ) -> anyhow::Result<()> {
 8214        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8215        let mut updated_diagnostics_paths = HashMap::default();
 8216        for mut update in diagnostic_updates {
 8217            let abs_path = &update.diagnostics.document_abs_path;
 8218            let server_id = update.server_id;
 8219            let Some((worktree, relative_path)) =
 8220                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8221            else {
 8222                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8223                return Ok(());
 8224            };
 8225
 8226            let worktree_id = worktree.read(cx).id();
 8227            let project_path = ProjectPath {
 8228                worktree_id,
 8229                path: relative_path,
 8230            };
 8231
 8232            let document_uri = lsp::Uri::from_file_path(abs_path)
 8233                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8234            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8235                let snapshot = buffer_handle.read(cx).snapshot();
 8236                let buffer = buffer_handle.read(cx);
 8237                let reused_diagnostics = buffer
 8238                    .buffer_diagnostics(Some(server_id))
 8239                    .iter()
 8240                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8241                    .map(|v| {
 8242                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8243                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8244                        DiagnosticEntry {
 8245                            range: start..end,
 8246                            diagnostic: v.diagnostic.clone(),
 8247                        }
 8248                    })
 8249                    .collect::<Vec<_>>();
 8250
 8251                self.as_local_mut()
 8252                    .context("cannot merge diagnostics on a remote LspStore")?
 8253                    .update_buffer_diagnostics(
 8254                        &buffer_handle,
 8255                        server_id,
 8256                        Some(update.registration_id),
 8257                        update.result_id,
 8258                        update.diagnostics.version,
 8259                        update.diagnostics.diagnostics.clone(),
 8260                        reused_diagnostics.clone(),
 8261                        cx,
 8262                    )?;
 8263
 8264                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8265            } else if let Some(local) = self.as_local() {
 8266                let reused_diagnostics = local
 8267                    .diagnostics
 8268                    .get(&worktree_id)
 8269                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8270                    .and_then(|diagnostics_by_server_id| {
 8271                        diagnostics_by_server_id
 8272                            .binary_search_by_key(&server_id, |e| e.0)
 8273                            .ok()
 8274                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8275                    })
 8276                    .into_iter()
 8277                    .flatten()
 8278                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8279
 8280                update
 8281                    .diagnostics
 8282                    .diagnostics
 8283                    .extend(reused_diagnostics.cloned());
 8284            }
 8285
 8286            let updated = worktree.update(cx, |worktree, cx| {
 8287                self.update_worktree_diagnostics(
 8288                    worktree.id(),
 8289                    server_id,
 8290                    project_path.path.clone(),
 8291                    update.diagnostics.diagnostics,
 8292                    cx,
 8293                )
 8294            })?;
 8295            match updated {
 8296                ControlFlow::Continue(new_summary) => {
 8297                    if let Some((project_id, new_summary)) = new_summary {
 8298                        match &mut diagnostics_summary {
 8299                            Some(diagnostics_summary) => {
 8300                                diagnostics_summary
 8301                                    .more_summaries
 8302                                    .push(proto::DiagnosticSummary {
 8303                                        path: project_path.path.as_ref().to_proto(),
 8304                                        language_server_id: server_id.0 as u64,
 8305                                        error_count: new_summary.error_count,
 8306                                        warning_count: new_summary.warning_count,
 8307                                    })
 8308                            }
 8309                            None => {
 8310                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8311                                    project_id,
 8312                                    worktree_id: worktree_id.to_proto(),
 8313                                    summary: Some(proto::DiagnosticSummary {
 8314                                        path: project_path.path.as_ref().to_proto(),
 8315                                        language_server_id: server_id.0 as u64,
 8316                                        error_count: new_summary.error_count,
 8317                                        warning_count: new_summary.warning_count,
 8318                                    }),
 8319                                    more_summaries: Vec::new(),
 8320                                })
 8321                            }
 8322                        }
 8323                    }
 8324                    updated_diagnostics_paths
 8325                        .entry(server_id)
 8326                        .or_insert_with(Vec::new)
 8327                        .push(project_path);
 8328                }
 8329                ControlFlow::Break(()) => {}
 8330            }
 8331        }
 8332
 8333        if let Some((diagnostics_summary, (downstream_client, _))) =
 8334            diagnostics_summary.zip(self.downstream_client.as_ref())
 8335        {
 8336            downstream_client.send(diagnostics_summary).log_err();
 8337        }
 8338        for (server_id, paths) in updated_diagnostics_paths {
 8339            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8340        }
 8341        Ok(())
 8342    }
 8343
 8344    fn update_worktree_diagnostics(
 8345        &mut self,
 8346        worktree_id: WorktreeId,
 8347        server_id: LanguageServerId,
 8348        path_in_worktree: Arc<RelPath>,
 8349        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8350        _: &mut Context<Worktree>,
 8351    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8352        let local = match &mut self.mode {
 8353            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8354            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8355        };
 8356
 8357        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8358        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8359        let summaries_by_server_id = summaries_for_tree
 8360            .entry(path_in_worktree.clone())
 8361            .or_default();
 8362
 8363        let old_summary = summaries_by_server_id
 8364            .remove(&server_id)
 8365            .unwrap_or_default();
 8366
 8367        let new_summary = DiagnosticSummary::new(&diagnostics);
 8368        if diagnostics.is_empty() {
 8369            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8370            {
 8371                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8372                    diagnostics_by_server_id.remove(ix);
 8373                }
 8374                if diagnostics_by_server_id.is_empty() {
 8375                    diagnostics_for_tree.remove(&path_in_worktree);
 8376                }
 8377            }
 8378        } else {
 8379            summaries_by_server_id.insert(server_id, new_summary);
 8380            let diagnostics_by_server_id = diagnostics_for_tree
 8381                .entry(path_in_worktree.clone())
 8382                .or_default();
 8383            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8384                Ok(ix) => {
 8385                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8386                }
 8387                Err(ix) => {
 8388                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8389                }
 8390            }
 8391        }
 8392
 8393        if !old_summary.is_empty() || !new_summary.is_empty() {
 8394            if let Some((_, project_id)) = &self.downstream_client {
 8395                Ok(ControlFlow::Continue(Some((
 8396                    *project_id,
 8397                    proto::DiagnosticSummary {
 8398                        path: path_in_worktree.to_proto(),
 8399                        language_server_id: server_id.0 as u64,
 8400                        error_count: new_summary.error_count as u32,
 8401                        warning_count: new_summary.warning_count as u32,
 8402                    },
 8403                ))))
 8404            } else {
 8405                Ok(ControlFlow::Continue(None))
 8406            }
 8407        } else {
 8408            Ok(ControlFlow::Break(()))
 8409        }
 8410    }
 8411
 8412    pub fn open_buffer_for_symbol(
 8413        &mut self,
 8414        symbol: &Symbol,
 8415        cx: &mut Context<Self>,
 8416    ) -> Task<Result<Entity<Buffer>>> {
 8417        if let Some((client, project_id)) = self.upstream_client() {
 8418            let request = client.request(proto::OpenBufferForSymbol {
 8419                project_id,
 8420                symbol: Some(Self::serialize_symbol(symbol)),
 8421            });
 8422            cx.spawn(async move |this, cx| {
 8423                let response = request.await?;
 8424                let buffer_id = BufferId::new(response.buffer_id)?;
 8425                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8426                    .await
 8427            })
 8428        } else if let Some(local) = self.as_local() {
 8429            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8430                seed.worktree_id == symbol.source_worktree_id
 8431                    && state.id == symbol.source_language_server_id
 8432                    && symbol.language_server_name == seed.name
 8433            });
 8434            if !is_valid {
 8435                return Task::ready(Err(anyhow!(
 8436                    "language server for worktree and language not found"
 8437                )));
 8438            };
 8439
 8440            let symbol_abs_path = match &symbol.path {
 8441                SymbolLocation::InProject(project_path) => self
 8442                    .worktree_store
 8443                    .read(cx)
 8444                    .absolutize(&project_path, cx)
 8445                    .context("no such worktree"),
 8446                SymbolLocation::OutsideProject {
 8447                    abs_path,
 8448                    signature: _,
 8449                } => Ok(abs_path.to_path_buf()),
 8450            };
 8451            let symbol_abs_path = match symbol_abs_path {
 8452                Ok(abs_path) => abs_path,
 8453                Err(err) => return Task::ready(Err(err)),
 8454            };
 8455            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8456                uri
 8457            } else {
 8458                return Task::ready(Err(anyhow!("invalid symbol path")));
 8459            };
 8460
 8461            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8462        } else {
 8463            Task::ready(Err(anyhow!("no upstream client or local store")))
 8464        }
 8465    }
 8466
 8467    pub(crate) fn open_local_buffer_via_lsp(
 8468        &mut self,
 8469        abs_path: lsp::Uri,
 8470        language_server_id: LanguageServerId,
 8471        cx: &mut Context<Self>,
 8472    ) -> Task<Result<Entity<Buffer>>> {
 8473        let path_style = self.worktree_store.read(cx).path_style();
 8474        cx.spawn(async move |lsp_store, cx| {
 8475            // Escape percent-encoded string.
 8476            let current_scheme = abs_path.scheme().to_owned();
 8477            // Uri is immutable, so we can't modify the scheme
 8478
 8479            let abs_path = abs_path
 8480                .to_file_path_ext(path_style)
 8481                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8482            let p = abs_path.clone();
 8483            let yarn_worktree = lsp_store
 8484                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8485                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8486                        cx.spawn(async move |this, cx| {
 8487                            let t = this
 8488                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8489                                .ok()?;
 8490                            t.await
 8491                        })
 8492                    }),
 8493                    None => Task::ready(None),
 8494                })?
 8495                .await;
 8496            let (worktree_root_target, known_relative_path) =
 8497                if let Some((zip_root, relative_path)) = yarn_worktree {
 8498                    (zip_root, Some(relative_path))
 8499                } else {
 8500                    (Arc::<Path>::from(abs_path.as_path()), None)
 8501                };
 8502            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8503                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8504                    worktree_store.find_worktree(&worktree_root_target, cx)
 8505                })
 8506            })?;
 8507            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8508                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8509                (result.0, relative_path, None)
 8510            } else {
 8511                let worktree = lsp_store
 8512                    .update(cx, |lsp_store, cx| {
 8513                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8514                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8515                        })
 8516                    })?
 8517                    .await?;
 8518                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8519                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8520                    lsp_store
 8521                        .update(cx, |lsp_store, cx| {
 8522                            if let Some(local) = lsp_store.as_local_mut() {
 8523                                local.register_language_server_for_invisible_worktree(
 8524                                    &worktree,
 8525                                    language_server_id,
 8526                                    cx,
 8527                                )
 8528                            }
 8529                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8530                                Some(status) => status.worktree,
 8531                                None => None,
 8532                            }
 8533                        })
 8534                        .ok()
 8535                        .flatten()
 8536                        .zip(Some(worktree_root.clone()))
 8537                } else {
 8538                    None
 8539                };
 8540                let relative_path = if let Some(known_path) = known_relative_path {
 8541                    known_path
 8542                } else {
 8543                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8544                        .into_arc()
 8545                };
 8546                (worktree, relative_path, source_ws)
 8547            };
 8548            let project_path = ProjectPath {
 8549                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8550                path: relative_path,
 8551            };
 8552            let buffer = lsp_store
 8553                .update(cx, |lsp_store, cx| {
 8554                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8555                        buffer_store.open_buffer(project_path, cx)
 8556                    })
 8557                })?
 8558                .await?;
 8559            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8560            if let Some((source_ws, worktree_root)) = source_ws {
 8561                buffer.update(cx, |buffer, cx| {
 8562                    let settings = WorktreeSettings::get(
 8563                        Some(
 8564                            (&ProjectPath {
 8565                                worktree_id: source_ws,
 8566                                path: Arc::from(RelPath::empty()),
 8567                            })
 8568                                .into(),
 8569                        ),
 8570                        cx,
 8571                    );
 8572                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8573                    if is_read_only {
 8574                        buffer.set_capability(Capability::ReadOnly, cx);
 8575                    }
 8576                });
 8577            }
 8578            Ok(buffer)
 8579        })
 8580    }
 8581
 8582    fn local_lsp_servers_for_buffer(
 8583        &self,
 8584        buffer: &Entity<Buffer>,
 8585        cx: &mut Context<Self>,
 8586    ) -> Vec<LanguageServerId> {
 8587        let Some(local) = self.as_local() else {
 8588            return Vec::new();
 8589        };
 8590
 8591        let snapshot = buffer.read(cx).snapshot();
 8592
 8593        buffer.update(cx, |buffer, cx| {
 8594            local
 8595                .language_servers_for_buffer(buffer, cx)
 8596                .map(|(_, server)| server.server_id())
 8597                .filter(|server_id| {
 8598                    self.as_local().is_none_or(|local| {
 8599                        local
 8600                            .buffers_opened_in_servers
 8601                            .get(&snapshot.remote_id())
 8602                            .is_some_and(|servers| servers.contains(server_id))
 8603                    })
 8604                })
 8605                .collect()
 8606        })
 8607    }
 8608
 8609    fn request_multiple_lsp_locally<P, R>(
 8610        &mut self,
 8611        buffer: &Entity<Buffer>,
 8612        position: Option<P>,
 8613        request: R,
 8614        cx: &mut Context<Self>,
 8615    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8616    where
 8617        P: ToOffset,
 8618        R: LspCommand + Clone,
 8619        <R::LspRequest as lsp::request::Request>::Result: Send,
 8620        <R::LspRequest as lsp::request::Request>::Params: Send,
 8621    {
 8622        let Some(local) = self.as_local() else {
 8623            return Task::ready(Vec::new());
 8624        };
 8625
 8626        let snapshot = buffer.read(cx).snapshot();
 8627        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8628
 8629        let server_ids = buffer.update(cx, |buffer, cx| {
 8630            local
 8631                .language_servers_for_buffer(buffer, cx)
 8632                .filter(|(adapter, _)| {
 8633                    scope
 8634                        .as_ref()
 8635                        .map(|scope| scope.language_allowed(&adapter.name))
 8636                        .unwrap_or(true)
 8637                })
 8638                .map(|(_, server)| server.server_id())
 8639                .filter(|server_id| {
 8640                    self.as_local().is_none_or(|local| {
 8641                        local
 8642                            .buffers_opened_in_servers
 8643                            .get(&snapshot.remote_id())
 8644                            .is_some_and(|servers| servers.contains(server_id))
 8645                    })
 8646                })
 8647                .collect::<Vec<_>>()
 8648        });
 8649
 8650        let mut response_results = server_ids
 8651            .into_iter()
 8652            .map(|server_id| {
 8653                let task = self.request_lsp(
 8654                    buffer.clone(),
 8655                    LanguageServerToQuery::Other(server_id),
 8656                    request.clone(),
 8657                    cx,
 8658                );
 8659                async move { (server_id, task.await) }
 8660            })
 8661            .collect::<FuturesUnordered<_>>();
 8662
 8663        cx.background_spawn(async move {
 8664            let mut responses = Vec::with_capacity(response_results.len());
 8665            while let Some((server_id, response_result)) = response_results.next().await {
 8666                match response_result {
 8667                    Ok(response) => responses.push((server_id, response)),
 8668                    // rust-analyzer likes to error with this when its still loading up
 8669                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8670                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8671                }
 8672            }
 8673            responses
 8674        })
 8675    }
 8676
 8677    async fn handle_lsp_get_completions(
 8678        this: Entity<Self>,
 8679        envelope: TypedEnvelope<proto::GetCompletions>,
 8680        mut cx: AsyncApp,
 8681    ) -> Result<proto::GetCompletionsResponse> {
 8682        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8683
 8684        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8685        let buffer_handle = this.update(&mut cx, |this, cx| {
 8686            this.buffer_store.read(cx).get_existing(buffer_id)
 8687        })?;
 8688        let request = GetCompletions::from_proto(
 8689            envelope.payload,
 8690            this.clone(),
 8691            buffer_handle.clone(),
 8692            cx.clone(),
 8693        )
 8694        .await?;
 8695
 8696        let server_to_query = match request.server_id {
 8697            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8698            None => LanguageServerToQuery::FirstCapable,
 8699        };
 8700
 8701        let response = this
 8702            .update(&mut cx, |this, cx| {
 8703                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8704            })
 8705            .await?;
 8706        this.update(&mut cx, |this, cx| {
 8707            Ok(GetCompletions::response_to_proto(
 8708                response,
 8709                this,
 8710                sender_id,
 8711                &buffer_handle.read(cx).version(),
 8712                cx,
 8713            ))
 8714        })
 8715    }
 8716
 8717    async fn handle_lsp_command<T: LspCommand>(
 8718        this: Entity<Self>,
 8719        envelope: TypedEnvelope<T::ProtoRequest>,
 8720        mut cx: AsyncApp,
 8721    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8722    where
 8723        <T::LspRequest as lsp::request::Request>::Params: Send,
 8724        <T::LspRequest as lsp::request::Request>::Result: Send,
 8725    {
 8726        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8727        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8728        let buffer_handle = this.update(&mut cx, |this, cx| {
 8729            this.buffer_store.read(cx).get_existing(buffer_id)
 8730        })?;
 8731        let request = T::from_proto(
 8732            envelope.payload,
 8733            this.clone(),
 8734            buffer_handle.clone(),
 8735            cx.clone(),
 8736        )
 8737        .await?;
 8738        let response = this
 8739            .update(&mut cx, |this, cx| {
 8740                this.request_lsp(
 8741                    buffer_handle.clone(),
 8742                    LanguageServerToQuery::FirstCapable,
 8743                    request,
 8744                    cx,
 8745                )
 8746            })
 8747            .await?;
 8748        this.update(&mut cx, |this, cx| {
 8749            Ok(T::response_to_proto(
 8750                response,
 8751                this,
 8752                sender_id,
 8753                &buffer_handle.read(cx).version(),
 8754                cx,
 8755            ))
 8756        })
 8757    }
 8758
 8759    async fn handle_lsp_query(
 8760        lsp_store: Entity<Self>,
 8761        envelope: TypedEnvelope<proto::LspQuery>,
 8762        mut cx: AsyncApp,
 8763    ) -> Result<proto::Ack> {
 8764        use proto::lsp_query::Request;
 8765        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8766        let lsp_query = envelope.payload;
 8767        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8768        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8769        match lsp_query.request.context("invalid LSP query request")? {
 8770            Request::GetReferences(get_references) => {
 8771                let position = get_references.position.clone().and_then(deserialize_anchor);
 8772                Self::query_lsp_locally::<GetReferences>(
 8773                    lsp_store,
 8774                    server_id,
 8775                    sender_id,
 8776                    lsp_request_id,
 8777                    get_references,
 8778                    position,
 8779                    &mut cx,
 8780                )
 8781                .await?;
 8782            }
 8783            Request::GetDocumentColor(get_document_color) => {
 8784                Self::query_lsp_locally::<GetDocumentColor>(
 8785                    lsp_store,
 8786                    server_id,
 8787                    sender_id,
 8788                    lsp_request_id,
 8789                    get_document_color,
 8790                    None,
 8791                    &mut cx,
 8792                )
 8793                .await?;
 8794            }
 8795            Request::GetFoldingRanges(get_folding_ranges) => {
 8796                Self::query_lsp_locally::<GetFoldingRanges>(
 8797                    lsp_store,
 8798                    server_id,
 8799                    sender_id,
 8800                    lsp_request_id,
 8801                    get_folding_ranges,
 8802                    None,
 8803                    &mut cx,
 8804                )
 8805                .await?;
 8806            }
 8807            Request::GetHover(get_hover) => {
 8808                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8809                Self::query_lsp_locally::<GetHover>(
 8810                    lsp_store,
 8811                    server_id,
 8812                    sender_id,
 8813                    lsp_request_id,
 8814                    get_hover,
 8815                    position,
 8816                    &mut cx,
 8817                )
 8818                .await?;
 8819            }
 8820            Request::GetCodeActions(get_code_actions) => {
 8821                Self::query_lsp_locally::<GetCodeActions>(
 8822                    lsp_store,
 8823                    server_id,
 8824                    sender_id,
 8825                    lsp_request_id,
 8826                    get_code_actions,
 8827                    None,
 8828                    &mut cx,
 8829                )
 8830                .await?;
 8831            }
 8832            Request::GetSignatureHelp(get_signature_help) => {
 8833                let position = get_signature_help
 8834                    .position
 8835                    .clone()
 8836                    .and_then(deserialize_anchor);
 8837                Self::query_lsp_locally::<GetSignatureHelp>(
 8838                    lsp_store,
 8839                    server_id,
 8840                    sender_id,
 8841                    lsp_request_id,
 8842                    get_signature_help,
 8843                    position,
 8844                    &mut cx,
 8845                )
 8846                .await?;
 8847            }
 8848            Request::GetCodeLens(get_code_lens) => {
 8849                Self::query_lsp_locally::<GetCodeLens>(
 8850                    lsp_store,
 8851                    server_id,
 8852                    sender_id,
 8853                    lsp_request_id,
 8854                    get_code_lens,
 8855                    None,
 8856                    &mut cx,
 8857                )
 8858                .await?;
 8859            }
 8860            Request::GetDefinition(get_definition) => {
 8861                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8862                Self::query_lsp_locally::<GetDefinitions>(
 8863                    lsp_store,
 8864                    server_id,
 8865                    sender_id,
 8866                    lsp_request_id,
 8867                    get_definition,
 8868                    position,
 8869                    &mut cx,
 8870                )
 8871                .await?;
 8872            }
 8873            Request::GetDeclaration(get_declaration) => {
 8874                let position = get_declaration
 8875                    .position
 8876                    .clone()
 8877                    .and_then(deserialize_anchor);
 8878                Self::query_lsp_locally::<GetDeclarations>(
 8879                    lsp_store,
 8880                    server_id,
 8881                    sender_id,
 8882                    lsp_request_id,
 8883                    get_declaration,
 8884                    position,
 8885                    &mut cx,
 8886                )
 8887                .await?;
 8888            }
 8889            Request::GetTypeDefinition(get_type_definition) => {
 8890                let position = get_type_definition
 8891                    .position
 8892                    .clone()
 8893                    .and_then(deserialize_anchor);
 8894                Self::query_lsp_locally::<GetTypeDefinitions>(
 8895                    lsp_store,
 8896                    server_id,
 8897                    sender_id,
 8898                    lsp_request_id,
 8899                    get_type_definition,
 8900                    position,
 8901                    &mut cx,
 8902                )
 8903                .await?;
 8904            }
 8905            Request::GetImplementation(get_implementation) => {
 8906                let position = get_implementation
 8907                    .position
 8908                    .clone()
 8909                    .and_then(deserialize_anchor);
 8910                Self::query_lsp_locally::<GetImplementations>(
 8911                    lsp_store,
 8912                    server_id,
 8913                    sender_id,
 8914                    lsp_request_id,
 8915                    get_implementation,
 8916                    position,
 8917                    &mut cx,
 8918                )
 8919                .await?;
 8920            }
 8921            Request::InlayHints(inlay_hints) => {
 8922                let query_start = inlay_hints
 8923                    .start
 8924                    .clone()
 8925                    .and_then(deserialize_anchor)
 8926                    .context("invalid inlay hints range start")?;
 8927                let query_end = inlay_hints
 8928                    .end
 8929                    .clone()
 8930                    .and_then(deserialize_anchor)
 8931                    .context("invalid inlay hints range end")?;
 8932                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8933                    &lsp_store,
 8934                    server_id,
 8935                    lsp_request_id,
 8936                    &inlay_hints,
 8937                    query_start..query_end,
 8938                    &mut cx,
 8939                )
 8940                .await
 8941                .context("preparing inlay hints request")?;
 8942                Self::query_lsp_locally::<InlayHints>(
 8943                    lsp_store,
 8944                    server_id,
 8945                    sender_id,
 8946                    lsp_request_id,
 8947                    inlay_hints,
 8948                    None,
 8949                    &mut cx,
 8950                )
 8951                .await
 8952                .context("querying for inlay hints")?
 8953            }
 8954            //////////////////////////////
 8955            // Below are LSP queries that need to fetch more data,
 8956            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 8957            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8958                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 8959                    &lsp_store,
 8960                    &get_document_diagnostics,
 8961                    &mut cx,
 8962                )
 8963                .await?;
 8964                lsp_store.update(&mut cx, |lsp_store, cx| {
 8965                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8966                    let key = LspKey {
 8967                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8968                        server_queried: server_id,
 8969                    };
 8970                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8971                    ) {
 8972                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8973                            lsp_requests.clear();
 8974                        };
 8975                    }
 8976
 8977                    lsp_data.lsp_requests.entry(key).or_default().insert(
 8978                        lsp_request_id,
 8979                        cx.spawn(async move |lsp_store, cx| {
 8980                            let diagnostics_pull = lsp_store
 8981                                .update(cx, |lsp_store, cx| {
 8982                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8983                                })
 8984                                .ok();
 8985                            if let Some(diagnostics_pull) = diagnostics_pull {
 8986                                match diagnostics_pull.await {
 8987                                    Ok(()) => {}
 8988                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8989                                };
 8990                            }
 8991                        }),
 8992                    );
 8993                });
 8994            }
 8995            Request::SemanticTokens(semantic_tokens) => {
 8996                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 8997                    &lsp_store,
 8998                    &semantic_tokens,
 8999                    &mut cx,
 9000                )
 9001                .await?;
 9002                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9003                lsp_store.update(&mut cx, |lsp_store, cx| {
 9004                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9005                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9006                        let key = LspKey {
 9007                            request_type: TypeId::of::<SemanticTokensFull>(),
 9008                            server_queried: server_id,
 9009                        };
 9010                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9011                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9012                                lsp_requests.clear();
 9013                            };
 9014                        }
 9015
 9016                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9017                            lsp_request_id,
 9018                            cx.spawn(async move |lsp_store, cx| {
 9019                                let tokens_fetch = lsp_store
 9020                                    .update(cx, |lsp_store, cx| {
 9021                                        lsp_store
 9022                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9023                                    })
 9024                                    .ok();
 9025                                if let Some(tokens_fetch) = tokens_fetch {
 9026                                    let new_tokens = tokens_fetch.await;
 9027                                    if let Some(new_tokens) = new_tokens {
 9028                                        lsp_store
 9029                                            .update(cx, |lsp_store, cx| {
 9030                                                let response = new_tokens
 9031                                                    .into_iter()
 9032                                                    .map(|(server_id, response)| {
 9033                                                        (
 9034                                                            server_id.to_proto(),
 9035                                                            SemanticTokensFull::response_to_proto(
 9036                                                                response,
 9037                                                                lsp_store,
 9038                                                                sender_id,
 9039                                                                &buffer_version,
 9040                                                                cx,
 9041                                                            ),
 9042                                                        )
 9043                                                    })
 9044                                                    .collect::<HashMap<_, _>>();
 9045                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9046                                                    project_id,
 9047                                                    lsp_request_id,
 9048                                                    response,
 9049                                                ) {
 9050                                                    Ok(()) => {}
 9051                                                    Err(e) => {
 9052                                                        log::error!(
 9053                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9054                                                        )
 9055                                                    }
 9056                                                }
 9057                                            })
 9058                                            .ok();
 9059                                    }
 9060                                }
 9061                            }),
 9062                        );
 9063                    }
 9064                });
 9065            }
 9066        }
 9067        Ok(proto::Ack {})
 9068    }
 9069
 9070    async fn handle_lsp_query_response(
 9071        lsp_store: Entity<Self>,
 9072        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9073        cx: AsyncApp,
 9074    ) -> Result<()> {
 9075        lsp_store.read_with(&cx, |lsp_store, _| {
 9076            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9077                upstream_client.handle_lsp_response(envelope.clone());
 9078            }
 9079        });
 9080        Ok(())
 9081    }
 9082
 9083    async fn handle_apply_code_action(
 9084        this: Entity<Self>,
 9085        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9086        mut cx: AsyncApp,
 9087    ) -> Result<proto::ApplyCodeActionResponse> {
 9088        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9089        let action =
 9090            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9091        let apply_code_action = this.update(&mut cx, |this, cx| {
 9092            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9093            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9094            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9095        })?;
 9096
 9097        let project_transaction = apply_code_action.await?;
 9098        let project_transaction = this.update(&mut cx, |this, cx| {
 9099            this.buffer_store.update(cx, |buffer_store, cx| {
 9100                buffer_store.serialize_project_transaction_for_peer(
 9101                    project_transaction,
 9102                    sender_id,
 9103                    cx,
 9104                )
 9105            })
 9106        });
 9107        Ok(proto::ApplyCodeActionResponse {
 9108            transaction: Some(project_transaction),
 9109        })
 9110    }
 9111
 9112    async fn handle_register_buffer_with_language_servers(
 9113        this: Entity<Self>,
 9114        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9115        mut cx: AsyncApp,
 9116    ) -> Result<proto::Ack> {
 9117        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9118        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9119        this.update(&mut cx, |this, cx| {
 9120            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9121                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9122                    project_id: upstream_project_id,
 9123                    buffer_id: buffer_id.to_proto(),
 9124                    only_servers: envelope.payload.only_servers,
 9125                });
 9126            }
 9127
 9128            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9129                anyhow::bail!("buffer is not open");
 9130            };
 9131
 9132            let handle = this.register_buffer_with_language_servers(
 9133                &buffer,
 9134                envelope
 9135                    .payload
 9136                    .only_servers
 9137                    .into_iter()
 9138                    .filter_map(|selector| {
 9139                        Some(match selector.selector? {
 9140                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9141                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9142                            }
 9143                            proto::language_server_selector::Selector::Name(name) => {
 9144                                LanguageServerSelector::Name(LanguageServerName(
 9145                                    SharedString::from(name),
 9146                                ))
 9147                            }
 9148                        })
 9149                    })
 9150                    .collect(),
 9151                false,
 9152                cx,
 9153            );
 9154            // Pull diagnostics for the buffer even if it was already registered.
 9155            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9156            // but it's unclear if we need it.
 9157            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9158                .detach();
 9159            this.buffer_store().update(cx, |buffer_store, _| {
 9160                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9161            });
 9162
 9163            Ok(())
 9164        })?;
 9165        Ok(proto::Ack {})
 9166    }
 9167
 9168    async fn handle_rename_project_entry(
 9169        this: Entity<Self>,
 9170        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9171        mut cx: AsyncApp,
 9172    ) -> Result<proto::ProjectEntryResponse> {
 9173        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9174        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9175        let new_path =
 9176            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9177
 9178        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9179            .update(&mut cx, |this, cx| {
 9180                let (worktree, entry) = this
 9181                    .worktree_store
 9182                    .read(cx)
 9183                    .worktree_and_entry_for_id(entry_id, cx)?;
 9184                let new_worktree = this
 9185                    .worktree_store
 9186                    .read(cx)
 9187                    .worktree_for_id(new_worktree_id, cx)?;
 9188                Some((
 9189                    this.worktree_store.clone(),
 9190                    worktree,
 9191                    new_worktree,
 9192                    entry.clone(),
 9193                ))
 9194            })
 9195            .context("worktree not found")?;
 9196        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9197            (worktree.absolutize(&old_entry.path), worktree.id())
 9198        });
 9199        let new_abs_path =
 9200            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9201
 9202        let _transaction = Self::will_rename_entry(
 9203            this.downgrade(),
 9204            old_worktree_id,
 9205            &old_abs_path,
 9206            &new_abs_path,
 9207            old_entry.is_dir(),
 9208            cx.clone(),
 9209        )
 9210        .await;
 9211        let response = WorktreeStore::handle_rename_project_entry(
 9212            worktree_store,
 9213            envelope.payload,
 9214            cx.clone(),
 9215        )
 9216        .await;
 9217        this.read_with(&cx, |this, _| {
 9218            this.did_rename_entry(
 9219                old_worktree_id,
 9220                &old_abs_path,
 9221                &new_abs_path,
 9222                old_entry.is_dir(),
 9223            );
 9224        });
 9225        response
 9226    }
 9227
 9228    async fn handle_update_diagnostic_summary(
 9229        this: Entity<Self>,
 9230        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9231        mut cx: AsyncApp,
 9232    ) -> Result<()> {
 9233        this.update(&mut cx, |lsp_store, cx| {
 9234            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9235            let mut updated_diagnostics_paths = HashMap::default();
 9236            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9237            for message_summary in envelope
 9238                .payload
 9239                .summary
 9240                .into_iter()
 9241                .chain(envelope.payload.more_summaries)
 9242            {
 9243                let project_path = ProjectPath {
 9244                    worktree_id,
 9245                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9246                };
 9247                let path = project_path.path.clone();
 9248                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9249                let summary = DiagnosticSummary {
 9250                    error_count: message_summary.error_count as usize,
 9251                    warning_count: message_summary.warning_count as usize,
 9252                };
 9253
 9254                if summary.is_empty() {
 9255                    if let Some(worktree_summaries) =
 9256                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9257                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9258                    {
 9259                        summaries.remove(&server_id);
 9260                        if summaries.is_empty() {
 9261                            worktree_summaries.remove(&path);
 9262                        }
 9263                    }
 9264                } else {
 9265                    lsp_store
 9266                        .diagnostic_summaries
 9267                        .entry(worktree_id)
 9268                        .or_default()
 9269                        .entry(path)
 9270                        .or_default()
 9271                        .insert(server_id, summary);
 9272                }
 9273
 9274                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9275                    match &mut diagnostics_summary {
 9276                        Some(diagnostics_summary) => {
 9277                            diagnostics_summary
 9278                                .more_summaries
 9279                                .push(proto::DiagnosticSummary {
 9280                                    path: project_path.path.as_ref().to_proto(),
 9281                                    language_server_id: server_id.0 as u64,
 9282                                    error_count: summary.error_count as u32,
 9283                                    warning_count: summary.warning_count as u32,
 9284                                })
 9285                        }
 9286                        None => {
 9287                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9288                                project_id: *project_id,
 9289                                worktree_id: worktree_id.to_proto(),
 9290                                summary: Some(proto::DiagnosticSummary {
 9291                                    path: project_path.path.as_ref().to_proto(),
 9292                                    language_server_id: server_id.0 as u64,
 9293                                    error_count: summary.error_count as u32,
 9294                                    warning_count: summary.warning_count as u32,
 9295                                }),
 9296                                more_summaries: Vec::new(),
 9297                            })
 9298                        }
 9299                    }
 9300                }
 9301                updated_diagnostics_paths
 9302                    .entry(server_id)
 9303                    .or_insert_with(Vec::new)
 9304                    .push(project_path);
 9305            }
 9306
 9307            if let Some((diagnostics_summary, (downstream_client, _))) =
 9308                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9309            {
 9310                downstream_client.send(diagnostics_summary).log_err();
 9311            }
 9312            for (server_id, paths) in updated_diagnostics_paths {
 9313                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9314            }
 9315            Ok(())
 9316        })
 9317    }
 9318
 9319    async fn handle_start_language_server(
 9320        lsp_store: Entity<Self>,
 9321        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9322        mut cx: AsyncApp,
 9323    ) -> Result<()> {
 9324        let server = envelope.payload.server.context("invalid server")?;
 9325        let server_capabilities =
 9326            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9327                .with_context(|| {
 9328                    format!(
 9329                        "incorrect server capabilities {}",
 9330                        envelope.payload.capabilities
 9331                    )
 9332                })?;
 9333        lsp_store.update(&mut cx, |lsp_store, cx| {
 9334            let server_id = LanguageServerId(server.id as usize);
 9335            let server_name = LanguageServerName::from_proto(server.name.clone());
 9336            lsp_store
 9337                .lsp_server_capabilities
 9338                .insert(server_id, server_capabilities);
 9339            lsp_store.language_server_statuses.insert(
 9340                server_id,
 9341                LanguageServerStatus {
 9342                    name: server_name.clone(),
 9343                    server_version: None,
 9344                    pending_work: Default::default(),
 9345                    has_pending_diagnostic_updates: false,
 9346                    progress_tokens: Default::default(),
 9347                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9348                    binary: None,
 9349                    configuration: None,
 9350                    workspace_folders: BTreeSet::new(),
 9351                    process_id: None,
 9352                },
 9353            );
 9354            cx.emit(LspStoreEvent::LanguageServerAdded(
 9355                server_id,
 9356                server_name,
 9357                server.worktree_id.map(WorktreeId::from_proto),
 9358            ));
 9359            cx.notify();
 9360        });
 9361        Ok(())
 9362    }
 9363
 9364    async fn handle_update_language_server(
 9365        lsp_store: Entity<Self>,
 9366        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9367        mut cx: AsyncApp,
 9368    ) -> Result<()> {
 9369        lsp_store.update(&mut cx, |lsp_store, cx| {
 9370            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9371
 9372            match envelope.payload.variant.context("invalid variant")? {
 9373                proto::update_language_server::Variant::WorkStart(payload) => {
 9374                    lsp_store.on_lsp_work_start(
 9375                        language_server_id,
 9376                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9377                            .context("invalid progress token value")?,
 9378                        LanguageServerProgress {
 9379                            title: payload.title,
 9380                            is_disk_based_diagnostics_progress: false,
 9381                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9382                            message: payload.message,
 9383                            percentage: payload.percentage.map(|p| p as usize),
 9384                            last_update_at: cx.background_executor().now(),
 9385                        },
 9386                        cx,
 9387                    );
 9388                }
 9389                proto::update_language_server::Variant::WorkProgress(payload) => {
 9390                    lsp_store.on_lsp_work_progress(
 9391                        language_server_id,
 9392                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9393                            .context("invalid progress token value")?,
 9394                        LanguageServerProgress {
 9395                            title: None,
 9396                            is_disk_based_diagnostics_progress: false,
 9397                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9398                            message: payload.message,
 9399                            percentage: payload.percentage.map(|p| p as usize),
 9400                            last_update_at: cx.background_executor().now(),
 9401                        },
 9402                        cx,
 9403                    );
 9404                }
 9405
 9406                proto::update_language_server::Variant::WorkEnd(payload) => {
 9407                    lsp_store.on_lsp_work_end(
 9408                        language_server_id,
 9409                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9410                            .context("invalid progress token value")?,
 9411                        cx,
 9412                    );
 9413                }
 9414
 9415                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9416                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9417                }
 9418
 9419                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9420                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9421                }
 9422
 9423                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9424                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9425                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9426                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9427                        language_server_id,
 9428                        name: envelope
 9429                            .payload
 9430                            .server_name
 9431                            .map(SharedString::new)
 9432                            .map(LanguageServerName),
 9433                        message: non_lsp,
 9434                    });
 9435                }
 9436            }
 9437
 9438            Ok(())
 9439        })
 9440    }
 9441
 9442    async fn handle_language_server_log(
 9443        this: Entity<Self>,
 9444        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9445        mut cx: AsyncApp,
 9446    ) -> Result<()> {
 9447        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9448        let log_type = envelope
 9449            .payload
 9450            .log_type
 9451            .map(LanguageServerLogType::from_proto)
 9452            .context("invalid language server log type")?;
 9453
 9454        let message = envelope.payload.message;
 9455
 9456        this.update(&mut cx, |_, cx| {
 9457            cx.emit(LspStoreEvent::LanguageServerLog(
 9458                language_server_id,
 9459                log_type,
 9460                message,
 9461            ));
 9462        });
 9463        Ok(())
 9464    }
 9465
 9466    async fn handle_lsp_ext_cancel_flycheck(
 9467        lsp_store: Entity<Self>,
 9468        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9469        cx: AsyncApp,
 9470    ) -> Result<proto::Ack> {
 9471        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9472        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9473            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9474                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9475            } else {
 9476                None
 9477            }
 9478        });
 9479        if let Some(task) = task {
 9480            task.context("handling lsp ext cancel flycheck")?;
 9481        }
 9482
 9483        Ok(proto::Ack {})
 9484    }
 9485
 9486    async fn handle_lsp_ext_run_flycheck(
 9487        lsp_store: Entity<Self>,
 9488        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9489        mut cx: AsyncApp,
 9490    ) -> Result<proto::Ack> {
 9491        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9492        lsp_store.update(&mut cx, |lsp_store, cx| {
 9493            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9494                let text_document = if envelope.payload.current_file_only {
 9495                    let buffer_id = envelope
 9496                        .payload
 9497                        .buffer_id
 9498                        .map(|id| BufferId::new(id))
 9499                        .transpose()?;
 9500                    buffer_id
 9501                        .and_then(|buffer_id| {
 9502                            lsp_store
 9503                                .buffer_store()
 9504                                .read(cx)
 9505                                .get(buffer_id)
 9506                                .and_then(|buffer| {
 9507                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9508                                })
 9509                                .map(|path| make_text_document_identifier(&path))
 9510                        })
 9511                        .transpose()?
 9512                } else {
 9513                    None
 9514                };
 9515                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9516                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9517                )?;
 9518            }
 9519            anyhow::Ok(())
 9520        })?;
 9521
 9522        Ok(proto::Ack {})
 9523    }
 9524
 9525    async fn handle_lsp_ext_clear_flycheck(
 9526        lsp_store: Entity<Self>,
 9527        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9528        cx: AsyncApp,
 9529    ) -> Result<proto::Ack> {
 9530        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9531        lsp_store.read_with(&cx, |lsp_store, _| {
 9532            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9533                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9534            } else {
 9535                None
 9536            }
 9537        });
 9538
 9539        Ok(proto::Ack {})
 9540    }
 9541
 9542    pub fn disk_based_diagnostics_started(
 9543        &mut self,
 9544        language_server_id: LanguageServerId,
 9545        cx: &mut Context<Self>,
 9546    ) {
 9547        if let Some(language_server_status) =
 9548            self.language_server_statuses.get_mut(&language_server_id)
 9549        {
 9550            language_server_status.has_pending_diagnostic_updates = true;
 9551        }
 9552
 9553        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9554        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9555            language_server_id,
 9556            name: self
 9557                .language_server_adapter_for_id(language_server_id)
 9558                .map(|adapter| adapter.name()),
 9559            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9560                Default::default(),
 9561            ),
 9562        })
 9563    }
 9564
 9565    pub fn disk_based_diagnostics_finished(
 9566        &mut self,
 9567        language_server_id: LanguageServerId,
 9568        cx: &mut Context<Self>,
 9569    ) {
 9570        if let Some(language_server_status) =
 9571            self.language_server_statuses.get_mut(&language_server_id)
 9572        {
 9573            language_server_status.has_pending_diagnostic_updates = false;
 9574        }
 9575
 9576        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9577        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9578            language_server_id,
 9579            name: self
 9580                .language_server_adapter_for_id(language_server_id)
 9581                .map(|adapter| adapter.name()),
 9582            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9583                Default::default(),
 9584            ),
 9585        })
 9586    }
 9587
 9588    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9589    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9590    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9591    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9592    // the language server might take some time to publish diagnostics.
 9593    fn simulate_disk_based_diagnostics_events_if_needed(
 9594        &mut self,
 9595        language_server_id: LanguageServerId,
 9596        cx: &mut Context<Self>,
 9597    ) {
 9598        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9599
 9600        let Some(LanguageServerState::Running {
 9601            simulate_disk_based_diagnostics_completion,
 9602            adapter,
 9603            ..
 9604        }) = self
 9605            .as_local_mut()
 9606            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9607        else {
 9608            return;
 9609        };
 9610
 9611        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9612            return;
 9613        }
 9614
 9615        let prev_task =
 9616            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9617                cx.background_executor()
 9618                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9619                    .await;
 9620
 9621                this.update(cx, |this, cx| {
 9622                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9623
 9624                    if let Some(LanguageServerState::Running {
 9625                        simulate_disk_based_diagnostics_completion,
 9626                        ..
 9627                    }) = this.as_local_mut().and_then(|local_store| {
 9628                        local_store.language_servers.get_mut(&language_server_id)
 9629                    }) {
 9630                        *simulate_disk_based_diagnostics_completion = None;
 9631                    }
 9632                })
 9633                .ok();
 9634            }));
 9635
 9636        if prev_task.is_none() {
 9637            self.disk_based_diagnostics_started(language_server_id, cx);
 9638        }
 9639    }
 9640
 9641    pub fn language_server_statuses(
 9642        &self,
 9643    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9644        self.language_server_statuses
 9645            .iter()
 9646            .map(|(key, value)| (*key, value))
 9647    }
 9648
 9649    pub(super) fn did_rename_entry(
 9650        &self,
 9651        worktree_id: WorktreeId,
 9652        old_path: &Path,
 9653        new_path: &Path,
 9654        is_dir: bool,
 9655    ) {
 9656        maybe!({
 9657            let local_store = self.as_local()?;
 9658
 9659            let old_uri = lsp::Uri::from_file_path(old_path)
 9660                .ok()
 9661                .map(|uri| uri.to_string())?;
 9662            let new_uri = lsp::Uri::from_file_path(new_path)
 9663                .ok()
 9664                .map(|uri| uri.to_string())?;
 9665
 9666            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9667                let Some(filter) = local_store
 9668                    .language_server_paths_watched_for_rename
 9669                    .get(&language_server.server_id())
 9670                else {
 9671                    continue;
 9672                };
 9673
 9674                if filter.should_send_did_rename(&old_uri, is_dir) {
 9675                    language_server
 9676                        .notify::<DidRenameFiles>(RenameFilesParams {
 9677                            files: vec![FileRename {
 9678                                old_uri: old_uri.clone(),
 9679                                new_uri: new_uri.clone(),
 9680                            }],
 9681                        })
 9682                        .ok();
 9683                }
 9684            }
 9685            Some(())
 9686        });
 9687    }
 9688
 9689    pub(super) fn will_rename_entry(
 9690        this: WeakEntity<Self>,
 9691        worktree_id: WorktreeId,
 9692        old_path: &Path,
 9693        new_path: &Path,
 9694        is_dir: bool,
 9695        cx: AsyncApp,
 9696    ) -> Task<ProjectTransaction> {
 9697        let old_uri = lsp::Uri::from_file_path(old_path)
 9698            .ok()
 9699            .map(|uri| uri.to_string());
 9700        let new_uri = lsp::Uri::from_file_path(new_path)
 9701            .ok()
 9702            .map(|uri| uri.to_string());
 9703        cx.spawn(async move |cx| {
 9704            let mut tasks = vec![];
 9705            this.update(cx, |this, cx| {
 9706                let local_store = this.as_local()?;
 9707                let old_uri = old_uri?;
 9708                let new_uri = new_uri?;
 9709                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9710                    let Some(filter) = local_store
 9711                        .language_server_paths_watched_for_rename
 9712                        .get(&language_server.server_id())
 9713                    else {
 9714                        continue;
 9715                    };
 9716
 9717                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9718                        continue;
 9719                    }
 9720                    let request_timeout = ProjectSettings::get_global(cx)
 9721                        .global_lsp_settings
 9722                        .get_request_timeout();
 9723
 9724                    let apply_edit = cx.spawn({
 9725                        let old_uri = old_uri.clone();
 9726                        let new_uri = new_uri.clone();
 9727                        let language_server = language_server.clone();
 9728                        async move |this, cx| {
 9729                            let edit = language_server
 9730                                .request::<WillRenameFiles>(
 9731                                    RenameFilesParams {
 9732                                        files: vec![FileRename { old_uri, new_uri }],
 9733                                    },
 9734                                    request_timeout,
 9735                                )
 9736                                .await
 9737                                .into_response()
 9738                                .context("will rename files")
 9739                                .log_err()
 9740                                .flatten()?;
 9741
 9742                            LocalLspStore::deserialize_workspace_edit(
 9743                                this.upgrade()?,
 9744                                edit,
 9745                                false,
 9746                                language_server.clone(),
 9747                                cx,
 9748                            )
 9749                            .await
 9750                            .ok()
 9751                        }
 9752                    });
 9753                    tasks.push(apply_edit);
 9754                }
 9755                Some(())
 9756            })
 9757            .ok()
 9758            .flatten();
 9759            let mut merged_transaction = ProjectTransaction::default();
 9760            for task in tasks {
 9761                // Await on tasks sequentially so that the order of application of edits is deterministic
 9762                // (at least with regards to the order of registration of language servers)
 9763                if let Some(transaction) = task.await {
 9764                    for (buffer, buffer_transaction) in transaction.0 {
 9765                        merged_transaction.0.insert(buffer, buffer_transaction);
 9766                    }
 9767                }
 9768            }
 9769            merged_transaction
 9770        })
 9771    }
 9772
 9773    fn lsp_notify_abs_paths_changed(
 9774        &mut self,
 9775        server_id: LanguageServerId,
 9776        changes: Vec<PathEvent>,
 9777    ) {
 9778        maybe!({
 9779            let server = self.language_server_for_id(server_id)?;
 9780            let changes = changes
 9781                .into_iter()
 9782                .filter_map(|event| {
 9783                    let typ = match event.kind? {
 9784                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9785                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9786                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9787                    };
 9788                    Some(lsp::FileEvent {
 9789                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9790                        typ,
 9791                    })
 9792                })
 9793                .collect::<Vec<_>>();
 9794            if !changes.is_empty() {
 9795                server
 9796                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9797                        lsp::DidChangeWatchedFilesParams { changes },
 9798                    )
 9799                    .ok();
 9800            }
 9801            Some(())
 9802        });
 9803    }
 9804
 9805    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9806        self.as_local()?.language_server_for_id(id)
 9807    }
 9808
 9809    fn on_lsp_progress(
 9810        &mut self,
 9811        progress_params: lsp::ProgressParams,
 9812        language_server_id: LanguageServerId,
 9813        disk_based_diagnostics_progress_token: Option<String>,
 9814        cx: &mut Context<Self>,
 9815    ) {
 9816        match progress_params.value {
 9817            lsp::ProgressParamsValue::WorkDone(progress) => {
 9818                self.handle_work_done_progress(
 9819                    progress,
 9820                    language_server_id,
 9821                    disk_based_diagnostics_progress_token,
 9822                    ProgressToken::from_lsp(progress_params.token),
 9823                    cx,
 9824                );
 9825            }
 9826            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9827                let registration_id = match progress_params.token {
 9828                    lsp::NumberOrString::Number(_) => None,
 9829                    lsp::NumberOrString::String(token) => token
 9830                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9831                        .map(|(_, id)| id.to_owned()),
 9832                };
 9833                if let Some(LanguageServerState::Running {
 9834                    workspace_diagnostics_refresh_tasks,
 9835                    ..
 9836                }) = self
 9837                    .as_local_mut()
 9838                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9839                    && let Some(workspace_diagnostics) =
 9840                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9841                {
 9842                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9843                    self.apply_workspace_diagnostic_report(
 9844                        language_server_id,
 9845                        report,
 9846                        registration_id.map(SharedString::from),
 9847                        cx,
 9848                    )
 9849                }
 9850            }
 9851        }
 9852    }
 9853
 9854    fn handle_work_done_progress(
 9855        &mut self,
 9856        progress: lsp::WorkDoneProgress,
 9857        language_server_id: LanguageServerId,
 9858        disk_based_diagnostics_progress_token: Option<String>,
 9859        token: ProgressToken,
 9860        cx: &mut Context<Self>,
 9861    ) {
 9862        let language_server_status =
 9863            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9864                status
 9865            } else {
 9866                return;
 9867            };
 9868
 9869        if !language_server_status.progress_tokens.contains(&token) {
 9870            return;
 9871        }
 9872
 9873        let is_disk_based_diagnostics_progress =
 9874            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9875                (&disk_based_diagnostics_progress_token, &token)
 9876            {
 9877                token.starts_with(disk_based_token)
 9878            } else {
 9879                false
 9880            };
 9881
 9882        match progress {
 9883            lsp::WorkDoneProgress::Begin(report) => {
 9884                if is_disk_based_diagnostics_progress {
 9885                    self.disk_based_diagnostics_started(language_server_id, cx);
 9886                }
 9887                self.on_lsp_work_start(
 9888                    language_server_id,
 9889                    token.clone(),
 9890                    LanguageServerProgress {
 9891                        title: Some(report.title),
 9892                        is_disk_based_diagnostics_progress,
 9893                        is_cancellable: report.cancellable.unwrap_or(false),
 9894                        message: report.message.clone(),
 9895                        percentage: report.percentage.map(|p| p as usize),
 9896                        last_update_at: cx.background_executor().now(),
 9897                    },
 9898                    cx,
 9899                );
 9900            }
 9901            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9902                language_server_id,
 9903                token,
 9904                LanguageServerProgress {
 9905                    title: None,
 9906                    is_disk_based_diagnostics_progress,
 9907                    is_cancellable: report.cancellable.unwrap_or(false),
 9908                    message: report.message,
 9909                    percentage: report.percentage.map(|p| p as usize),
 9910                    last_update_at: cx.background_executor().now(),
 9911                },
 9912                cx,
 9913            ),
 9914            lsp::WorkDoneProgress::End(_) => {
 9915                language_server_status.progress_tokens.remove(&token);
 9916                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9917                if is_disk_based_diagnostics_progress {
 9918                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9919                }
 9920            }
 9921        }
 9922    }
 9923
 9924    fn on_lsp_work_start(
 9925        &mut self,
 9926        language_server_id: LanguageServerId,
 9927        token: ProgressToken,
 9928        progress: LanguageServerProgress,
 9929        cx: &mut Context<Self>,
 9930    ) {
 9931        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9932            status.pending_work.insert(token.clone(), progress.clone());
 9933            cx.notify();
 9934        }
 9935        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9936            language_server_id,
 9937            name: self
 9938                .language_server_adapter_for_id(language_server_id)
 9939                .map(|adapter| adapter.name()),
 9940            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9941                token: Some(token.to_proto()),
 9942                title: progress.title,
 9943                message: progress.message,
 9944                percentage: progress.percentage.map(|p| p as u32),
 9945                is_cancellable: Some(progress.is_cancellable),
 9946            }),
 9947        })
 9948    }
 9949
 9950    fn on_lsp_work_progress(
 9951        &mut self,
 9952        language_server_id: LanguageServerId,
 9953        token: ProgressToken,
 9954        progress: LanguageServerProgress,
 9955        cx: &mut Context<Self>,
 9956    ) {
 9957        let mut did_update = false;
 9958        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9959            match status.pending_work.entry(token.clone()) {
 9960                btree_map::Entry::Vacant(entry) => {
 9961                    entry.insert(progress.clone());
 9962                    did_update = true;
 9963                }
 9964                btree_map::Entry::Occupied(mut entry) => {
 9965                    let entry = entry.get_mut();
 9966                    if (progress.last_update_at - entry.last_update_at)
 9967                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9968                    {
 9969                        entry.last_update_at = progress.last_update_at;
 9970                        if progress.message.is_some() {
 9971                            entry.message = progress.message.clone();
 9972                        }
 9973                        if progress.percentage.is_some() {
 9974                            entry.percentage = progress.percentage;
 9975                        }
 9976                        if progress.is_cancellable != entry.is_cancellable {
 9977                            entry.is_cancellable = progress.is_cancellable;
 9978                        }
 9979                        did_update = true;
 9980                    }
 9981                }
 9982            }
 9983        }
 9984
 9985        if did_update {
 9986            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9987                language_server_id,
 9988                name: self
 9989                    .language_server_adapter_for_id(language_server_id)
 9990                    .map(|adapter| adapter.name()),
 9991                message: proto::update_language_server::Variant::WorkProgress(
 9992                    proto::LspWorkProgress {
 9993                        token: Some(token.to_proto()),
 9994                        message: progress.message,
 9995                        percentage: progress.percentage.map(|p| p as u32),
 9996                        is_cancellable: Some(progress.is_cancellable),
 9997                    },
 9998                ),
 9999            })
10000        }
10001    }
10002
10003    fn on_lsp_work_end(
10004        &mut self,
10005        language_server_id: LanguageServerId,
10006        token: ProgressToken,
10007        cx: &mut Context<Self>,
10008    ) {
10009        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10010            if let Some(work) = status.pending_work.remove(&token)
10011                && !work.is_disk_based_diagnostics_progress
10012            {
10013                cx.emit(LspStoreEvent::RefreshInlayHints {
10014                    server_id: language_server_id,
10015                    request_id: None,
10016                });
10017            }
10018            cx.notify();
10019        }
10020
10021        cx.emit(LspStoreEvent::LanguageServerUpdate {
10022            language_server_id,
10023            name: self
10024                .language_server_adapter_for_id(language_server_id)
10025                .map(|adapter| adapter.name()),
10026            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10027                token: Some(token.to_proto()),
10028            }),
10029        })
10030    }
10031
10032    pub async fn handle_resolve_completion_documentation(
10033        this: Entity<Self>,
10034        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10035        mut cx: AsyncApp,
10036    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10037        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10038
10039        let completion = this
10040            .read_with(&cx, |this, cx| {
10041                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10042                let server = this
10043                    .language_server_for_id(id)
10044                    .with_context(|| format!("No language server {id}"))?;
10045
10046                let request_timeout = ProjectSettings::get_global(cx)
10047                    .global_lsp_settings
10048                    .get_request_timeout();
10049
10050                anyhow::Ok(cx.background_spawn(async move {
10051                    let can_resolve = server
10052                        .capabilities()
10053                        .completion_provider
10054                        .as_ref()
10055                        .and_then(|options| options.resolve_provider)
10056                        .unwrap_or(false);
10057                    if can_resolve {
10058                        server
10059                            .request::<lsp::request::ResolveCompletionItem>(
10060                                lsp_completion,
10061                                request_timeout,
10062                            )
10063                            .await
10064                            .into_response()
10065                            .context("resolve completion item")
10066                    } else {
10067                        anyhow::Ok(lsp_completion)
10068                    }
10069                }))
10070            })?
10071            .await?;
10072
10073        let mut documentation_is_markdown = false;
10074        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10075        let documentation = match completion.documentation {
10076            Some(lsp::Documentation::String(text)) => text,
10077
10078            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10079                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10080                value
10081            }
10082
10083            _ => String::new(),
10084        };
10085
10086        // If we have a new buffer_id, that means we're talking to a new client
10087        // and want to check for new text_edits in the completion too.
10088        let mut old_replace_start = None;
10089        let mut old_replace_end = None;
10090        let mut old_insert_start = None;
10091        let mut old_insert_end = None;
10092        let mut new_text = String::default();
10093        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10094            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10095                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10096                anyhow::Ok(buffer.read(cx).snapshot())
10097            })?;
10098
10099            if let Some(text_edit) = completion.text_edit.as_ref() {
10100                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10101
10102                if let Some(mut edit) = edit {
10103                    LineEnding::normalize(&mut edit.new_text);
10104
10105                    new_text = edit.new_text;
10106                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10107                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10108                    if let Some(insert_range) = edit.insert_range {
10109                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10110                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10111                    }
10112                }
10113            }
10114        }
10115
10116        Ok(proto::ResolveCompletionDocumentationResponse {
10117            documentation,
10118            documentation_is_markdown,
10119            old_replace_start,
10120            old_replace_end,
10121            new_text,
10122            lsp_completion,
10123            old_insert_start,
10124            old_insert_end,
10125        })
10126    }
10127
10128    async fn handle_on_type_formatting(
10129        this: Entity<Self>,
10130        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10131        mut cx: AsyncApp,
10132    ) -> Result<proto::OnTypeFormattingResponse> {
10133        let on_type_formatting = this.update(&mut cx, |this, cx| {
10134            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10135            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10136            let position = envelope
10137                .payload
10138                .position
10139                .and_then(deserialize_anchor)
10140                .context("invalid position")?;
10141            anyhow::Ok(this.apply_on_type_formatting(
10142                buffer,
10143                position,
10144                envelope.payload.trigger.clone(),
10145                cx,
10146            ))
10147        })?;
10148
10149        let transaction = on_type_formatting
10150            .await?
10151            .as_ref()
10152            .map(language::proto::serialize_transaction);
10153        Ok(proto::OnTypeFormattingResponse { transaction })
10154    }
10155
10156    async fn handle_pull_workspace_diagnostics(
10157        lsp_store: Entity<Self>,
10158        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10159        mut cx: AsyncApp,
10160    ) -> Result<proto::Ack> {
10161        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10162        lsp_store.update(&mut cx, |lsp_store, _| {
10163            lsp_store.pull_workspace_diagnostics(server_id);
10164        });
10165        Ok(proto::Ack {})
10166    }
10167
10168    async fn handle_open_buffer_for_symbol(
10169        this: Entity<Self>,
10170        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10171        mut cx: AsyncApp,
10172    ) -> Result<proto::OpenBufferForSymbolResponse> {
10173        let peer_id = envelope.original_sender_id().unwrap_or_default();
10174        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10175        let symbol = Self::deserialize_symbol(symbol)?;
10176        this.read_with(&cx, |this, _| {
10177            if let SymbolLocation::OutsideProject {
10178                abs_path,
10179                signature,
10180            } = &symbol.path
10181            {
10182                let new_signature = this.symbol_signature(&abs_path);
10183                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10184            }
10185            Ok(())
10186        })?;
10187        let buffer = this
10188            .update(&mut cx, |this, cx| {
10189                this.open_buffer_for_symbol(
10190                    &Symbol {
10191                        language_server_name: symbol.language_server_name,
10192                        source_worktree_id: symbol.source_worktree_id,
10193                        source_language_server_id: symbol.source_language_server_id,
10194                        path: symbol.path,
10195                        name: symbol.name,
10196                        kind: symbol.kind,
10197                        range: symbol.range,
10198                        label: CodeLabel::default(),
10199                        container_name: symbol.container_name,
10200                    },
10201                    cx,
10202                )
10203            })
10204            .await?;
10205
10206        this.update(&mut cx, |this, cx| {
10207            let is_private = buffer
10208                .read(cx)
10209                .file()
10210                .map(|f| f.is_private())
10211                .unwrap_or_default();
10212            if is_private {
10213                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10214            } else {
10215                this.buffer_store
10216                    .update(cx, |buffer_store, cx| {
10217                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10218                    })
10219                    .detach_and_log_err(cx);
10220                let buffer_id = buffer.read(cx).remote_id().to_proto();
10221                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10222            }
10223        })
10224    }
10225
10226    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10227        let mut hasher = Sha256::new();
10228        hasher.update(abs_path.to_string_lossy().as_bytes());
10229        hasher.update(self.nonce.to_be_bytes());
10230        hasher.finalize().as_slice().try_into().unwrap()
10231    }
10232
10233    pub async fn handle_get_project_symbols(
10234        this: Entity<Self>,
10235        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10236        mut cx: AsyncApp,
10237    ) -> Result<proto::GetProjectSymbolsResponse> {
10238        let symbols = this
10239            .update(&mut cx, |this, cx| {
10240                this.symbols(&envelope.payload.query, cx)
10241            })
10242            .await?;
10243
10244        Ok(proto::GetProjectSymbolsResponse {
10245            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10246        })
10247    }
10248
10249    pub async fn handle_restart_language_servers(
10250        this: Entity<Self>,
10251        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10252        mut cx: AsyncApp,
10253    ) -> Result<proto::Ack> {
10254        this.update(&mut cx, |lsp_store, cx| {
10255            let buffers =
10256                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10257            lsp_store.restart_language_servers_for_buffers(
10258                buffers,
10259                envelope
10260                    .payload
10261                    .only_servers
10262                    .into_iter()
10263                    .filter_map(|selector| {
10264                        Some(match selector.selector? {
10265                            proto::language_server_selector::Selector::ServerId(server_id) => {
10266                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10267                            }
10268                            proto::language_server_selector::Selector::Name(name) => {
10269                                LanguageServerSelector::Name(LanguageServerName(
10270                                    SharedString::from(name),
10271                                ))
10272                            }
10273                        })
10274                    })
10275                    .collect(),
10276                cx,
10277            );
10278        });
10279
10280        Ok(proto::Ack {})
10281    }
10282
10283    pub async fn handle_stop_language_servers(
10284        lsp_store: Entity<Self>,
10285        envelope: TypedEnvelope<proto::StopLanguageServers>,
10286        mut cx: AsyncApp,
10287    ) -> Result<proto::Ack> {
10288        lsp_store.update(&mut cx, |lsp_store, cx| {
10289            if envelope.payload.all
10290                && envelope.payload.also_servers.is_empty()
10291                && envelope.payload.buffer_ids.is_empty()
10292            {
10293                lsp_store.stop_all_language_servers(cx);
10294            } else {
10295                let buffers =
10296                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10297                lsp_store
10298                    .stop_language_servers_for_buffers(
10299                        buffers,
10300                        envelope
10301                            .payload
10302                            .also_servers
10303                            .into_iter()
10304                            .filter_map(|selector| {
10305                                Some(match selector.selector? {
10306                                    proto::language_server_selector::Selector::ServerId(
10307                                        server_id,
10308                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10309                                        server_id,
10310                                    )),
10311                                    proto::language_server_selector::Selector::Name(name) => {
10312                                        LanguageServerSelector::Name(LanguageServerName(
10313                                            SharedString::from(name),
10314                                        ))
10315                                    }
10316                                })
10317                            })
10318                            .collect(),
10319                        cx,
10320                    )
10321                    .detach_and_log_err(cx);
10322            }
10323        });
10324
10325        Ok(proto::Ack {})
10326    }
10327
10328    pub async fn handle_cancel_language_server_work(
10329        lsp_store: Entity<Self>,
10330        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10331        mut cx: AsyncApp,
10332    ) -> Result<proto::Ack> {
10333        lsp_store.update(&mut cx, |lsp_store, cx| {
10334            if let Some(work) = envelope.payload.work {
10335                match work {
10336                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10337                        let buffers =
10338                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10339                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10340                    }
10341                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10342                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10343                        let token = work
10344                            .token
10345                            .map(|token| {
10346                                ProgressToken::from_proto(token)
10347                                    .context("invalid work progress token")
10348                            })
10349                            .transpose()?;
10350                        lsp_store.cancel_language_server_work(server_id, token, cx);
10351                    }
10352                }
10353            }
10354            anyhow::Ok(())
10355        })?;
10356
10357        Ok(proto::Ack {})
10358    }
10359
10360    fn buffer_ids_to_buffers(
10361        &mut self,
10362        buffer_ids: impl Iterator<Item = u64>,
10363        cx: &mut Context<Self>,
10364    ) -> Vec<Entity<Buffer>> {
10365        buffer_ids
10366            .into_iter()
10367            .flat_map(|buffer_id| {
10368                self.buffer_store
10369                    .read(cx)
10370                    .get(BufferId::new(buffer_id).log_err()?)
10371            })
10372            .collect::<Vec<_>>()
10373    }
10374
10375    async fn handle_apply_additional_edits_for_completion(
10376        this: Entity<Self>,
10377        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10378        mut cx: AsyncApp,
10379    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10380        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10381            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10382            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10383            let completion = Self::deserialize_completion(
10384                envelope.payload.completion.context("invalid completion")?,
10385            )?;
10386            anyhow::Ok((buffer, completion))
10387        })?;
10388
10389        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10390            this.apply_additional_edits_for_completion(
10391                buffer,
10392                Rc::new(RefCell::new(Box::new([Completion {
10393                    replace_range: completion.replace_range,
10394                    new_text: completion.new_text,
10395                    source: completion.source,
10396                    documentation: None,
10397                    label: CodeLabel::default(),
10398                    match_start: None,
10399                    snippet_deduplication_key: None,
10400                    insert_text_mode: None,
10401                    icon_path: None,
10402                    confirm: None,
10403                }]))),
10404                0,
10405                false,
10406                cx,
10407            )
10408        });
10409
10410        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10411            transaction: apply_additional_edits
10412                .await?
10413                .as_ref()
10414                .map(language::proto::serialize_transaction),
10415        })
10416    }
10417
10418    pub fn last_formatting_failure(&self) -> Option<&str> {
10419        self.last_formatting_failure.as_deref()
10420    }
10421
10422    pub fn reset_last_formatting_failure(&mut self) {
10423        self.last_formatting_failure = None;
10424    }
10425
10426    pub fn environment_for_buffer(
10427        &self,
10428        buffer: &Entity<Buffer>,
10429        cx: &mut Context<Self>,
10430    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10431        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10432            environment.update(cx, |env, cx| {
10433                env.buffer_environment(buffer, &self.worktree_store, cx)
10434            })
10435        } else {
10436            Task::ready(None).shared()
10437        }
10438    }
10439
10440    pub fn format(
10441        &mut self,
10442        buffers: HashSet<Entity<Buffer>>,
10443        target: LspFormatTarget,
10444        push_to_history: bool,
10445        trigger: FormatTrigger,
10446        cx: &mut Context<Self>,
10447    ) -> Task<anyhow::Result<ProjectTransaction>> {
10448        let logger = zlog::scoped!("format");
10449        if self.as_local().is_some() {
10450            zlog::trace!(logger => "Formatting locally");
10451            let logger = zlog::scoped!(logger => "local");
10452            let buffers = buffers
10453                .into_iter()
10454                .map(|buffer_handle| {
10455                    let buffer = buffer_handle.read(cx);
10456                    let buffer_abs_path = File::from_dyn(buffer.file())
10457                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10458
10459                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10460                })
10461                .collect::<Vec<_>>();
10462
10463            cx.spawn(async move |lsp_store, cx| {
10464                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10465
10466                for (handle, abs_path, id) in buffers {
10467                    let env = lsp_store
10468                        .update(cx, |lsp_store, cx| {
10469                            lsp_store.environment_for_buffer(&handle, cx)
10470                        })?
10471                        .await;
10472
10473                    let ranges = match &target {
10474                        LspFormatTarget::Buffers => None,
10475                        LspFormatTarget::Ranges(ranges) => {
10476                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10477                        }
10478                    };
10479
10480                    formattable_buffers.push(FormattableBuffer {
10481                        handle,
10482                        abs_path,
10483                        env,
10484                        ranges,
10485                    });
10486                }
10487                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10488
10489                let format_timer = zlog::time!(logger => "Formatting buffers");
10490                let result = LocalLspStore::format_locally(
10491                    lsp_store.clone(),
10492                    formattable_buffers,
10493                    push_to_history,
10494                    trigger,
10495                    logger,
10496                    cx,
10497                )
10498                .await;
10499                format_timer.end();
10500
10501                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10502
10503                lsp_store.update(cx, |lsp_store, _| {
10504                    lsp_store.update_last_formatting_failure(&result);
10505                })?;
10506
10507                result
10508            })
10509        } else if let Some((client, project_id)) = self.upstream_client() {
10510            zlog::trace!(logger => "Formatting remotely");
10511            let logger = zlog::scoped!(logger => "remote");
10512
10513            let buffer_ranges = match &target {
10514                LspFormatTarget::Buffers => Vec::new(),
10515                LspFormatTarget::Ranges(ranges) => ranges
10516                    .iter()
10517                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10518                        buffer_id: buffer_id.to_proto(),
10519                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10520                    })
10521                    .collect(),
10522            };
10523
10524            let buffer_store = self.buffer_store();
10525            cx.spawn(async move |lsp_store, cx| {
10526                zlog::trace!(logger => "Sending remote format request");
10527                let request_timer = zlog::time!(logger => "remote format request");
10528                let result = client
10529                    .request(proto::FormatBuffers {
10530                        project_id,
10531                        trigger: trigger as i32,
10532                        buffer_ids: buffers
10533                            .iter()
10534                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10535                            .collect(),
10536                        buffer_ranges,
10537                    })
10538                    .await
10539                    .and_then(|result| result.transaction.context("missing transaction"));
10540                request_timer.end();
10541
10542                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10543
10544                lsp_store.update(cx, |lsp_store, _| {
10545                    lsp_store.update_last_formatting_failure(&result);
10546                })?;
10547
10548                let transaction_response = result?;
10549                let _timer = zlog::time!(logger => "deserializing project transaction");
10550                buffer_store
10551                    .update(cx, |buffer_store, cx| {
10552                        buffer_store.deserialize_project_transaction(
10553                            transaction_response,
10554                            push_to_history,
10555                            cx,
10556                        )
10557                    })
10558                    .await
10559            })
10560        } else {
10561            zlog::trace!(logger => "Not formatting");
10562            Task::ready(Ok(ProjectTransaction::default()))
10563        }
10564    }
10565
10566    async fn handle_format_buffers(
10567        this: Entity<Self>,
10568        envelope: TypedEnvelope<proto::FormatBuffers>,
10569        mut cx: AsyncApp,
10570    ) -> Result<proto::FormatBuffersResponse> {
10571        let sender_id = envelope.original_sender_id().unwrap_or_default();
10572        let format = this.update(&mut cx, |this, cx| {
10573            let mut buffers = HashSet::default();
10574            for buffer_id in &envelope.payload.buffer_ids {
10575                let buffer_id = BufferId::new(*buffer_id)?;
10576                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10577            }
10578
10579            let target = if envelope.payload.buffer_ranges.is_empty() {
10580                LspFormatTarget::Buffers
10581            } else {
10582                let mut ranges_map = BTreeMap::new();
10583                for buffer_range in &envelope.payload.buffer_ranges {
10584                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10585                    let ranges: Result<Vec<_>> = buffer_range
10586                        .ranges
10587                        .iter()
10588                        .map(|range| {
10589                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10590                        })
10591                        .collect();
10592                    ranges_map.insert(buffer_id, ranges?);
10593                }
10594                LspFormatTarget::Ranges(ranges_map)
10595            };
10596
10597            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10598            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10599        })?;
10600
10601        let project_transaction = format.await?;
10602        let project_transaction = this.update(&mut cx, |this, cx| {
10603            this.buffer_store.update(cx, |buffer_store, cx| {
10604                buffer_store.serialize_project_transaction_for_peer(
10605                    project_transaction,
10606                    sender_id,
10607                    cx,
10608                )
10609            })
10610        });
10611        Ok(proto::FormatBuffersResponse {
10612            transaction: Some(project_transaction),
10613        })
10614    }
10615
10616    async fn handle_apply_code_action_kind(
10617        this: Entity<Self>,
10618        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10619        mut cx: AsyncApp,
10620    ) -> Result<proto::ApplyCodeActionKindResponse> {
10621        let sender_id = envelope.original_sender_id().unwrap_or_default();
10622        let format = this.update(&mut cx, |this, cx| {
10623            let mut buffers = HashSet::default();
10624            for buffer_id in &envelope.payload.buffer_ids {
10625                let buffer_id = BufferId::new(*buffer_id)?;
10626                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10627            }
10628            let kind = match envelope.payload.kind.as_str() {
10629                "" => CodeActionKind::EMPTY,
10630                "quickfix" => CodeActionKind::QUICKFIX,
10631                "refactor" => CodeActionKind::REFACTOR,
10632                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10633                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10634                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10635                "source" => CodeActionKind::SOURCE,
10636                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10637                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10638                _ => anyhow::bail!(
10639                    "Invalid code action kind {}",
10640                    envelope.payload.kind.as_str()
10641                ),
10642            };
10643            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10644        })?;
10645
10646        let project_transaction = format.await?;
10647        let project_transaction = this.update(&mut cx, |this, cx| {
10648            this.buffer_store.update(cx, |buffer_store, cx| {
10649                buffer_store.serialize_project_transaction_for_peer(
10650                    project_transaction,
10651                    sender_id,
10652                    cx,
10653                )
10654            })
10655        });
10656        Ok(proto::ApplyCodeActionKindResponse {
10657            transaction: Some(project_transaction),
10658        })
10659    }
10660
10661    async fn shutdown_language_server(
10662        server_state: Option<LanguageServerState>,
10663        name: LanguageServerName,
10664        cx: &mut AsyncApp,
10665    ) {
10666        let server = match server_state {
10667            Some(LanguageServerState::Starting { startup, .. }) => {
10668                let mut timer = cx
10669                    .background_executor()
10670                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10671                    .fuse();
10672
10673                select! {
10674                    server = startup.fuse() => server,
10675                    () = timer => {
10676                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10677                        None
10678                    },
10679                }
10680            }
10681
10682            Some(LanguageServerState::Running { server, .. }) => Some(server),
10683
10684            None => None,
10685        };
10686
10687        let Some(server) = server else { return };
10688        if let Some(shutdown) = server.shutdown() {
10689            shutdown.await;
10690        }
10691    }
10692
10693    // Returns a list of all of the worktrees which no longer have a language server and the root path
10694    // for the stopped server
10695    fn stop_local_language_server(
10696        &mut self,
10697        server_id: LanguageServerId,
10698        cx: &mut Context<Self>,
10699    ) -> Task<()> {
10700        let local = match &mut self.mode {
10701            LspStoreMode::Local(local) => local,
10702            _ => {
10703                return Task::ready(());
10704            }
10705        };
10706
10707        // Remove this server ID from all entries in the given worktree.
10708        local
10709            .language_server_ids
10710            .retain(|_, state| state.id != server_id);
10711        self.buffer_store.update(cx, |buffer_store, cx| {
10712            for buffer in buffer_store.buffers() {
10713                buffer.update(cx, |buffer, cx| {
10714                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10715                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10716                });
10717            }
10718        });
10719
10720        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10721            summaries.retain(|path, summaries_by_server_id| {
10722                if summaries_by_server_id.remove(&server_id).is_some() {
10723                    if let Some((client, project_id)) = self.downstream_client.clone() {
10724                        client
10725                            .send(proto::UpdateDiagnosticSummary {
10726                                project_id,
10727                                worktree_id: worktree_id.to_proto(),
10728                                summary: Some(proto::DiagnosticSummary {
10729                                    path: path.as_ref().to_proto(),
10730                                    language_server_id: server_id.0 as u64,
10731                                    error_count: 0,
10732                                    warning_count: 0,
10733                                }),
10734                                more_summaries: Vec::new(),
10735                            })
10736                            .log_err();
10737                    }
10738                    !summaries_by_server_id.is_empty()
10739                } else {
10740                    true
10741                }
10742            });
10743        }
10744
10745        let local = self.as_local_mut().unwrap();
10746        for diagnostics in local.diagnostics.values_mut() {
10747            diagnostics.retain(|_, diagnostics_by_server_id| {
10748                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10749                    diagnostics_by_server_id.remove(ix);
10750                    !diagnostics_by_server_id.is_empty()
10751                } else {
10752                    true
10753                }
10754            });
10755        }
10756        local.language_server_watched_paths.remove(&server_id);
10757
10758        let server_state = local.language_servers.remove(&server_id);
10759        self.cleanup_lsp_data(server_id);
10760        let name = self
10761            .language_server_statuses
10762            .remove(&server_id)
10763            .map(|status| status.name)
10764            .or_else(|| {
10765                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10766                    Some(adapter.name())
10767                } else {
10768                    None
10769                }
10770            });
10771
10772        if let Some(name) = name {
10773            log::info!("stopping language server {name}");
10774            self.languages
10775                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10776            cx.notify();
10777
10778            return cx.spawn(async move |lsp_store, cx| {
10779                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10780                lsp_store
10781                    .update(cx, |lsp_store, cx| {
10782                        lsp_store
10783                            .languages
10784                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10785                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10786                        cx.notify();
10787                    })
10788                    .ok();
10789            });
10790        }
10791
10792        if server_state.is_some() {
10793            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10794        }
10795        Task::ready(())
10796    }
10797
10798    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10799        self.shutdown_all_language_servers(cx).detach();
10800    }
10801
10802    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10803        if let Some((client, project_id)) = self.upstream_client() {
10804            let request = client.request(proto::StopLanguageServers {
10805                project_id,
10806                buffer_ids: Vec::new(),
10807                also_servers: Vec::new(),
10808                all: true,
10809            });
10810            cx.background_spawn(async move {
10811                request.await.ok();
10812            })
10813        } else {
10814            let Some(local) = self.as_local_mut() else {
10815                return Task::ready(());
10816            };
10817            let language_servers_to_stop = local
10818                .language_server_ids
10819                .values()
10820                .map(|state| state.id)
10821                .collect();
10822            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10823            let tasks = language_servers_to_stop
10824                .into_iter()
10825                .map(|server| self.stop_local_language_server(server, cx))
10826                .collect::<Vec<_>>();
10827            cx.background_spawn(async move {
10828                futures::future::join_all(tasks).await;
10829            })
10830        }
10831    }
10832
10833    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10834        let buffers = self.buffer_store.read(cx).buffers().collect();
10835        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10836    }
10837
10838    pub fn restart_language_servers_for_buffers(
10839        &mut self,
10840        buffers: Vec<Entity<Buffer>>,
10841        only_restart_servers: HashSet<LanguageServerSelector>,
10842        cx: &mut Context<Self>,
10843    ) {
10844        if let Some((client, project_id)) = self.upstream_client() {
10845            let request = client.request(proto::RestartLanguageServers {
10846                project_id,
10847                buffer_ids: buffers
10848                    .into_iter()
10849                    .map(|b| b.read(cx).remote_id().to_proto())
10850                    .collect(),
10851                only_servers: only_restart_servers
10852                    .into_iter()
10853                    .map(|selector| {
10854                        let selector = match selector {
10855                            LanguageServerSelector::Id(language_server_id) => {
10856                                proto::language_server_selector::Selector::ServerId(
10857                                    language_server_id.to_proto(),
10858                                )
10859                            }
10860                            LanguageServerSelector::Name(language_server_name) => {
10861                                proto::language_server_selector::Selector::Name(
10862                                    language_server_name.to_string(),
10863                                )
10864                            }
10865                        };
10866                        proto::LanguageServerSelector {
10867                            selector: Some(selector),
10868                        }
10869                    })
10870                    .collect(),
10871                all: false,
10872            });
10873            cx.background_spawn(request).detach_and_log_err(cx);
10874        } else {
10875            let stop_task = if only_restart_servers.is_empty() {
10876                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10877            } else {
10878                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10879            };
10880            cx.spawn(async move |lsp_store, cx| {
10881                stop_task.await;
10882                lsp_store.update(cx, |lsp_store, cx| {
10883                    for buffer in buffers {
10884                        lsp_store.register_buffer_with_language_servers(
10885                            &buffer,
10886                            only_restart_servers.clone(),
10887                            true,
10888                            cx,
10889                        );
10890                    }
10891                })
10892            })
10893            .detach();
10894        }
10895    }
10896
10897    pub fn stop_language_servers_for_buffers(
10898        &mut self,
10899        buffers: Vec<Entity<Buffer>>,
10900        also_stop_servers: HashSet<LanguageServerSelector>,
10901        cx: &mut Context<Self>,
10902    ) -> Task<Result<()>> {
10903        if let Some((client, project_id)) = self.upstream_client() {
10904            let request = client.request(proto::StopLanguageServers {
10905                project_id,
10906                buffer_ids: buffers
10907                    .into_iter()
10908                    .map(|b| b.read(cx).remote_id().to_proto())
10909                    .collect(),
10910                also_servers: also_stop_servers
10911                    .into_iter()
10912                    .map(|selector| {
10913                        let selector = match selector {
10914                            LanguageServerSelector::Id(language_server_id) => {
10915                                proto::language_server_selector::Selector::ServerId(
10916                                    language_server_id.to_proto(),
10917                                )
10918                            }
10919                            LanguageServerSelector::Name(language_server_name) => {
10920                                proto::language_server_selector::Selector::Name(
10921                                    language_server_name.to_string(),
10922                                )
10923                            }
10924                        };
10925                        proto::LanguageServerSelector {
10926                            selector: Some(selector),
10927                        }
10928                    })
10929                    .collect(),
10930                all: false,
10931            });
10932            cx.background_spawn(async move {
10933                let _ = request.await?;
10934                Ok(())
10935            })
10936        } else {
10937            let task =
10938                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10939            cx.background_spawn(async move {
10940                task.await;
10941                Ok(())
10942            })
10943        }
10944    }
10945
10946    fn stop_local_language_servers_for_buffers(
10947        &mut self,
10948        buffers: &[Entity<Buffer>],
10949        also_stop_servers: HashSet<LanguageServerSelector>,
10950        cx: &mut Context<Self>,
10951    ) -> Task<()> {
10952        let Some(local) = self.as_local_mut() else {
10953            return Task::ready(());
10954        };
10955        let mut language_server_names_to_stop = BTreeSet::default();
10956        let mut language_servers_to_stop = also_stop_servers
10957            .into_iter()
10958            .flat_map(|selector| match selector {
10959                LanguageServerSelector::Id(id) => Some(id),
10960                LanguageServerSelector::Name(name) => {
10961                    language_server_names_to_stop.insert(name);
10962                    None
10963                }
10964            })
10965            .collect::<BTreeSet<_>>();
10966
10967        let mut covered_worktrees = HashSet::default();
10968        for buffer in buffers {
10969            buffer.update(cx, |buffer, cx| {
10970                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10971                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10972                    && covered_worktrees.insert(worktree_id)
10973                {
10974                    language_server_names_to_stop.retain(|name| {
10975                        let old_ids_count = language_servers_to_stop.len();
10976                        let all_language_servers_with_this_name = local
10977                            .language_server_ids
10978                            .iter()
10979                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10980                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10981                        old_ids_count == language_servers_to_stop.len()
10982                    });
10983                }
10984            });
10985        }
10986        for name in language_server_names_to_stop {
10987            language_servers_to_stop.extend(
10988                local
10989                    .language_server_ids
10990                    .iter()
10991                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10992            );
10993        }
10994
10995        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10996        let tasks = language_servers_to_stop
10997            .into_iter()
10998            .map(|server| self.stop_local_language_server(server, cx))
10999            .collect::<Vec<_>>();
11000
11001        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11002    }
11003
11004    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11005        let (worktree, relative_path) =
11006            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11007
11008        let project_path = ProjectPath {
11009            worktree_id: worktree.read(cx).id(),
11010            path: relative_path,
11011        };
11012
11013        Some(
11014            self.buffer_store()
11015                .read(cx)
11016                .get_by_path(&project_path)?
11017                .read(cx),
11018        )
11019    }
11020
11021    #[cfg(any(test, feature = "test-support"))]
11022    pub fn update_diagnostics(
11023        &mut self,
11024        server_id: LanguageServerId,
11025        diagnostics: lsp::PublishDiagnosticsParams,
11026        result_id: Option<SharedString>,
11027        source_kind: DiagnosticSourceKind,
11028        disk_based_sources: &[String],
11029        cx: &mut Context<Self>,
11030    ) -> Result<()> {
11031        self.merge_lsp_diagnostics(
11032            source_kind,
11033            vec![DocumentDiagnosticsUpdate {
11034                diagnostics,
11035                result_id,
11036                server_id,
11037                disk_based_sources: Cow::Borrowed(disk_based_sources),
11038                registration_id: None,
11039            }],
11040            |_, _, _| false,
11041            cx,
11042        )
11043    }
11044
11045    pub fn merge_lsp_diagnostics(
11046        &mut self,
11047        source_kind: DiagnosticSourceKind,
11048        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11049        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11050        cx: &mut Context<Self>,
11051    ) -> Result<()> {
11052        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11053        let updates = lsp_diagnostics
11054            .into_iter()
11055            .filter_map(|update| {
11056                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11057                Some(DocumentDiagnosticsUpdate {
11058                    diagnostics: self.lsp_to_document_diagnostics(
11059                        abs_path,
11060                        source_kind,
11061                        update.server_id,
11062                        update.diagnostics,
11063                        &update.disk_based_sources,
11064                        update.registration_id.clone(),
11065                    ),
11066                    result_id: update.result_id,
11067                    server_id: update.server_id,
11068                    disk_based_sources: update.disk_based_sources,
11069                    registration_id: update.registration_id,
11070                })
11071            })
11072            .collect();
11073        self.merge_diagnostic_entries(updates, merge, cx)?;
11074        Ok(())
11075    }
11076
11077    fn lsp_to_document_diagnostics(
11078        &mut self,
11079        document_abs_path: PathBuf,
11080        source_kind: DiagnosticSourceKind,
11081        server_id: LanguageServerId,
11082        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11083        disk_based_sources: &[String],
11084        registration_id: Option<SharedString>,
11085    ) -> DocumentDiagnostics {
11086        let mut diagnostics = Vec::default();
11087        let mut primary_diagnostic_group_ids = HashMap::default();
11088        let mut sources_by_group_id = HashMap::default();
11089        let mut supporting_diagnostics = HashMap::default();
11090
11091        let adapter = self.language_server_adapter_for_id(server_id);
11092
11093        // Ensure that primary diagnostics are always the most severe
11094        lsp_diagnostics
11095            .diagnostics
11096            .sort_by_key(|item| item.severity);
11097
11098        for diagnostic in &lsp_diagnostics.diagnostics {
11099            let source = diagnostic.source.as_ref();
11100            let range = range_from_lsp(diagnostic.range);
11101            let is_supporting = diagnostic
11102                .related_information
11103                .as_ref()
11104                .is_some_and(|infos| {
11105                    infos.iter().any(|info| {
11106                        primary_diagnostic_group_ids.contains_key(&(
11107                            source,
11108                            diagnostic.code.clone(),
11109                            range_from_lsp(info.location.range),
11110                        ))
11111                    })
11112                });
11113
11114            let is_unnecessary = diagnostic
11115                .tags
11116                .as_ref()
11117                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11118
11119            let underline = self
11120                .language_server_adapter_for_id(server_id)
11121                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11122
11123            if is_supporting {
11124                supporting_diagnostics.insert(
11125                    (source, diagnostic.code.clone(), range),
11126                    (diagnostic.severity, is_unnecessary),
11127                );
11128            } else {
11129                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11130                let is_disk_based =
11131                    source.is_some_and(|source| disk_based_sources.contains(source));
11132
11133                sources_by_group_id.insert(group_id, source);
11134                primary_diagnostic_group_ids
11135                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11136
11137                diagnostics.push(DiagnosticEntry {
11138                    range,
11139                    diagnostic: Diagnostic {
11140                        source: diagnostic.source.clone(),
11141                        source_kind,
11142                        code: diagnostic.code.clone(),
11143                        code_description: diagnostic
11144                            .code_description
11145                            .as_ref()
11146                            .and_then(|d| d.href.clone()),
11147                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11148                        markdown: adapter.as_ref().and_then(|adapter| {
11149                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11150                        }),
11151                        message: diagnostic.message.trim().to_string(),
11152                        group_id,
11153                        is_primary: true,
11154                        is_disk_based,
11155                        is_unnecessary,
11156                        underline,
11157                        data: diagnostic.data.clone(),
11158                        registration_id: registration_id.clone(),
11159                    },
11160                });
11161                if let Some(infos) = &diagnostic.related_information {
11162                    for info in infos {
11163                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11164                            let range = range_from_lsp(info.location.range);
11165                            diagnostics.push(DiagnosticEntry {
11166                                range,
11167                                diagnostic: Diagnostic {
11168                                    source: diagnostic.source.clone(),
11169                                    source_kind,
11170                                    code: diagnostic.code.clone(),
11171                                    code_description: diagnostic
11172                                        .code_description
11173                                        .as_ref()
11174                                        .and_then(|d| d.href.clone()),
11175                                    severity: DiagnosticSeverity::INFORMATION,
11176                                    markdown: adapter.as_ref().and_then(|adapter| {
11177                                        adapter.diagnostic_message_to_markdown(&info.message)
11178                                    }),
11179                                    message: info.message.trim().to_string(),
11180                                    group_id,
11181                                    is_primary: false,
11182                                    is_disk_based,
11183                                    is_unnecessary: false,
11184                                    underline,
11185                                    data: diagnostic.data.clone(),
11186                                    registration_id: registration_id.clone(),
11187                                },
11188                            });
11189                        }
11190                    }
11191                }
11192            }
11193        }
11194
11195        for entry in &mut diagnostics {
11196            let diagnostic = &mut entry.diagnostic;
11197            if !diagnostic.is_primary {
11198                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11199                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11200                    source,
11201                    diagnostic.code.clone(),
11202                    entry.range.clone(),
11203                )) {
11204                    if let Some(severity) = severity {
11205                        diagnostic.severity = severity;
11206                    }
11207                    diagnostic.is_unnecessary = is_unnecessary;
11208                }
11209            }
11210        }
11211
11212        DocumentDiagnostics {
11213            diagnostics,
11214            document_abs_path,
11215            version: lsp_diagnostics.version,
11216        }
11217    }
11218
11219    fn insert_newly_running_language_server(
11220        &mut self,
11221        adapter: Arc<CachedLspAdapter>,
11222        language_server: Arc<LanguageServer>,
11223        server_id: LanguageServerId,
11224        key: LanguageServerSeed,
11225        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11226        cx: &mut Context<Self>,
11227    ) {
11228        let Some(local) = self.as_local_mut() else {
11229            return;
11230        };
11231        // If the language server for this key doesn't match the server id, don't store the
11232        // server. Which will cause it to be dropped, killing the process
11233        if local
11234            .language_server_ids
11235            .get(&key)
11236            .map(|state| state.id != server_id)
11237            .unwrap_or(false)
11238        {
11239            return;
11240        }
11241
11242        // Update language_servers collection with Running variant of LanguageServerState
11243        // indicating that the server is up and running and ready
11244        let workspace_folders = workspace_folders.lock().clone();
11245        language_server.set_workspace_folders(workspace_folders);
11246
11247        let workspace_diagnostics_refresh_tasks = language_server
11248            .capabilities()
11249            .diagnostic_provider
11250            .and_then(|provider| {
11251                local
11252                    .language_server_dynamic_registrations
11253                    .entry(server_id)
11254                    .or_default()
11255                    .diagnostics
11256                    .entry(None)
11257                    .or_insert(provider.clone());
11258                let workspace_refresher =
11259                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11260
11261                Some((None, workspace_refresher))
11262            })
11263            .into_iter()
11264            .collect();
11265        local.language_servers.insert(
11266            server_id,
11267            LanguageServerState::Running {
11268                workspace_diagnostics_refresh_tasks,
11269                adapter: adapter.clone(),
11270                server: language_server.clone(),
11271                simulate_disk_based_diagnostics_completion: None,
11272            },
11273        );
11274        local
11275            .languages
11276            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11277        if let Some(file_ops_caps) = language_server
11278            .capabilities()
11279            .workspace
11280            .as_ref()
11281            .and_then(|ws| ws.file_operations.as_ref())
11282        {
11283            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11284            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11285            if did_rename_caps.or(will_rename_caps).is_some() {
11286                let watcher = RenamePathsWatchedForServer::default()
11287                    .with_did_rename_patterns(did_rename_caps)
11288                    .with_will_rename_patterns(will_rename_caps);
11289                local
11290                    .language_server_paths_watched_for_rename
11291                    .insert(server_id, watcher);
11292            }
11293        }
11294
11295        self.language_server_statuses.insert(
11296            server_id,
11297            LanguageServerStatus {
11298                name: language_server.name(),
11299                server_version: language_server.version(),
11300                pending_work: Default::default(),
11301                has_pending_diagnostic_updates: false,
11302                progress_tokens: Default::default(),
11303                worktree: Some(key.worktree_id),
11304                binary: Some(language_server.binary().clone()),
11305                configuration: Some(language_server.configuration().clone()),
11306                workspace_folders: language_server.workspace_folders(),
11307                process_id: language_server.process_id(),
11308            },
11309        );
11310
11311        cx.emit(LspStoreEvent::LanguageServerAdded(
11312            server_id,
11313            language_server.name(),
11314            Some(key.worktree_id),
11315        ));
11316
11317        let server_capabilities = language_server.capabilities();
11318        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11319            downstream_client
11320                .send(proto::StartLanguageServer {
11321                    project_id: *project_id,
11322                    server: Some(proto::LanguageServer {
11323                        id: server_id.to_proto(),
11324                        name: language_server.name().to_string(),
11325                        worktree_id: Some(key.worktree_id.to_proto()),
11326                    }),
11327                    capabilities: serde_json::to_string(&server_capabilities)
11328                        .expect("serializing server LSP capabilities"),
11329                })
11330                .log_err();
11331        }
11332        self.lsp_server_capabilities
11333            .insert(server_id, server_capabilities);
11334
11335        // Tell the language server about every open buffer in the worktree that matches the language.
11336        // Also check for buffers in worktrees that reused this server
11337        let mut worktrees_using_server = vec![key.worktree_id];
11338        if let Some(local) = self.as_local() {
11339            // Find all worktrees that have this server in their language server tree
11340            for (worktree_id, servers) in &local.lsp_tree.instances {
11341                if *worktree_id != key.worktree_id {
11342                    for server_map in servers.roots.values() {
11343                        if server_map
11344                            .values()
11345                            .any(|(node, _)| node.id() == Some(server_id))
11346                        {
11347                            worktrees_using_server.push(*worktree_id);
11348                        }
11349                    }
11350                }
11351            }
11352        }
11353
11354        let mut buffer_paths_registered = Vec::new();
11355        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11356            let mut lsp_adapters = HashMap::default();
11357            for buffer_handle in buffer_store.buffers() {
11358                let buffer = buffer_handle.read(cx);
11359                let file = match File::from_dyn(buffer.file()) {
11360                    Some(file) => file,
11361                    None => continue,
11362                };
11363                let language = match buffer.language() {
11364                    Some(language) => language,
11365                    None => continue,
11366                };
11367
11368                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11369                    || !lsp_adapters
11370                        .entry(language.name())
11371                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11372                        .iter()
11373                        .any(|a| a.name == key.name)
11374                {
11375                    continue;
11376                }
11377                // didOpen
11378                let file = match file.as_local() {
11379                    Some(file) => file,
11380                    None => continue,
11381                };
11382
11383                let local = self.as_local_mut().unwrap();
11384
11385                let buffer_id = buffer.remote_id();
11386                if local.registered_buffers.contains_key(&buffer_id) {
11387                    let versions = local
11388                        .buffer_snapshots
11389                        .entry(buffer_id)
11390                        .or_default()
11391                        .entry(server_id)
11392                        .and_modify(|_| {
11393                            assert!(
11394                            false,
11395                            "There should not be an existing snapshot for a newly inserted buffer"
11396                        )
11397                        })
11398                        .or_insert_with(|| {
11399                            vec![LspBufferSnapshot {
11400                                version: 0,
11401                                snapshot: buffer.text_snapshot(),
11402                            }]
11403                        });
11404
11405                    let snapshot = versions.last().unwrap();
11406                    let version = snapshot.version;
11407                    let initial_snapshot = &snapshot.snapshot;
11408                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11409                    language_server.register_buffer(
11410                        uri,
11411                        adapter.language_id(&language.name()),
11412                        version,
11413                        initial_snapshot.text(),
11414                    );
11415                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11416                    local
11417                        .buffers_opened_in_servers
11418                        .entry(buffer_id)
11419                        .or_default()
11420                        .insert(server_id);
11421                }
11422                buffer_handle.update(cx, |buffer, cx| {
11423                    buffer.set_completion_triggers(
11424                        server_id,
11425                        language_server
11426                            .capabilities()
11427                            .completion_provider
11428                            .as_ref()
11429                            .and_then(|provider| {
11430                                provider
11431                                    .trigger_characters
11432                                    .as_ref()
11433                                    .map(|characters| characters.iter().cloned().collect())
11434                            })
11435                            .unwrap_or_default(),
11436                        cx,
11437                    )
11438                });
11439            }
11440        });
11441
11442        for (buffer_id, abs_path) in buffer_paths_registered {
11443            cx.emit(LspStoreEvent::LanguageServerUpdate {
11444                language_server_id: server_id,
11445                name: Some(adapter.name()),
11446                message: proto::update_language_server::Variant::RegisteredForBuffer(
11447                    proto::RegisteredForBuffer {
11448                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11449                        buffer_id: buffer_id.to_proto(),
11450                    },
11451                ),
11452            });
11453        }
11454
11455        cx.notify();
11456    }
11457
11458    pub fn language_servers_running_disk_based_diagnostics(
11459        &self,
11460    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11461        self.language_server_statuses
11462            .iter()
11463            .filter_map(|(id, status)| {
11464                if status.has_pending_diagnostic_updates {
11465                    Some(*id)
11466                } else {
11467                    None
11468                }
11469            })
11470    }
11471
11472    pub(crate) fn cancel_language_server_work_for_buffers(
11473        &mut self,
11474        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11475        cx: &mut Context<Self>,
11476    ) {
11477        if let Some((client, project_id)) = self.upstream_client() {
11478            let request = client.request(proto::CancelLanguageServerWork {
11479                project_id,
11480                work: Some(proto::cancel_language_server_work::Work::Buffers(
11481                    proto::cancel_language_server_work::Buffers {
11482                        buffer_ids: buffers
11483                            .into_iter()
11484                            .map(|b| b.read(cx).remote_id().to_proto())
11485                            .collect(),
11486                    },
11487                )),
11488            });
11489            cx.background_spawn(request).detach_and_log_err(cx);
11490        } else if let Some(local) = self.as_local() {
11491            let servers = buffers
11492                .into_iter()
11493                .flat_map(|buffer| {
11494                    buffer.update(cx, |buffer, cx| {
11495                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11496                    })
11497                })
11498                .collect::<HashSet<_>>();
11499            for server_id in servers {
11500                self.cancel_language_server_work(server_id, None, cx);
11501            }
11502        }
11503    }
11504
11505    pub(crate) fn cancel_language_server_work(
11506        &mut self,
11507        server_id: LanguageServerId,
11508        token_to_cancel: Option<ProgressToken>,
11509        cx: &mut Context<Self>,
11510    ) {
11511        if let Some(local) = self.as_local() {
11512            let status = self.language_server_statuses.get(&server_id);
11513            let server = local.language_servers.get(&server_id);
11514            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11515            {
11516                for (token, progress) in &status.pending_work {
11517                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11518                        && token != token_to_cancel
11519                    {
11520                        continue;
11521                    }
11522                    if progress.is_cancellable {
11523                        server
11524                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11525                                WorkDoneProgressCancelParams {
11526                                    token: token.to_lsp(),
11527                                },
11528                            )
11529                            .ok();
11530                    }
11531                }
11532            }
11533        } else if let Some((client, project_id)) = self.upstream_client() {
11534            let request = client.request(proto::CancelLanguageServerWork {
11535                project_id,
11536                work: Some(
11537                    proto::cancel_language_server_work::Work::LanguageServerWork(
11538                        proto::cancel_language_server_work::LanguageServerWork {
11539                            language_server_id: server_id.to_proto(),
11540                            token: token_to_cancel.map(|token| token.to_proto()),
11541                        },
11542                    ),
11543                ),
11544            });
11545            cx.background_spawn(request).detach_and_log_err(cx);
11546        }
11547    }
11548
11549    fn register_supplementary_language_server(
11550        &mut self,
11551        id: LanguageServerId,
11552        name: LanguageServerName,
11553        server: Arc<LanguageServer>,
11554        cx: &mut Context<Self>,
11555    ) {
11556        if let Some(local) = self.as_local_mut() {
11557            local
11558                .supplementary_language_servers
11559                .insert(id, (name.clone(), server));
11560            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11561        }
11562    }
11563
11564    fn unregister_supplementary_language_server(
11565        &mut self,
11566        id: LanguageServerId,
11567        cx: &mut Context<Self>,
11568    ) {
11569        if let Some(local) = self.as_local_mut() {
11570            local.supplementary_language_servers.remove(&id);
11571            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11572        }
11573    }
11574
11575    pub(crate) fn supplementary_language_servers(
11576        &self,
11577    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11578        self.as_local().into_iter().flat_map(|local| {
11579            local
11580                .supplementary_language_servers
11581                .iter()
11582                .map(|(id, (name, _))| (*id, name.clone()))
11583        })
11584    }
11585
11586    pub fn language_server_adapter_for_id(
11587        &self,
11588        id: LanguageServerId,
11589    ) -> Option<Arc<CachedLspAdapter>> {
11590        self.as_local()
11591            .and_then(|local| local.language_servers.get(&id))
11592            .and_then(|language_server_state| match language_server_state {
11593                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11594                _ => None,
11595            })
11596    }
11597
11598    pub(super) fn update_local_worktree_language_servers(
11599        &mut self,
11600        worktree_handle: &Entity<Worktree>,
11601        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11602        cx: &mut Context<Self>,
11603    ) {
11604        if changes.is_empty() {
11605            return;
11606        }
11607
11608        let Some(local) = self.as_local() else { return };
11609
11610        local.prettier_store.update(cx, |prettier_store, cx| {
11611            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11612        });
11613
11614        let worktree_id = worktree_handle.read(cx).id();
11615        let mut language_server_ids = local
11616            .language_server_ids
11617            .iter()
11618            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11619            .collect::<Vec<_>>();
11620        language_server_ids.sort();
11621        language_server_ids.dedup();
11622
11623        // let abs_path = worktree_handle.read(cx).abs_path();
11624        for server_id in &language_server_ids {
11625            if let Some(LanguageServerState::Running { server, .. }) =
11626                local.language_servers.get(server_id)
11627                && let Some(watched_paths) = local
11628                    .language_server_watched_paths
11629                    .get(server_id)
11630                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11631            {
11632                let params = lsp::DidChangeWatchedFilesParams {
11633                    changes: changes
11634                        .iter()
11635                        .filter_map(|(path, _, change)| {
11636                            if !watched_paths.is_match(path.as_std_path()) {
11637                                return None;
11638                            }
11639                            let typ = match change {
11640                                PathChange::Loaded => return None,
11641                                PathChange::Added => lsp::FileChangeType::CREATED,
11642                                PathChange::Removed => lsp::FileChangeType::DELETED,
11643                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11644                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11645                            };
11646                            let uri = lsp::Uri::from_file_path(
11647                                worktree_handle.read(cx).absolutize(&path),
11648                            )
11649                            .ok()?;
11650                            Some(lsp::FileEvent { uri, typ })
11651                        })
11652                        .collect(),
11653                };
11654                if !params.changes.is_empty() {
11655                    server
11656                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11657                        .ok();
11658                }
11659            }
11660        }
11661        for (path, _, _) in changes {
11662            if let Some(file_name) = path.file_name()
11663                && local.watched_manifest_filenames.contains(file_name)
11664            {
11665                self.request_workspace_config_refresh();
11666                break;
11667            }
11668        }
11669    }
11670
11671    pub fn wait_for_remote_buffer(
11672        &mut self,
11673        id: BufferId,
11674        cx: &mut Context<Self>,
11675    ) -> Task<Result<Entity<Buffer>>> {
11676        self.buffer_store.update(cx, |buffer_store, cx| {
11677            buffer_store.wait_for_remote_buffer(id, cx)
11678        })
11679    }
11680
11681    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11682        let mut result = proto::Symbol {
11683            language_server_name: symbol.language_server_name.0.to_string(),
11684            source_worktree_id: symbol.source_worktree_id.to_proto(),
11685            language_server_id: symbol.source_language_server_id.to_proto(),
11686            name: symbol.name.clone(),
11687            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11688            start: Some(proto::PointUtf16 {
11689                row: symbol.range.start.0.row,
11690                column: symbol.range.start.0.column,
11691            }),
11692            end: Some(proto::PointUtf16 {
11693                row: symbol.range.end.0.row,
11694                column: symbol.range.end.0.column,
11695            }),
11696            worktree_id: Default::default(),
11697            path: Default::default(),
11698            signature: Default::default(),
11699            container_name: symbol.container_name.clone(),
11700        };
11701        match &symbol.path {
11702            SymbolLocation::InProject(path) => {
11703                result.worktree_id = path.worktree_id.to_proto();
11704                result.path = path.path.to_proto();
11705            }
11706            SymbolLocation::OutsideProject {
11707                abs_path,
11708                signature,
11709            } => {
11710                result.path = abs_path.to_string_lossy().into_owned();
11711                result.signature = signature.to_vec();
11712            }
11713        }
11714        result
11715    }
11716
11717    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11718        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11719        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11720        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11721
11722        let path = if serialized_symbol.signature.is_empty() {
11723            SymbolLocation::InProject(ProjectPath {
11724                worktree_id,
11725                path: RelPath::from_proto(&serialized_symbol.path)
11726                    .context("invalid symbol path")?,
11727            })
11728        } else {
11729            SymbolLocation::OutsideProject {
11730                abs_path: Path::new(&serialized_symbol.path).into(),
11731                signature: serialized_symbol
11732                    .signature
11733                    .try_into()
11734                    .map_err(|_| anyhow!("invalid signature"))?,
11735            }
11736        };
11737
11738        let start = serialized_symbol.start.context("invalid start")?;
11739        let end = serialized_symbol.end.context("invalid end")?;
11740        Ok(CoreSymbol {
11741            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11742            source_worktree_id,
11743            source_language_server_id: LanguageServerId::from_proto(
11744                serialized_symbol.language_server_id,
11745            ),
11746            path,
11747            name: serialized_symbol.name,
11748            range: Unclipped(PointUtf16::new(start.row, start.column))
11749                ..Unclipped(PointUtf16::new(end.row, end.column)),
11750            kind,
11751            container_name: serialized_symbol.container_name,
11752        })
11753    }
11754
11755    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11756        let mut serialized_completion = proto::Completion {
11757            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11758            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11759            new_text: completion.new_text.clone(),
11760            ..proto::Completion::default()
11761        };
11762        match &completion.source {
11763            CompletionSource::Lsp {
11764                insert_range,
11765                server_id,
11766                lsp_completion,
11767                lsp_defaults,
11768                resolved,
11769            } => {
11770                let (old_insert_start, old_insert_end) = insert_range
11771                    .as_ref()
11772                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11773                    .unzip();
11774
11775                serialized_completion.old_insert_start = old_insert_start;
11776                serialized_completion.old_insert_end = old_insert_end;
11777                serialized_completion.source = proto::completion::Source::Lsp as i32;
11778                serialized_completion.server_id = server_id.0 as u64;
11779                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11780                serialized_completion.lsp_defaults = lsp_defaults
11781                    .as_deref()
11782                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11783                serialized_completion.resolved = *resolved;
11784            }
11785            CompletionSource::BufferWord {
11786                word_range,
11787                resolved,
11788            } => {
11789                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11790                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11791                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11792                serialized_completion.resolved = *resolved;
11793            }
11794            CompletionSource::Custom => {
11795                serialized_completion.source = proto::completion::Source::Custom as i32;
11796                serialized_completion.resolved = true;
11797            }
11798            CompletionSource::Dap { sort_text } => {
11799                serialized_completion.source = proto::completion::Source::Dap as i32;
11800                serialized_completion.sort_text = Some(sort_text.clone());
11801            }
11802        }
11803
11804        serialized_completion
11805    }
11806
11807    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11808        let old_replace_start = completion
11809            .old_replace_start
11810            .and_then(deserialize_anchor)
11811            .context("invalid old start")?;
11812        let old_replace_end = completion
11813            .old_replace_end
11814            .and_then(deserialize_anchor)
11815            .context("invalid old end")?;
11816        let insert_range = {
11817            match completion.old_insert_start.zip(completion.old_insert_end) {
11818                Some((start, end)) => {
11819                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11820                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11821                    Some(start..end)
11822                }
11823                None => None,
11824            }
11825        };
11826        Ok(CoreCompletion {
11827            replace_range: old_replace_start..old_replace_end,
11828            new_text: completion.new_text,
11829            source: match proto::completion::Source::from_i32(completion.source) {
11830                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11831                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11832                    insert_range,
11833                    server_id: LanguageServerId::from_proto(completion.server_id),
11834                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11835                    lsp_defaults: completion
11836                        .lsp_defaults
11837                        .as_deref()
11838                        .map(serde_json::from_slice)
11839                        .transpose()?,
11840                    resolved: completion.resolved,
11841                },
11842                Some(proto::completion::Source::BufferWord) => {
11843                    let word_range = completion
11844                        .buffer_word_start
11845                        .and_then(deserialize_anchor)
11846                        .context("invalid buffer word start")?
11847                        ..completion
11848                            .buffer_word_end
11849                            .and_then(deserialize_anchor)
11850                            .context("invalid buffer word end")?;
11851                    CompletionSource::BufferWord {
11852                        word_range,
11853                        resolved: completion.resolved,
11854                    }
11855                }
11856                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11857                    sort_text: completion
11858                        .sort_text
11859                        .context("expected sort text to exist")?,
11860                },
11861                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11862            },
11863        })
11864    }
11865
11866    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11867        let (kind, lsp_action) = match &action.lsp_action {
11868            LspAction::Action(code_action) => (
11869                proto::code_action::Kind::Action as i32,
11870                serde_json::to_vec(code_action).unwrap(),
11871            ),
11872            LspAction::Command(command) => (
11873                proto::code_action::Kind::Command as i32,
11874                serde_json::to_vec(command).unwrap(),
11875            ),
11876            LspAction::CodeLens(code_lens) => (
11877                proto::code_action::Kind::CodeLens as i32,
11878                serde_json::to_vec(code_lens).unwrap(),
11879            ),
11880        };
11881
11882        proto::CodeAction {
11883            server_id: action.server_id.0 as u64,
11884            start: Some(serialize_anchor(&action.range.start)),
11885            end: Some(serialize_anchor(&action.range.end)),
11886            lsp_action,
11887            kind,
11888            resolved: action.resolved,
11889        }
11890    }
11891
11892    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11893        let start = action
11894            .start
11895            .and_then(deserialize_anchor)
11896            .context("invalid start")?;
11897        let end = action
11898            .end
11899            .and_then(deserialize_anchor)
11900            .context("invalid end")?;
11901        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11902            Some(proto::code_action::Kind::Action) => {
11903                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11904            }
11905            Some(proto::code_action::Kind::Command) => {
11906                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11907            }
11908            Some(proto::code_action::Kind::CodeLens) => {
11909                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11910            }
11911            None => anyhow::bail!("Unknown action kind {}", action.kind),
11912        };
11913        Ok(CodeAction {
11914            server_id: LanguageServerId(action.server_id as usize),
11915            range: start..end,
11916            resolved: action.resolved,
11917            lsp_action,
11918        })
11919    }
11920
11921    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11922        match &formatting_result {
11923            Ok(_) => self.last_formatting_failure = None,
11924            Err(error) => {
11925                let error_string = format!("{error:#}");
11926                log::error!("Formatting failed: {error_string}");
11927                self.last_formatting_failure
11928                    .replace(error_string.lines().join(" "));
11929            }
11930        }
11931    }
11932
11933    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11934        self.lsp_server_capabilities.remove(&for_server);
11935        self.semantic_token_config.remove_server_data(for_server);
11936        for lsp_data in self.lsp_data.values_mut() {
11937            lsp_data.remove_server_data(for_server);
11938        }
11939        if let Some(local) = self.as_local_mut() {
11940            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11941            local
11942                .workspace_pull_diagnostics_result_ids
11943                .remove(&for_server);
11944            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11945                buffer_servers.remove(&for_server);
11946            }
11947        }
11948    }
11949
11950    pub fn result_id_for_buffer_pull(
11951        &self,
11952        server_id: LanguageServerId,
11953        buffer_id: BufferId,
11954        registration_id: &Option<SharedString>,
11955        cx: &App,
11956    ) -> Option<SharedString> {
11957        let abs_path = self
11958            .buffer_store
11959            .read(cx)
11960            .get(buffer_id)
11961            .and_then(|b| File::from_dyn(b.read(cx).file()))
11962            .map(|f| f.abs_path(cx))?;
11963        self.as_local()?
11964            .buffer_pull_diagnostics_result_ids
11965            .get(&server_id)?
11966            .get(registration_id)?
11967            .get(&abs_path)?
11968            .clone()
11969    }
11970
11971    /// Gets all result_ids for a workspace diagnostics pull request.
11972    /// 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.
11973    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
11974    pub fn result_ids_for_workspace_refresh(
11975        &self,
11976        server_id: LanguageServerId,
11977        registration_id: &Option<SharedString>,
11978    ) -> HashMap<PathBuf, SharedString> {
11979        let Some(local) = self.as_local() else {
11980            return HashMap::default();
11981        };
11982        local
11983            .workspace_pull_diagnostics_result_ids
11984            .get(&server_id)
11985            .into_iter()
11986            .filter_map(|diagnostics| diagnostics.get(registration_id))
11987            .flatten()
11988            .filter_map(|(abs_path, result_id)| {
11989                let result_id = local
11990                    .buffer_pull_diagnostics_result_ids
11991                    .get(&server_id)
11992                    .and_then(|buffer_ids_result_ids| {
11993                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
11994                    })
11995                    .cloned()
11996                    .flatten()
11997                    .or_else(|| result_id.clone())?;
11998                Some((abs_path.clone(), result_id))
11999            })
12000            .collect()
12001    }
12002
12003    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12004        if let Some(LanguageServerState::Running {
12005            workspace_diagnostics_refresh_tasks,
12006            ..
12007        }) = self
12008            .as_local_mut()
12009            .and_then(|local| local.language_servers.get_mut(&server_id))
12010        {
12011            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12012                diagnostics.refresh_tx.try_send(()).ok();
12013            }
12014        }
12015    }
12016
12017    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12018    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12019    /// which requires refreshing both workspace and document diagnostics.
12020    pub fn pull_document_diagnostics_for_server(
12021        &mut self,
12022        server_id: LanguageServerId,
12023        source_buffer_id: Option<BufferId>,
12024        cx: &mut Context<Self>,
12025    ) -> Shared<Task<()>> {
12026        let Some(local) = self.as_local_mut() else {
12027            return Task::ready(()).shared();
12028        };
12029        let mut buffers_to_refresh = HashSet::default();
12030        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12031            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12032                buffers_to_refresh.insert(*buffer_id);
12033            }
12034        }
12035
12036        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12037    }
12038
12039    pub fn pull_document_diagnostics_for_buffer_edit(
12040        &mut self,
12041        buffer_id: BufferId,
12042        cx: &mut Context<Self>,
12043    ) {
12044        let Some(local) = self.as_local_mut() else {
12045            return;
12046        };
12047        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12048        else {
12049            return;
12050        };
12051        for server_id in languages_servers {
12052            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12053        }
12054    }
12055
12056    fn apply_workspace_diagnostic_report(
12057        &mut self,
12058        server_id: LanguageServerId,
12059        report: lsp::WorkspaceDiagnosticReportResult,
12060        registration_id: Option<SharedString>,
12061        cx: &mut Context<Self>,
12062    ) {
12063        let mut workspace_diagnostics =
12064            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12065                report,
12066                server_id,
12067                registration_id,
12068            );
12069        workspace_diagnostics.retain(|d| match &d.diagnostics {
12070            LspPullDiagnostics::Response {
12071                server_id,
12072                registration_id,
12073                ..
12074            } => self.diagnostic_registration_exists(*server_id, registration_id),
12075            LspPullDiagnostics::Default => false,
12076        });
12077        let mut unchanged_buffers = HashMap::default();
12078        let workspace_diagnostics_updates = workspace_diagnostics
12079            .into_iter()
12080            .filter_map(
12081                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12082                    LspPullDiagnostics::Response {
12083                        server_id,
12084                        uri,
12085                        diagnostics,
12086                        registration_id,
12087                    } => Some((
12088                        server_id,
12089                        uri,
12090                        diagnostics,
12091                        workspace_diagnostics.version,
12092                        registration_id,
12093                    )),
12094                    LspPullDiagnostics::Default => None,
12095                },
12096            )
12097            .fold(
12098                HashMap::default(),
12099                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12100                    let (result_id, diagnostics) = match diagnostics {
12101                        PulledDiagnostics::Unchanged { result_id } => {
12102                            unchanged_buffers
12103                                .entry(new_registration_id.clone())
12104                                .or_insert_with(HashSet::default)
12105                                .insert(uri.clone());
12106                            (Some(result_id), Vec::new())
12107                        }
12108                        PulledDiagnostics::Changed {
12109                            result_id,
12110                            diagnostics,
12111                        } => (result_id, diagnostics),
12112                    };
12113                    let disk_based_sources = Cow::Owned(
12114                        self.language_server_adapter_for_id(server_id)
12115                            .as_ref()
12116                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12117                            .unwrap_or(&[])
12118                            .to_vec(),
12119                    );
12120
12121                    let Some(abs_path) = uri.to_file_path().ok() else {
12122                        return acc;
12123                    };
12124                    let Some((worktree, relative_path)) =
12125                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12126                    else {
12127                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12128                        return acc;
12129                    };
12130                    let worktree_id = worktree.read(cx).id();
12131                    let project_path = ProjectPath {
12132                        worktree_id,
12133                        path: relative_path,
12134                    };
12135                    if let Some(local_lsp_store) = self.as_local_mut() {
12136                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12137                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12138                    }
12139                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12140                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12141                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12142                        acc.entry(server_id)
12143                            .or_insert_with(HashMap::default)
12144                            .entry(new_registration_id.clone())
12145                            .or_insert_with(Vec::new)
12146                            .push(DocumentDiagnosticsUpdate {
12147                                server_id,
12148                                diagnostics: lsp::PublishDiagnosticsParams {
12149                                    uri,
12150                                    diagnostics,
12151                                    version,
12152                                },
12153                                result_id: result_id.map(SharedString::new),
12154                                disk_based_sources,
12155                                registration_id: new_registration_id,
12156                            });
12157                    }
12158                    acc
12159                },
12160            );
12161
12162        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12163            for (registration_id, diagnostic_updates) in diagnostic_updates {
12164                self.merge_lsp_diagnostics(
12165                    DiagnosticSourceKind::Pulled,
12166                    diagnostic_updates,
12167                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12168                        DiagnosticSourceKind::Pulled => {
12169                            old_diagnostic.registration_id != registration_id
12170                                || unchanged_buffers
12171                                    .get(&old_diagnostic.registration_id)
12172                                    .is_some_and(|unchanged_buffers| {
12173                                        unchanged_buffers.contains(&document_uri)
12174                                    })
12175                        }
12176                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12177                    },
12178                    cx,
12179                )
12180                .log_err();
12181            }
12182        }
12183    }
12184
12185    fn register_server_capabilities(
12186        &mut self,
12187        server_id: LanguageServerId,
12188        params: lsp::RegistrationParams,
12189        cx: &mut Context<Self>,
12190    ) -> anyhow::Result<()> {
12191        let server = self
12192            .language_server_for_id(server_id)
12193            .with_context(|| format!("no server {server_id} found"))?;
12194        for reg in params.registrations {
12195            match reg.method.as_str() {
12196                "workspace/didChangeWatchedFiles" => {
12197                    if let Some(options) = reg.register_options {
12198                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12199                            let caps = serde_json::from_value(options)?;
12200                            local_lsp_store
12201                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12202                            true
12203                        } else {
12204                            false
12205                        };
12206                        if notify {
12207                            notify_server_capabilities_updated(&server, cx);
12208                        }
12209                    }
12210                }
12211                "workspace/didChangeConfiguration" => {
12212                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12213                }
12214                "workspace/didChangeWorkspaceFolders" => {
12215                    // In this case register options is an empty object, we can ignore it
12216                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12217                        supported: Some(true),
12218                        change_notifications: Some(OneOf::Right(reg.id)),
12219                    };
12220                    server.update_capabilities(|capabilities| {
12221                        capabilities
12222                            .workspace
12223                            .get_or_insert_default()
12224                            .workspace_folders = Some(caps);
12225                    });
12226                    notify_server_capabilities_updated(&server, cx);
12227                }
12228                "workspace/symbol" => {
12229                    let options = parse_register_capabilities(reg)?;
12230                    server.update_capabilities(|capabilities| {
12231                        capabilities.workspace_symbol_provider = Some(options);
12232                    });
12233                    notify_server_capabilities_updated(&server, cx);
12234                }
12235                "workspace/fileOperations" => {
12236                    if let Some(options) = reg.register_options {
12237                        let caps = serde_json::from_value(options)?;
12238                        server.update_capabilities(|capabilities| {
12239                            capabilities
12240                                .workspace
12241                                .get_or_insert_default()
12242                                .file_operations = Some(caps);
12243                        });
12244                        notify_server_capabilities_updated(&server, cx);
12245                    }
12246                }
12247                "workspace/executeCommand" => {
12248                    if let Some(options) = reg.register_options {
12249                        let options = serde_json::from_value(options)?;
12250                        server.update_capabilities(|capabilities| {
12251                            capabilities.execute_command_provider = Some(options);
12252                        });
12253                        notify_server_capabilities_updated(&server, cx);
12254                    }
12255                }
12256                "textDocument/rangeFormatting" => {
12257                    let options = parse_register_capabilities(reg)?;
12258                    server.update_capabilities(|capabilities| {
12259                        capabilities.document_range_formatting_provider = Some(options);
12260                    });
12261                    notify_server_capabilities_updated(&server, cx);
12262                }
12263                "textDocument/onTypeFormatting" => {
12264                    if let Some(options) = reg
12265                        .register_options
12266                        .map(serde_json::from_value)
12267                        .transpose()?
12268                    {
12269                        server.update_capabilities(|capabilities| {
12270                            capabilities.document_on_type_formatting_provider = Some(options);
12271                        });
12272                        notify_server_capabilities_updated(&server, cx);
12273                    }
12274                }
12275                "textDocument/formatting" => {
12276                    let options = parse_register_capabilities(reg)?;
12277                    server.update_capabilities(|capabilities| {
12278                        capabilities.document_formatting_provider = Some(options);
12279                    });
12280                    notify_server_capabilities_updated(&server, cx);
12281                }
12282                "textDocument/rename" => {
12283                    let options = parse_register_capabilities(reg)?;
12284                    server.update_capabilities(|capabilities| {
12285                        capabilities.rename_provider = Some(options);
12286                    });
12287                    notify_server_capabilities_updated(&server, cx);
12288                }
12289                "textDocument/inlayHint" => {
12290                    let options = parse_register_capabilities(reg)?;
12291                    server.update_capabilities(|capabilities| {
12292                        capabilities.inlay_hint_provider = Some(options);
12293                    });
12294                    notify_server_capabilities_updated(&server, cx);
12295                }
12296                "textDocument/documentSymbol" => {
12297                    let options = parse_register_capabilities(reg)?;
12298                    server.update_capabilities(|capabilities| {
12299                        capabilities.document_symbol_provider = Some(options);
12300                    });
12301                    notify_server_capabilities_updated(&server, cx);
12302                }
12303                "textDocument/codeAction" => {
12304                    let options = parse_register_capabilities(reg)?;
12305                    let provider = match options {
12306                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12307                        OneOf::Right(caps) => caps,
12308                    };
12309                    server.update_capabilities(|capabilities| {
12310                        capabilities.code_action_provider = Some(provider);
12311                    });
12312                    notify_server_capabilities_updated(&server, cx);
12313                }
12314                "textDocument/definition" => {
12315                    let options = parse_register_capabilities(reg)?;
12316                    server.update_capabilities(|capabilities| {
12317                        capabilities.definition_provider = Some(options);
12318                    });
12319                    notify_server_capabilities_updated(&server, cx);
12320                }
12321                "textDocument/completion" => {
12322                    if let Some(caps) = reg
12323                        .register_options
12324                        .map(serde_json::from_value::<CompletionOptions>)
12325                        .transpose()?
12326                    {
12327                        server.update_capabilities(|capabilities| {
12328                            capabilities.completion_provider = Some(caps.clone());
12329                        });
12330
12331                        if let Some(local) = self.as_local() {
12332                            let mut buffers_with_language_server = Vec::new();
12333                            for handle in self.buffer_store.read(cx).buffers() {
12334                                let buffer_id = handle.read(cx).remote_id();
12335                                if local
12336                                    .buffers_opened_in_servers
12337                                    .get(&buffer_id)
12338                                    .filter(|s| s.contains(&server_id))
12339                                    .is_some()
12340                                {
12341                                    buffers_with_language_server.push(handle);
12342                                }
12343                            }
12344                            let triggers = caps
12345                                .trigger_characters
12346                                .unwrap_or_default()
12347                                .into_iter()
12348                                .collect::<BTreeSet<_>>();
12349                            for handle in buffers_with_language_server {
12350                                let triggers = triggers.clone();
12351                                let _ = handle.update(cx, move |buffer, cx| {
12352                                    buffer.set_completion_triggers(server_id, triggers, cx);
12353                                });
12354                            }
12355                        }
12356                        notify_server_capabilities_updated(&server, cx);
12357                    }
12358                }
12359                "textDocument/hover" => {
12360                    let options = parse_register_capabilities(reg)?;
12361                    let provider = match options {
12362                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12363                        OneOf::Right(caps) => caps,
12364                    };
12365                    server.update_capabilities(|capabilities| {
12366                        capabilities.hover_provider = Some(provider);
12367                    });
12368                    notify_server_capabilities_updated(&server, cx);
12369                }
12370                "textDocument/signatureHelp" => {
12371                    if let Some(caps) = reg
12372                        .register_options
12373                        .map(serde_json::from_value)
12374                        .transpose()?
12375                    {
12376                        server.update_capabilities(|capabilities| {
12377                            capabilities.signature_help_provider = Some(caps);
12378                        });
12379                        notify_server_capabilities_updated(&server, cx);
12380                    }
12381                }
12382                "textDocument/didChange" => {
12383                    if let Some(sync_kind) = reg
12384                        .register_options
12385                        .and_then(|opts| opts.get("syncKind").cloned())
12386                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12387                        .transpose()?
12388                    {
12389                        server.update_capabilities(|capabilities| {
12390                            let mut sync_options =
12391                                Self::take_text_document_sync_options(capabilities);
12392                            sync_options.change = Some(sync_kind);
12393                            capabilities.text_document_sync =
12394                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12395                        });
12396                        notify_server_capabilities_updated(&server, cx);
12397                    }
12398                }
12399                "textDocument/didSave" => {
12400                    if let Some(include_text) = reg
12401                        .register_options
12402                        .map(|opts| {
12403                            let transpose = opts
12404                                .get("includeText")
12405                                .cloned()
12406                                .map(serde_json::from_value::<Option<bool>>)
12407                                .transpose();
12408                            match transpose {
12409                                Ok(value) => Ok(value.flatten()),
12410                                Err(e) => Err(e),
12411                            }
12412                        })
12413                        .transpose()?
12414                    {
12415                        server.update_capabilities(|capabilities| {
12416                            let mut sync_options =
12417                                Self::take_text_document_sync_options(capabilities);
12418                            sync_options.save =
12419                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12420                                    include_text,
12421                                }));
12422                            capabilities.text_document_sync =
12423                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12424                        });
12425                        notify_server_capabilities_updated(&server, cx);
12426                    }
12427                }
12428                "textDocument/codeLens" => {
12429                    if let Some(caps) = reg
12430                        .register_options
12431                        .map(serde_json::from_value)
12432                        .transpose()?
12433                    {
12434                        server.update_capabilities(|capabilities| {
12435                            capabilities.code_lens_provider = Some(caps);
12436                        });
12437                        notify_server_capabilities_updated(&server, cx);
12438                    }
12439                }
12440                "textDocument/diagnostic" => {
12441                    if let Some(caps) = reg
12442                        .register_options
12443                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12444                        .transpose()?
12445                    {
12446                        let local = self
12447                            .as_local_mut()
12448                            .context("Expected LSP Store to be local")?;
12449                        let state = local
12450                            .language_servers
12451                            .get_mut(&server_id)
12452                            .context("Could not obtain Language Servers state")?;
12453                        local
12454                            .language_server_dynamic_registrations
12455                            .entry(server_id)
12456                            .or_default()
12457                            .diagnostics
12458                            .insert(Some(reg.id.clone()), caps.clone());
12459
12460                        let supports_workspace_diagnostics =
12461                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12462                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12463                                    diagnostic_options.workspace_diagnostics
12464                                }
12465                                DiagnosticServerCapabilities::RegistrationOptions(
12466                                    diagnostic_registration_options,
12467                                ) => {
12468                                    diagnostic_registration_options
12469                                        .diagnostic_options
12470                                        .workspace_diagnostics
12471                                }
12472                            };
12473
12474                        if supports_workspace_diagnostics(&caps) {
12475                            if let LanguageServerState::Running {
12476                                workspace_diagnostics_refresh_tasks,
12477                                ..
12478                            } = state
12479                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12480                                    Some(reg.id.clone()),
12481                                    caps.clone(),
12482                                    server.clone(),
12483                                    cx,
12484                                )
12485                            {
12486                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12487                            }
12488                        }
12489
12490                        server.update_capabilities(|capabilities| {
12491                            capabilities.diagnostic_provider = Some(caps);
12492                        });
12493
12494                        notify_server_capabilities_updated(&server, cx);
12495
12496                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12497                    }
12498                }
12499                "textDocument/documentColor" => {
12500                    let options = parse_register_capabilities(reg)?;
12501                    let provider = match options {
12502                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12503                        OneOf::Right(caps) => caps,
12504                    };
12505                    server.update_capabilities(|capabilities| {
12506                        capabilities.color_provider = Some(provider);
12507                    });
12508                    notify_server_capabilities_updated(&server, cx);
12509                }
12510                "textDocument/foldingRange" => {
12511                    let options = parse_register_capabilities(reg)?;
12512                    let provider = match options {
12513                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12514                        OneOf::Right(caps) => caps,
12515                    };
12516                    server.update_capabilities(|capabilities| {
12517                        capabilities.folding_range_provider = Some(provider);
12518                    });
12519                    notify_server_capabilities_updated(&server, cx);
12520                }
12521                _ => log::warn!("unhandled capability registration: {reg:?}"),
12522            }
12523        }
12524
12525        Ok(())
12526    }
12527
12528    fn unregister_server_capabilities(
12529        &mut self,
12530        server_id: LanguageServerId,
12531        params: lsp::UnregistrationParams,
12532        cx: &mut Context<Self>,
12533    ) -> anyhow::Result<()> {
12534        let server = self
12535            .language_server_for_id(server_id)
12536            .with_context(|| format!("no server {server_id} found"))?;
12537        for unreg in params.unregisterations.iter() {
12538            match unreg.method.as_str() {
12539                "workspace/didChangeWatchedFiles" => {
12540                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12541                        local_lsp_store
12542                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12543                        true
12544                    } else {
12545                        false
12546                    };
12547                    if notify {
12548                        notify_server_capabilities_updated(&server, cx);
12549                    }
12550                }
12551                "workspace/didChangeConfiguration" => {
12552                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12553                }
12554                "workspace/didChangeWorkspaceFolders" => {
12555                    server.update_capabilities(|capabilities| {
12556                        capabilities
12557                            .workspace
12558                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12559                                workspace_folders: None,
12560                                file_operations: None,
12561                            })
12562                            .workspace_folders = None;
12563                    });
12564                    notify_server_capabilities_updated(&server, cx);
12565                }
12566                "workspace/symbol" => {
12567                    server.update_capabilities(|capabilities| {
12568                        capabilities.workspace_symbol_provider = None
12569                    });
12570                    notify_server_capabilities_updated(&server, cx);
12571                }
12572                "workspace/fileOperations" => {
12573                    server.update_capabilities(|capabilities| {
12574                        capabilities
12575                            .workspace
12576                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12577                                workspace_folders: None,
12578                                file_operations: None,
12579                            })
12580                            .file_operations = None;
12581                    });
12582                    notify_server_capabilities_updated(&server, cx);
12583                }
12584                "workspace/executeCommand" => {
12585                    server.update_capabilities(|capabilities| {
12586                        capabilities.execute_command_provider = None;
12587                    });
12588                    notify_server_capabilities_updated(&server, cx);
12589                }
12590                "textDocument/rangeFormatting" => {
12591                    server.update_capabilities(|capabilities| {
12592                        capabilities.document_range_formatting_provider = None
12593                    });
12594                    notify_server_capabilities_updated(&server, cx);
12595                }
12596                "textDocument/onTypeFormatting" => {
12597                    server.update_capabilities(|capabilities| {
12598                        capabilities.document_on_type_formatting_provider = None;
12599                    });
12600                    notify_server_capabilities_updated(&server, cx);
12601                }
12602                "textDocument/formatting" => {
12603                    server.update_capabilities(|capabilities| {
12604                        capabilities.document_formatting_provider = None;
12605                    });
12606                    notify_server_capabilities_updated(&server, cx);
12607                }
12608                "textDocument/rename" => {
12609                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12610                    notify_server_capabilities_updated(&server, cx);
12611                }
12612                "textDocument/codeAction" => {
12613                    server.update_capabilities(|capabilities| {
12614                        capabilities.code_action_provider = None;
12615                    });
12616                    notify_server_capabilities_updated(&server, cx);
12617                }
12618                "textDocument/definition" => {
12619                    server.update_capabilities(|capabilities| {
12620                        capabilities.definition_provider = None;
12621                    });
12622                    notify_server_capabilities_updated(&server, cx);
12623                }
12624                "textDocument/completion" => {
12625                    server.update_capabilities(|capabilities| {
12626                        capabilities.completion_provider = None;
12627                    });
12628                    notify_server_capabilities_updated(&server, cx);
12629                }
12630                "textDocument/hover" => {
12631                    server.update_capabilities(|capabilities| {
12632                        capabilities.hover_provider = None;
12633                    });
12634                    notify_server_capabilities_updated(&server, cx);
12635                }
12636                "textDocument/signatureHelp" => {
12637                    server.update_capabilities(|capabilities| {
12638                        capabilities.signature_help_provider = None;
12639                    });
12640                    notify_server_capabilities_updated(&server, cx);
12641                }
12642                "textDocument/didChange" => {
12643                    server.update_capabilities(|capabilities| {
12644                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12645                        sync_options.change = None;
12646                        capabilities.text_document_sync =
12647                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12648                    });
12649                    notify_server_capabilities_updated(&server, cx);
12650                }
12651                "textDocument/didSave" => {
12652                    server.update_capabilities(|capabilities| {
12653                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12654                        sync_options.save = None;
12655                        capabilities.text_document_sync =
12656                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12657                    });
12658                    notify_server_capabilities_updated(&server, cx);
12659                }
12660                "textDocument/codeLens" => {
12661                    server.update_capabilities(|capabilities| {
12662                        capabilities.code_lens_provider = None;
12663                    });
12664                    notify_server_capabilities_updated(&server, cx);
12665                }
12666                "textDocument/diagnostic" => {
12667                    let local = self
12668                        .as_local_mut()
12669                        .context("Expected LSP Store to be local")?;
12670
12671                    let state = local
12672                        .language_servers
12673                        .get_mut(&server_id)
12674                        .context("Could not obtain Language Servers state")?;
12675                    let registrations = local
12676                        .language_server_dynamic_registrations
12677                        .get_mut(&server_id)
12678                        .with_context(|| {
12679                            format!("Expected dynamic registration to exist for server {server_id}")
12680                        })?;
12681                    registrations.diagnostics
12682                        .remove(&Some(unreg.id.clone()))
12683                        .with_context(|| format!(
12684                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12685                            unreg.id)
12686                        )?;
12687                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12688
12689                    if let LanguageServerState::Running {
12690                        workspace_diagnostics_refresh_tasks,
12691                        ..
12692                    } = state
12693                    {
12694                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12695                    }
12696
12697                    self.clear_unregistered_diagnostics(
12698                        server_id,
12699                        SharedString::from(unreg.id.clone()),
12700                        cx,
12701                    )?;
12702
12703                    if removed_last_diagnostic_provider {
12704                        server.update_capabilities(|capabilities| {
12705                            debug_assert!(capabilities.diagnostic_provider.is_some());
12706                            capabilities.diagnostic_provider = None;
12707                        });
12708                    }
12709
12710                    notify_server_capabilities_updated(&server, cx);
12711                }
12712                "textDocument/documentColor" => {
12713                    server.update_capabilities(|capabilities| {
12714                        capabilities.color_provider = None;
12715                    });
12716                    notify_server_capabilities_updated(&server, cx);
12717                }
12718                "textDocument/foldingRange" => {
12719                    server.update_capabilities(|capabilities| {
12720                        capabilities.folding_range_provider = None;
12721                    });
12722                    notify_server_capabilities_updated(&server, cx);
12723                }
12724                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12725            }
12726        }
12727
12728        Ok(())
12729    }
12730
12731    fn clear_unregistered_diagnostics(
12732        &mut self,
12733        server_id: LanguageServerId,
12734        cleared_registration_id: SharedString,
12735        cx: &mut Context<Self>,
12736    ) -> anyhow::Result<()> {
12737        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12738
12739        self.buffer_store.update(cx, |buffer_store, cx| {
12740            for buffer_handle in buffer_store.buffers() {
12741                let buffer = buffer_handle.read(cx);
12742                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12743                let Some(abs_path) = abs_path else {
12744                    continue;
12745                };
12746                affected_abs_paths.insert(abs_path);
12747            }
12748        });
12749
12750        let local = self.as_local().context("Expected LSP Store to be local")?;
12751        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12752            let Some(worktree) = self
12753                .worktree_store
12754                .read(cx)
12755                .worktree_for_id(*worktree_id, cx)
12756            else {
12757                continue;
12758            };
12759
12760            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12761                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12762                    let has_matching_registration =
12763                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12764                            entry.diagnostic.registration_id.as_ref()
12765                                == Some(&cleared_registration_id)
12766                        });
12767                    if has_matching_registration {
12768                        let abs_path = worktree.read(cx).absolutize(rel_path);
12769                        affected_abs_paths.insert(abs_path);
12770                    }
12771                }
12772            }
12773        }
12774
12775        if affected_abs_paths.is_empty() {
12776            return Ok(());
12777        }
12778
12779        // Send a fake diagnostic update which clears the state for the registration ID
12780        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12781            affected_abs_paths
12782                .into_iter()
12783                .map(|abs_path| DocumentDiagnosticsUpdate {
12784                    diagnostics: DocumentDiagnostics {
12785                        diagnostics: Vec::new(),
12786                        document_abs_path: abs_path,
12787                        version: None,
12788                    },
12789                    result_id: None,
12790                    registration_id: Some(cleared_registration_id.clone()),
12791                    server_id,
12792                    disk_based_sources: Cow::Borrowed(&[]),
12793                })
12794                .collect();
12795
12796        let merge_registration_id = cleared_registration_id.clone();
12797        self.merge_diagnostic_entries(
12798            clears,
12799            move |_, diagnostic, _| {
12800                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12801                    diagnostic.registration_id != Some(merge_registration_id.clone())
12802                } else {
12803                    true
12804                }
12805            },
12806            cx,
12807        )?;
12808
12809        Ok(())
12810    }
12811
12812    async fn deduplicate_range_based_lsp_requests<T>(
12813        lsp_store: &Entity<Self>,
12814        server_id: Option<LanguageServerId>,
12815        lsp_request_id: LspRequestId,
12816        proto_request: &T::ProtoRequest,
12817        range: Range<Anchor>,
12818        cx: &mut AsyncApp,
12819    ) -> Result<()>
12820    where
12821        T: LspCommand,
12822        T::ProtoRequest: proto::LspRequestMessage,
12823    {
12824        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12825        let version = deserialize_version(proto_request.buffer_version());
12826        let buffer = lsp_store.update(cx, |this, cx| {
12827            this.buffer_store.read(cx).get_existing(buffer_id)
12828        })?;
12829        buffer
12830            .update(cx, |buffer, _| buffer.wait_for_version(version))
12831            .await?;
12832        lsp_store.update(cx, |lsp_store, cx| {
12833            let buffer_snapshot = buffer.read(cx).snapshot();
12834            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12835            let chunks_queried_for = lsp_data
12836                .inlay_hints
12837                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12838                .collect::<Vec<_>>();
12839            match chunks_queried_for.as_slice() {
12840                &[chunk] => {
12841                    let key = LspKey {
12842                        request_type: TypeId::of::<T>(),
12843                        server_queried: server_id,
12844                    };
12845                    let previous_request = lsp_data
12846                        .chunk_lsp_requests
12847                        .entry(key)
12848                        .or_default()
12849                        .insert(chunk, lsp_request_id);
12850                    if let Some((previous_request, running_requests)) =
12851                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12852                    {
12853                        running_requests.remove(&previous_request);
12854                    }
12855                }
12856                _ambiguous_chunks => {
12857                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12858                    // there, a buffer version-based check will be performed and outdated requests discarded.
12859                }
12860            }
12861            anyhow::Ok(())
12862        })?;
12863
12864        Ok(())
12865    }
12866
12867    async fn query_lsp_locally<T>(
12868        lsp_store: Entity<Self>,
12869        for_server_id: Option<LanguageServerId>,
12870        sender_id: proto::PeerId,
12871        lsp_request_id: LspRequestId,
12872        proto_request: T::ProtoRequest,
12873        position: Option<Anchor>,
12874        cx: &mut AsyncApp,
12875    ) -> Result<()>
12876    where
12877        T: LspCommand + Clone,
12878        T::ProtoRequest: proto::LspRequestMessage,
12879        <T::ProtoRequest as proto::RequestMessage>::Response:
12880            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12881    {
12882        let (buffer_version, buffer) =
12883            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12884        let request =
12885            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12886        let key = LspKey {
12887            request_type: TypeId::of::<T>(),
12888            server_queried: for_server_id,
12889        };
12890        lsp_store.update(cx, |lsp_store, cx| {
12891            let request_task = match for_server_id {
12892                Some(server_id) => {
12893                    let server_task = lsp_store.request_lsp(
12894                        buffer.clone(),
12895                        LanguageServerToQuery::Other(server_id),
12896                        request.clone(),
12897                        cx,
12898                    );
12899                    cx.background_spawn(async move {
12900                        let mut responses = Vec::new();
12901                        match server_task.await {
12902                            Ok(response) => responses.push((server_id, response)),
12903                            // rust-analyzer likes to error with this when its still loading up
12904                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12905                            Err(e) => log::error!(
12906                                "Error handling response for request {request:?}: {e:#}"
12907                            ),
12908                        }
12909                        responses
12910                    })
12911                }
12912                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12913            };
12914            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12915            if T::ProtoRequest::stop_previous_requests() {
12916                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12917                    lsp_requests.clear();
12918                }
12919            }
12920            lsp_data.lsp_requests.entry(key).or_default().insert(
12921                lsp_request_id,
12922                cx.spawn(async move |lsp_store, cx| {
12923                    let response = request_task.await;
12924                    lsp_store
12925                        .update(cx, |lsp_store, cx| {
12926                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12927                            {
12928                                let response = response
12929                                    .into_iter()
12930                                    .map(|(server_id, response)| {
12931                                        (
12932                                            server_id.to_proto(),
12933                                            T::response_to_proto(
12934                                                response,
12935                                                lsp_store,
12936                                                sender_id,
12937                                                &buffer_version,
12938                                                cx,
12939                                            )
12940                                            .into(),
12941                                        )
12942                                    })
12943                                    .collect::<HashMap<_, _>>();
12944                                match client.send_lsp_response::<T::ProtoRequest>(
12945                                    project_id,
12946                                    lsp_request_id,
12947                                    response,
12948                                ) {
12949                                    Ok(()) => {}
12950                                    Err(e) => {
12951                                        log::error!("Failed to send LSP response: {e:#}",)
12952                                    }
12953                                }
12954                            }
12955                        })
12956                        .ok();
12957                }),
12958            );
12959        });
12960        Ok(())
12961    }
12962
12963    async fn wait_for_buffer_version<T>(
12964        lsp_store: &Entity<Self>,
12965        proto_request: &T::ProtoRequest,
12966        cx: &mut AsyncApp,
12967    ) -> Result<(Global, Entity<Buffer>)>
12968    where
12969        T: LspCommand,
12970        T::ProtoRequest: proto::LspRequestMessage,
12971    {
12972        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12973        let version = deserialize_version(proto_request.buffer_version());
12974        let buffer = lsp_store.update(cx, |this, cx| {
12975            this.buffer_store.read(cx).get_existing(buffer_id)
12976        })?;
12977        buffer
12978            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
12979            .await?;
12980        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
12981        Ok((buffer_version, buffer))
12982    }
12983
12984    fn take_text_document_sync_options(
12985        capabilities: &mut lsp::ServerCapabilities,
12986    ) -> lsp::TextDocumentSyncOptions {
12987        match capabilities.text_document_sync.take() {
12988            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12989            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12990                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12991                sync_options.change = Some(sync_kind);
12992                sync_options
12993            }
12994            None => lsp::TextDocumentSyncOptions::default(),
12995        }
12996    }
12997
12998    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12999        self.downstream_client.clone()
13000    }
13001
13002    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13003        self.worktree_store.clone()
13004    }
13005
13006    /// Gets what's stored in the LSP data for the given buffer.
13007    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13008        self.lsp_data.get_mut(&buffer_id)
13009    }
13010
13011    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13012    /// new [`BufferLspData`] will be created to replace the previous state.
13013    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13014        let (buffer_id, buffer_version) =
13015            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13016        let lsp_data = self
13017            .lsp_data
13018            .entry(buffer_id)
13019            .or_insert_with(|| BufferLspData::new(buffer, cx));
13020        if buffer_version.changed_since(&lsp_data.buffer_version) {
13021            // To send delta requests for semantic tokens, the previous tokens
13022            // need to be kept between buffer changes.
13023            let semantic_tokens = lsp_data.semantic_tokens.take();
13024            *lsp_data = BufferLspData::new(buffer, cx);
13025            lsp_data.semantic_tokens = semantic_tokens;
13026        }
13027        lsp_data
13028    }
13029}
13030
13031// Registration with registerOptions as null, should fallback to true.
13032// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13033fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13034    reg: lsp::Registration,
13035) -> Result<OneOf<bool, T>> {
13036    Ok(match reg.register_options {
13037        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13038        None => OneOf::Left(true),
13039    })
13040}
13041
13042fn subscribe_to_binary_statuses(
13043    languages: &Arc<LanguageRegistry>,
13044    cx: &mut Context<'_, LspStore>,
13045) -> Task<()> {
13046    let mut server_statuses = languages.language_server_binary_statuses();
13047    cx.spawn(async move |lsp_store, cx| {
13048        while let Some((server_name, binary_status)) = server_statuses.next().await {
13049            if lsp_store
13050                .update(cx, |_, cx| {
13051                    let mut message = None;
13052                    let binary_status = match binary_status {
13053                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13054                        BinaryStatus::CheckingForUpdate => {
13055                            proto::ServerBinaryStatus::CheckingForUpdate
13056                        }
13057                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13058                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13059                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13060                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13061                        BinaryStatus::Failed { error } => {
13062                            message = Some(error);
13063                            proto::ServerBinaryStatus::Failed
13064                        }
13065                    };
13066                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13067                        // Binary updates are about the binary that might not have any language server id at that point.
13068                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13069                        language_server_id: LanguageServerId(0),
13070                        name: Some(server_name),
13071                        message: proto::update_language_server::Variant::StatusUpdate(
13072                            proto::StatusUpdate {
13073                                message,
13074                                status: Some(proto::status_update::Status::Binary(
13075                                    binary_status as i32,
13076                                )),
13077                            },
13078                        ),
13079                    });
13080                })
13081                .is_err()
13082            {
13083                break;
13084            }
13085        }
13086    })
13087}
13088
13089fn lsp_workspace_diagnostics_refresh(
13090    registration_id: Option<String>,
13091    options: DiagnosticServerCapabilities,
13092    server: Arc<LanguageServer>,
13093    cx: &mut Context<'_, LspStore>,
13094) -> Option<WorkspaceRefreshTask> {
13095    let identifier = workspace_diagnostic_identifier(&options)?;
13096    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13097
13098    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13099    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13100    refresh_tx.try_send(()).ok();
13101
13102    let request_timeout = ProjectSettings::get_global(cx)
13103        .global_lsp_settings
13104        .get_request_timeout();
13105
13106    // 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.
13107    // This allows users to increase the duration if need be
13108    let timeout = if request_timeout != Duration::ZERO {
13109        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13110    } else {
13111        request_timeout
13112    };
13113
13114    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13115        let mut attempts = 0;
13116        let max_attempts = 50;
13117        let mut requests = 0;
13118
13119        loop {
13120            let Some(()) = refresh_rx.recv().await else {
13121                return;
13122            };
13123
13124            'request: loop {
13125                requests += 1;
13126                if attempts > max_attempts {
13127                    log::error!(
13128                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13129                    );
13130                    return;
13131                }
13132                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13133                cx.background_executor()
13134                    .timer(Duration::from_millis(backoff_millis))
13135                    .await;
13136                attempts += 1;
13137
13138                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13139                    lsp_store
13140                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13141                        .into_iter()
13142                        .filter_map(|(abs_path, result_id)| {
13143                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13144                            Some(lsp::PreviousResultId {
13145                                uri,
13146                                value: result_id.to_string(),
13147                            })
13148                        })
13149                        .collect()
13150                }) else {
13151                    return;
13152                };
13153
13154                let token = if let Some(registration_id) = &registration_id {
13155                    format!(
13156                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13157                        server.server_id(),
13158                    )
13159                } else {
13160                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13161                };
13162
13163                progress_rx.try_recv().ok();
13164                let timer = server.request_timer(timeout).fuse();
13165                let progress = pin!(progress_rx.recv().fuse());
13166                let response_result = server
13167                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13168                        lsp::WorkspaceDiagnosticParams {
13169                            previous_result_ids,
13170                            identifier: identifier.clone(),
13171                            work_done_progress_params: Default::default(),
13172                            partial_result_params: lsp::PartialResultParams {
13173                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13174                            },
13175                        },
13176                        select(timer, progress).then(|either| match either {
13177                            Either::Left((message, ..)) => ready(message).left_future(),
13178                            Either::Right(..) => pending::<String>().right_future(),
13179                        }),
13180                    )
13181                    .await;
13182
13183                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13184                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13185                match response_result {
13186                    ConnectionResult::Timeout => {
13187                        log::error!("Timeout during workspace diagnostics pull");
13188                        continue 'request;
13189                    }
13190                    ConnectionResult::ConnectionReset => {
13191                        log::error!("Server closed a workspace diagnostics pull request");
13192                        continue 'request;
13193                    }
13194                    ConnectionResult::Result(Err(e)) => {
13195                        log::error!("Error during workspace diagnostics pull: {e:#}");
13196                        break 'request;
13197                    }
13198                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13199                        attempts = 0;
13200                        if lsp_store
13201                            .update(cx, |lsp_store, cx| {
13202                                lsp_store.apply_workspace_diagnostic_report(
13203                                    server.server_id(),
13204                                    pulled_diagnostics,
13205                                    registration_id_shared.clone(),
13206                                    cx,
13207                                )
13208                            })
13209                            .is_err()
13210                        {
13211                            return;
13212                        }
13213                        break 'request;
13214                    }
13215                }
13216            }
13217        }
13218    });
13219
13220    Some(WorkspaceRefreshTask {
13221        refresh_tx,
13222        progress_tx,
13223        task: workspace_query_language_server,
13224    })
13225}
13226
13227fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13228    match &options {
13229        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13230            .identifier
13231            .as_deref()
13232            .map(SharedString::new),
13233        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13234            let diagnostic_options = &registration_options.diagnostic_options;
13235            diagnostic_options
13236                .identifier
13237                .as_deref()
13238                .map(SharedString::new)
13239        }
13240    }
13241}
13242
13243fn workspace_diagnostic_identifier(
13244    options: &DiagnosticServerCapabilities,
13245) -> Option<Option<String>> {
13246    match &options {
13247        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13248            if !diagnostic_options.workspace_diagnostics {
13249                return None;
13250            }
13251            Some(diagnostic_options.identifier.clone())
13252        }
13253        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13254            let diagnostic_options = &registration_options.diagnostic_options;
13255            if !diagnostic_options.workspace_diagnostics {
13256                return None;
13257            }
13258            Some(diagnostic_options.identifier.clone())
13259        }
13260    }
13261}
13262
13263fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13264    let CompletionSource::BufferWord {
13265        word_range,
13266        resolved,
13267    } = &mut completion.source
13268    else {
13269        return;
13270    };
13271    if *resolved {
13272        return;
13273    }
13274
13275    if completion.new_text
13276        != snapshot
13277            .text_for_range(word_range.clone())
13278            .collect::<String>()
13279    {
13280        return;
13281    }
13282
13283    let mut offset = 0;
13284    for chunk in snapshot.chunks(word_range.clone(), true) {
13285        let end_offset = offset + chunk.text.len();
13286        if let Some(highlight_id) = chunk.syntax_highlight_id {
13287            completion
13288                .label
13289                .runs
13290                .push((offset..end_offset, highlight_id));
13291        }
13292        offset = end_offset;
13293    }
13294    *resolved = true;
13295}
13296
13297impl EventEmitter<LspStoreEvent> for LspStore {}
13298
13299fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13300    hover
13301        .contents
13302        .retain(|hover_block| !hover_block.text.trim().is_empty());
13303    if hover.contents.is_empty() {
13304        None
13305    } else {
13306        Some(hover)
13307    }
13308}
13309
13310async fn populate_labels_for_completions(
13311    new_completions: Vec<CoreCompletion>,
13312    language: Option<Arc<Language>>,
13313    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13314) -> Vec<Completion> {
13315    let lsp_completions = new_completions
13316        .iter()
13317        .filter_map(|new_completion| {
13318            new_completion
13319                .source
13320                .lsp_completion(true)
13321                .map(|lsp_completion| lsp_completion.into_owned())
13322        })
13323        .collect::<Vec<_>>();
13324
13325    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13326        lsp_adapter
13327            .labels_for_completions(&lsp_completions, language)
13328            .await
13329            .log_err()
13330            .unwrap_or_default()
13331    } else {
13332        Vec::new()
13333    }
13334    .into_iter()
13335    .fuse();
13336
13337    let mut completions = Vec::new();
13338    for completion in new_completions {
13339        match completion.source.lsp_completion(true) {
13340            Some(lsp_completion) => {
13341                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13342
13343                let mut label = labels.next().flatten().unwrap_or_else(|| {
13344                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13345                });
13346                ensure_uniform_list_compatible_label(&mut label);
13347                completions.push(Completion {
13348                    label,
13349                    documentation,
13350                    replace_range: completion.replace_range,
13351                    new_text: completion.new_text,
13352                    insert_text_mode: lsp_completion.insert_text_mode,
13353                    source: completion.source,
13354                    icon_path: None,
13355                    confirm: None,
13356                    match_start: None,
13357                    snippet_deduplication_key: None,
13358                });
13359            }
13360            None => {
13361                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13362                ensure_uniform_list_compatible_label(&mut label);
13363                completions.push(Completion {
13364                    label,
13365                    documentation: None,
13366                    replace_range: completion.replace_range,
13367                    new_text: completion.new_text,
13368                    source: completion.source,
13369                    insert_text_mode: None,
13370                    icon_path: None,
13371                    confirm: None,
13372                    match_start: None,
13373                    snippet_deduplication_key: None,
13374                });
13375            }
13376        }
13377    }
13378    completions
13379}
13380
13381#[derive(Debug)]
13382pub enum LanguageServerToQuery {
13383    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13384    FirstCapable,
13385    /// Query a specific language server.
13386    Other(LanguageServerId),
13387}
13388
13389#[derive(Default)]
13390struct RenamePathsWatchedForServer {
13391    did_rename: Vec<RenameActionPredicate>,
13392    will_rename: Vec<RenameActionPredicate>,
13393}
13394
13395impl RenamePathsWatchedForServer {
13396    fn with_did_rename_patterns(
13397        mut self,
13398        did_rename: Option<&FileOperationRegistrationOptions>,
13399    ) -> Self {
13400        if let Some(did_rename) = did_rename {
13401            self.did_rename = did_rename
13402                .filters
13403                .iter()
13404                .filter_map(|filter| filter.try_into().log_err())
13405                .collect();
13406        }
13407        self
13408    }
13409    fn with_will_rename_patterns(
13410        mut self,
13411        will_rename: Option<&FileOperationRegistrationOptions>,
13412    ) -> Self {
13413        if let Some(will_rename) = will_rename {
13414            self.will_rename = will_rename
13415                .filters
13416                .iter()
13417                .filter_map(|filter| filter.try_into().log_err())
13418                .collect();
13419        }
13420        self
13421    }
13422
13423    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13424        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13425    }
13426    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13427        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13428    }
13429}
13430
13431impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13432    type Error = globset::Error;
13433    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13434        Ok(Self {
13435            kind: ops.pattern.matches.clone(),
13436            glob: GlobBuilder::new(&ops.pattern.glob)
13437                .case_insensitive(
13438                    ops.pattern
13439                        .options
13440                        .as_ref()
13441                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13442                )
13443                .build()?
13444                .compile_matcher(),
13445        })
13446    }
13447}
13448struct RenameActionPredicate {
13449    glob: GlobMatcher,
13450    kind: Option<FileOperationPatternKind>,
13451}
13452
13453impl RenameActionPredicate {
13454    // Returns true if language server should be notified
13455    fn eval(&self, path: &str, is_dir: bool) -> bool {
13456        self.kind.as_ref().is_none_or(|kind| {
13457            let expected_kind = if is_dir {
13458                FileOperationPatternKind::Folder
13459            } else {
13460                FileOperationPatternKind::File
13461            };
13462            kind == &expected_kind
13463        }) && self.glob.is_match(path)
13464    }
13465}
13466
13467#[derive(Default)]
13468struct LanguageServerWatchedPaths {
13469    worktree_paths: HashMap<WorktreeId, GlobSet>,
13470    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13471}
13472
13473#[derive(Default)]
13474struct LanguageServerWatchedPathsBuilder {
13475    worktree_paths: HashMap<WorktreeId, GlobSet>,
13476    abs_paths: HashMap<Arc<Path>, GlobSet>,
13477}
13478
13479impl LanguageServerWatchedPathsBuilder {
13480    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13481        self.worktree_paths.insert(worktree_id, glob_set);
13482    }
13483    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13484        self.abs_paths.insert(path, glob_set);
13485    }
13486    fn build(
13487        self,
13488        fs: Arc<dyn Fs>,
13489        language_server_id: LanguageServerId,
13490        cx: &mut Context<LspStore>,
13491    ) -> LanguageServerWatchedPaths {
13492        let lsp_store = cx.weak_entity();
13493
13494        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13495        let abs_paths = self
13496            .abs_paths
13497            .into_iter()
13498            .map(|(abs_path, globset)| {
13499                let task = cx.spawn({
13500                    let abs_path = abs_path.clone();
13501                    let fs = fs.clone();
13502
13503                    let lsp_store = lsp_store.clone();
13504                    async move |_, cx| {
13505                        maybe!(async move {
13506                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13507                            while let Some(update) = push_updates.0.next().await {
13508                                let action = lsp_store
13509                                    .update(cx, |this, _| {
13510                                        let Some(local) = this.as_local() else {
13511                                            return ControlFlow::Break(());
13512                                        };
13513                                        let Some(watcher) = local
13514                                            .language_server_watched_paths
13515                                            .get(&language_server_id)
13516                                        else {
13517                                            return ControlFlow::Break(());
13518                                        };
13519                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13520                                            "Watched abs path is not registered with a watcher",
13521                                        );
13522                                        let matching_entries = update
13523                                            .into_iter()
13524                                            .filter(|event| globs.is_match(&event.path))
13525                                            .collect::<Vec<_>>();
13526                                        this.lsp_notify_abs_paths_changed(
13527                                            language_server_id,
13528                                            matching_entries,
13529                                        );
13530                                        ControlFlow::Continue(())
13531                                    })
13532                                    .ok()?;
13533
13534                                if action.is_break() {
13535                                    break;
13536                                }
13537                            }
13538                            Some(())
13539                        })
13540                        .await;
13541                    }
13542                });
13543                (abs_path, (globset, task))
13544            })
13545            .collect();
13546        LanguageServerWatchedPaths {
13547            worktree_paths: self.worktree_paths,
13548            abs_paths,
13549        }
13550    }
13551}
13552
13553struct LspBufferSnapshot {
13554    version: i32,
13555    snapshot: TextBufferSnapshot,
13556}
13557
13558/// A prompt requested by LSP server.
13559#[derive(Clone, Debug)]
13560pub struct LanguageServerPromptRequest {
13561    pub id: usize,
13562    pub level: PromptLevel,
13563    pub message: String,
13564    pub actions: Vec<MessageActionItem>,
13565    pub lsp_name: String,
13566    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13567}
13568
13569impl LanguageServerPromptRequest {
13570    pub fn new(
13571        level: PromptLevel,
13572        message: String,
13573        actions: Vec<MessageActionItem>,
13574        lsp_name: String,
13575        response_channel: smol::channel::Sender<MessageActionItem>,
13576    ) -> Self {
13577        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13578        LanguageServerPromptRequest {
13579            id,
13580            level,
13581            message,
13582            actions,
13583            lsp_name,
13584            response_channel,
13585        }
13586    }
13587    pub async fn respond(self, index: usize) -> Option<()> {
13588        if let Some(response) = self.actions.into_iter().nth(index) {
13589            self.response_channel.send(response).await.ok()
13590        } else {
13591            None
13592        }
13593    }
13594
13595    #[cfg(any(test, feature = "test-support"))]
13596    pub fn test(
13597        level: PromptLevel,
13598        message: String,
13599        actions: Vec<MessageActionItem>,
13600        lsp_name: String,
13601    ) -> Self {
13602        let (tx, _rx) = smol::channel::unbounded();
13603        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13604    }
13605}
13606impl PartialEq for LanguageServerPromptRequest {
13607    fn eq(&self, other: &Self) -> bool {
13608        self.message == other.message && self.actions == other.actions
13609    }
13610}
13611
13612#[derive(Clone, Debug, PartialEq)]
13613pub enum LanguageServerLogType {
13614    Log(MessageType),
13615    Trace { verbose_info: Option<String> },
13616    Rpc { received: bool },
13617}
13618
13619impl LanguageServerLogType {
13620    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13621        match self {
13622            Self::Log(log_type) => {
13623                use proto::log_message::LogLevel;
13624                let level = match *log_type {
13625                    MessageType::ERROR => LogLevel::Error,
13626                    MessageType::WARNING => LogLevel::Warning,
13627                    MessageType::INFO => LogLevel::Info,
13628                    MessageType::LOG => LogLevel::Log,
13629                    other => {
13630                        log::warn!("Unknown lsp log message type: {other:?}");
13631                        LogLevel::Log
13632                    }
13633                };
13634                proto::language_server_log::LogType::Log(proto::LogMessage {
13635                    level: level as i32,
13636                })
13637            }
13638            Self::Trace { verbose_info } => {
13639                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13640                    verbose_info: verbose_info.to_owned(),
13641                })
13642            }
13643            Self::Rpc { received } => {
13644                let kind = if *received {
13645                    proto::rpc_message::Kind::Received
13646                } else {
13647                    proto::rpc_message::Kind::Sent
13648                };
13649                let kind = kind as i32;
13650                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13651            }
13652        }
13653    }
13654
13655    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13656        use proto::log_message::LogLevel;
13657        use proto::rpc_message;
13658        match log_type {
13659            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13660                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13661                    LogLevel::Error => MessageType::ERROR,
13662                    LogLevel::Warning => MessageType::WARNING,
13663                    LogLevel::Info => MessageType::INFO,
13664                    LogLevel::Log => MessageType::LOG,
13665                },
13666            ),
13667            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13668                verbose_info: trace_message.verbose_info,
13669            },
13670            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13671                received: match rpc_message::Kind::from_i32(message.kind)
13672                    .unwrap_or(rpc_message::Kind::Received)
13673                {
13674                    rpc_message::Kind::Received => true,
13675                    rpc_message::Kind::Sent => false,
13676                },
13677            },
13678        }
13679    }
13680}
13681
13682pub struct WorkspaceRefreshTask {
13683    refresh_tx: mpsc::Sender<()>,
13684    progress_tx: mpsc::Sender<()>,
13685    #[allow(dead_code)]
13686    task: Task<()>,
13687}
13688
13689pub enum LanguageServerState {
13690    Starting {
13691        startup: Task<Option<Arc<LanguageServer>>>,
13692        /// List of language servers that will be added to the workspace once it's initialization completes.
13693        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13694    },
13695
13696    Running {
13697        adapter: Arc<CachedLspAdapter>,
13698        server: Arc<LanguageServer>,
13699        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13700        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13701    },
13702}
13703
13704impl LanguageServerState {
13705    fn add_workspace_folder(&self, uri: Uri) {
13706        match self {
13707            LanguageServerState::Starting {
13708                pending_workspace_folders,
13709                ..
13710            } => {
13711                pending_workspace_folders.lock().insert(uri);
13712            }
13713            LanguageServerState::Running { server, .. } => {
13714                server.add_workspace_folder(uri);
13715            }
13716        }
13717    }
13718    fn _remove_workspace_folder(&self, uri: Uri) {
13719        match self {
13720            LanguageServerState::Starting {
13721                pending_workspace_folders,
13722                ..
13723            } => {
13724                pending_workspace_folders.lock().remove(&uri);
13725            }
13726            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13727        }
13728    }
13729}
13730
13731impl std::fmt::Debug for LanguageServerState {
13732    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13733        match self {
13734            LanguageServerState::Starting { .. } => {
13735                f.debug_struct("LanguageServerState::Starting").finish()
13736            }
13737            LanguageServerState::Running { .. } => {
13738                f.debug_struct("LanguageServerState::Running").finish()
13739            }
13740        }
13741    }
13742}
13743
13744#[derive(Clone, Debug, Serialize)]
13745pub struct LanguageServerProgress {
13746    pub is_disk_based_diagnostics_progress: bool,
13747    pub is_cancellable: bool,
13748    pub title: Option<String>,
13749    pub message: Option<String>,
13750    pub percentage: Option<usize>,
13751    #[serde(skip_serializing)]
13752    pub last_update_at: Instant,
13753}
13754
13755#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13756pub struct DiagnosticSummary {
13757    pub error_count: usize,
13758    pub warning_count: usize,
13759}
13760
13761impl DiagnosticSummary {
13762    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13763        let mut this = Self {
13764            error_count: 0,
13765            warning_count: 0,
13766        };
13767
13768        for entry in diagnostics {
13769            if entry.diagnostic.is_primary {
13770                match entry.diagnostic.severity {
13771                    DiagnosticSeverity::ERROR => this.error_count += 1,
13772                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13773                    _ => {}
13774                }
13775            }
13776        }
13777
13778        this
13779    }
13780
13781    pub fn is_empty(&self) -> bool {
13782        self.error_count == 0 && self.warning_count == 0
13783    }
13784
13785    pub fn to_proto(
13786        self,
13787        language_server_id: LanguageServerId,
13788        path: &RelPath,
13789    ) -> proto::DiagnosticSummary {
13790        proto::DiagnosticSummary {
13791            path: path.to_proto(),
13792            language_server_id: language_server_id.0 as u64,
13793            error_count: self.error_count as u32,
13794            warning_count: self.warning_count as u32,
13795        }
13796    }
13797}
13798
13799#[derive(Clone, Debug)]
13800pub enum CompletionDocumentation {
13801    /// There is no documentation for this completion.
13802    Undocumented,
13803    /// A single line of documentation.
13804    SingleLine(SharedString),
13805    /// Multiple lines of plain text documentation.
13806    MultiLinePlainText(SharedString),
13807    /// Markdown documentation.
13808    MultiLineMarkdown(SharedString),
13809    /// Both single line and multiple lines of plain text documentation.
13810    SingleLineAndMultiLinePlainText {
13811        single_line: SharedString,
13812        plain_text: Option<SharedString>,
13813    },
13814}
13815
13816impl CompletionDocumentation {
13817    #[cfg(any(test, feature = "test-support"))]
13818    pub fn text(&self) -> SharedString {
13819        match self {
13820            CompletionDocumentation::Undocumented => "".into(),
13821            CompletionDocumentation::SingleLine(s) => s.clone(),
13822            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13823            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13824            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13825                single_line.clone()
13826            }
13827        }
13828    }
13829}
13830
13831impl From<lsp::Documentation> for CompletionDocumentation {
13832    fn from(docs: lsp::Documentation) -> Self {
13833        match docs {
13834            lsp::Documentation::String(text) => {
13835                if text.lines().count() <= 1 {
13836                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13837                } else {
13838                    CompletionDocumentation::MultiLinePlainText(text.into())
13839                }
13840            }
13841
13842            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13843                lsp::MarkupKind::PlainText => {
13844                    if value.lines().count() <= 1 {
13845                        CompletionDocumentation::SingleLine(value.into())
13846                    } else {
13847                        CompletionDocumentation::MultiLinePlainText(value.into())
13848                    }
13849                }
13850
13851                lsp::MarkupKind::Markdown => {
13852                    CompletionDocumentation::MultiLineMarkdown(value.into())
13853                }
13854            },
13855        }
13856    }
13857}
13858
13859pub enum ResolvedHint {
13860    Resolved(InlayHint),
13861    Resolving(Shared<Task<()>>),
13862}
13863
13864pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13865    glob.components()
13866        .take_while(|component| match component {
13867            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13868            _ => true,
13869        })
13870        .collect()
13871}
13872
13873pub struct SshLspAdapter {
13874    name: LanguageServerName,
13875    binary: LanguageServerBinary,
13876    initialization_options: Option<String>,
13877    code_action_kinds: Option<Vec<CodeActionKind>>,
13878}
13879
13880impl SshLspAdapter {
13881    pub fn new(
13882        name: LanguageServerName,
13883        binary: LanguageServerBinary,
13884        initialization_options: Option<String>,
13885        code_action_kinds: Option<String>,
13886    ) -> Self {
13887        Self {
13888            name,
13889            binary,
13890            initialization_options,
13891            code_action_kinds: code_action_kinds
13892                .as_ref()
13893                .and_then(|c| serde_json::from_str(c).ok()),
13894        }
13895    }
13896}
13897
13898impl LspInstaller for SshLspAdapter {
13899    type BinaryVersion = ();
13900    async fn check_if_user_installed(
13901        &self,
13902        _: &dyn LspAdapterDelegate,
13903        _: Option<Toolchain>,
13904        _: &AsyncApp,
13905    ) -> Option<LanguageServerBinary> {
13906        Some(self.binary.clone())
13907    }
13908
13909    async fn cached_server_binary(
13910        &self,
13911        _: PathBuf,
13912        _: &dyn LspAdapterDelegate,
13913    ) -> Option<LanguageServerBinary> {
13914        None
13915    }
13916
13917    async fn fetch_latest_server_version(
13918        &self,
13919        _: &dyn LspAdapterDelegate,
13920        _: bool,
13921        _: &mut AsyncApp,
13922    ) -> Result<()> {
13923        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13924    }
13925
13926    async fn fetch_server_binary(
13927        &self,
13928        _: (),
13929        _: PathBuf,
13930        _: &dyn LspAdapterDelegate,
13931    ) -> Result<LanguageServerBinary> {
13932        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13933    }
13934}
13935
13936#[async_trait(?Send)]
13937impl LspAdapter for SshLspAdapter {
13938    fn name(&self) -> LanguageServerName {
13939        self.name.clone()
13940    }
13941
13942    async fn initialization_options(
13943        self: Arc<Self>,
13944        _: &Arc<dyn LspAdapterDelegate>,
13945    ) -> Result<Option<serde_json::Value>> {
13946        let Some(options) = &self.initialization_options else {
13947            return Ok(None);
13948        };
13949        let result = serde_json::from_str(options)?;
13950        Ok(result)
13951    }
13952
13953    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13954        self.code_action_kinds.clone()
13955    }
13956}
13957
13958pub fn language_server_settings<'a>(
13959    delegate: &'a dyn LspAdapterDelegate,
13960    language: &LanguageServerName,
13961    cx: &'a App,
13962) -> Option<&'a LspSettings> {
13963    language_server_settings_for(
13964        SettingsLocation {
13965            worktree_id: delegate.worktree_id(),
13966            path: RelPath::empty(),
13967        },
13968        language,
13969        cx,
13970    )
13971}
13972
13973pub fn language_server_settings_for<'a>(
13974    location: SettingsLocation<'a>,
13975    language: &LanguageServerName,
13976    cx: &'a App,
13977) -> Option<&'a LspSettings> {
13978    ProjectSettings::get(Some(location), cx).lsp.get(language)
13979}
13980
13981pub struct LocalLspAdapterDelegate {
13982    lsp_store: WeakEntity<LspStore>,
13983    worktree: worktree::Snapshot,
13984    fs: Arc<dyn Fs>,
13985    http_client: Arc<dyn HttpClient>,
13986    language_registry: Arc<LanguageRegistry>,
13987    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13988}
13989
13990impl LocalLspAdapterDelegate {
13991    pub fn new(
13992        language_registry: Arc<LanguageRegistry>,
13993        environment: &Entity<ProjectEnvironment>,
13994        lsp_store: WeakEntity<LspStore>,
13995        worktree: &Entity<Worktree>,
13996        http_client: Arc<dyn HttpClient>,
13997        fs: Arc<dyn Fs>,
13998        cx: &mut App,
13999    ) -> Arc<Self> {
14000        let load_shell_env_task =
14001            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14002
14003        Arc::new(Self {
14004            lsp_store,
14005            worktree: worktree.read(cx).snapshot(),
14006            fs,
14007            http_client,
14008            language_registry,
14009            load_shell_env_task,
14010        })
14011    }
14012
14013    pub fn from_local_lsp(
14014        local: &LocalLspStore,
14015        worktree: &Entity<Worktree>,
14016        cx: &mut App,
14017    ) -> Arc<Self> {
14018        Self::new(
14019            local.languages.clone(),
14020            &local.environment,
14021            local.weak.clone(),
14022            worktree,
14023            local.http_client.clone(),
14024            local.fs.clone(),
14025            cx,
14026        )
14027    }
14028}
14029
14030#[async_trait]
14031impl LspAdapterDelegate for LocalLspAdapterDelegate {
14032    fn show_notification(&self, message: &str, cx: &mut App) {
14033        self.lsp_store
14034            .update(cx, |_, cx| {
14035                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14036            })
14037            .ok();
14038    }
14039
14040    fn http_client(&self) -> Arc<dyn HttpClient> {
14041        self.http_client.clone()
14042    }
14043
14044    fn worktree_id(&self) -> WorktreeId {
14045        self.worktree.id()
14046    }
14047
14048    fn worktree_root_path(&self) -> &Path {
14049        self.worktree.abs_path().as_ref()
14050    }
14051
14052    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14053        self.worktree.resolve_executable_path(path)
14054    }
14055
14056    async fn shell_env(&self) -> HashMap<String, String> {
14057        let task = self.load_shell_env_task.clone();
14058        task.await.unwrap_or_default()
14059    }
14060
14061    async fn npm_package_installed_version(
14062        &self,
14063        package_name: &str,
14064    ) -> Result<Option<(PathBuf, Version)>> {
14065        let local_package_directory = self.worktree_root_path();
14066        let node_modules_directory = local_package_directory.join("node_modules");
14067
14068        if let Some(version) =
14069            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14070        {
14071            return Ok(Some((node_modules_directory, version)));
14072        }
14073        let Some(npm) = self.which("npm".as_ref()).await else {
14074            log::warn!(
14075                "Failed to find npm executable for {:?}",
14076                local_package_directory
14077            );
14078            return Ok(None);
14079        };
14080
14081        let env = self.shell_env().await;
14082        let output = util::command::new_smol_command(&npm)
14083            .args(["root", "-g"])
14084            .envs(env)
14085            .current_dir(local_package_directory)
14086            .output()
14087            .await?;
14088        let global_node_modules =
14089            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14090
14091        if let Some(version) =
14092            read_package_installed_version(global_node_modules.clone(), package_name).await?
14093        {
14094            return Ok(Some((global_node_modules, version)));
14095        }
14096        return Ok(None);
14097    }
14098
14099    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14100        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14101        if self.fs.is_file(&worktree_abs_path).await {
14102            worktree_abs_path.pop();
14103        }
14104
14105        let env = self.shell_env().await;
14106
14107        let shell_path = env.get("PATH").cloned();
14108
14109        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14110    }
14111
14112    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14113        let mut working_dir = self.worktree_root_path().to_path_buf();
14114        if self.fs.is_file(&working_dir).await {
14115            working_dir.pop();
14116        }
14117        let output = util::command::new_smol_command(&command.path)
14118            .args(command.arguments)
14119            .envs(command.env.clone().unwrap_or_default())
14120            .current_dir(working_dir)
14121            .output()
14122            .await?;
14123
14124        anyhow::ensure!(
14125            output.status.success(),
14126            "{}, stdout: {:?}, stderr: {:?}",
14127            output.status,
14128            String::from_utf8_lossy(&output.stdout),
14129            String::from_utf8_lossy(&output.stderr)
14130        );
14131        Ok(())
14132    }
14133
14134    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14135        self.language_registry
14136            .update_lsp_binary_status(server_name, status);
14137    }
14138
14139    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14140        self.language_registry
14141            .all_lsp_adapters()
14142            .into_iter()
14143            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14144            .collect()
14145    }
14146
14147    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14148        let dir = self.language_registry.language_server_download_dir(name)?;
14149
14150        if !dir.exists() {
14151            smol::fs::create_dir_all(&dir)
14152                .await
14153                .context("failed to create container directory")
14154                .log_err()?;
14155        }
14156
14157        Some(dir)
14158    }
14159
14160    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14161        let entry = self
14162            .worktree
14163            .entry_for_path(path)
14164            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14165        let abs_path = self.worktree.absolutize(&entry.path);
14166        self.fs.load(&abs_path).await
14167    }
14168}
14169
14170async fn populate_labels_for_symbols(
14171    symbols: Vec<CoreSymbol>,
14172    language_registry: &Arc<LanguageRegistry>,
14173    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14174    output: &mut Vec<Symbol>,
14175) {
14176    #[allow(clippy::mutable_key_type)]
14177    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14178
14179    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14180    for symbol in symbols {
14181        let Some(file_name) = symbol.path.file_name() else {
14182            continue;
14183        };
14184        let language = language_registry
14185            .load_language_for_file_path(Path::new(file_name))
14186            .await
14187            .ok()
14188            .or_else(|| {
14189                unknown_paths.insert(file_name.into());
14190                None
14191            });
14192        symbols_by_language
14193            .entry(language)
14194            .or_default()
14195            .push(symbol);
14196    }
14197
14198    for unknown_path in unknown_paths {
14199        log::info!("no language found for symbol in file {unknown_path:?}");
14200    }
14201
14202    let mut label_params = Vec::new();
14203    for (language, mut symbols) in symbols_by_language {
14204        label_params.clear();
14205        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14206            name: mem::take(&mut symbol.name),
14207            kind: symbol.kind,
14208            container_name: symbol.container_name.take(),
14209        }));
14210
14211        let mut labels = Vec::new();
14212        if let Some(language) = language {
14213            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14214                language_registry
14215                    .lsp_adapters(&language.name())
14216                    .first()
14217                    .cloned()
14218            });
14219            if let Some(lsp_adapter) = lsp_adapter {
14220                labels = lsp_adapter
14221                    .labels_for_symbols(&label_params, &language)
14222                    .await
14223                    .log_err()
14224                    .unwrap_or_default();
14225            }
14226        }
14227
14228        for (
14229            (
14230                symbol,
14231                language::Symbol {
14232                    name,
14233                    container_name,
14234                    ..
14235                },
14236            ),
14237            label,
14238        ) in symbols
14239            .into_iter()
14240            .zip(label_params.drain(..))
14241            .zip(labels.into_iter().chain(iter::repeat(None)))
14242        {
14243            output.push(Symbol {
14244                language_server_name: symbol.language_server_name,
14245                source_worktree_id: symbol.source_worktree_id,
14246                source_language_server_id: symbol.source_language_server_id,
14247                path: symbol.path,
14248                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14249                name,
14250                kind: symbol.kind,
14251                range: symbol.range,
14252                container_name,
14253            });
14254        }
14255    }
14256}
14257
14258fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14259    match server.capabilities().text_document_sync.as_ref()? {
14260        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14261            // Server wants didSave but didn't specify includeText.
14262            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14263            // Server doesn't want didSave at all.
14264            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14265            // Server provided SaveOptions.
14266            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14267                Some(save_options.include_text.unwrap_or(false))
14268            }
14269        },
14270        // We do not have any save info. Kind affects didChange only.
14271        lsp::TextDocumentSyncCapability::Kind(_) => None,
14272    }
14273}
14274
14275/// Completion items are displayed in a `UniformList`.
14276/// Usually, those items are single-line strings, but in LSP responses,
14277/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14278/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14279/// 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,
14280/// breaking the completions menu presentation.
14281///
14282/// 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.
14283pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14284    let mut new_text = String::with_capacity(label.text.len());
14285    let mut offset_map = vec![0; label.text.len() + 1];
14286    let mut last_char_was_space = false;
14287    let mut new_idx = 0;
14288    let chars = label.text.char_indices().fuse();
14289    let mut newlines_removed = false;
14290
14291    for (idx, c) in chars {
14292        offset_map[idx] = new_idx;
14293
14294        match c {
14295            '\n' if last_char_was_space => {
14296                newlines_removed = true;
14297            }
14298            '\t' | ' ' if last_char_was_space => {}
14299            '\n' if !last_char_was_space => {
14300                new_text.push(' ');
14301                new_idx += 1;
14302                last_char_was_space = true;
14303                newlines_removed = true;
14304            }
14305            ' ' | '\t' => {
14306                new_text.push(' ');
14307                new_idx += 1;
14308                last_char_was_space = true;
14309            }
14310            _ => {
14311                new_text.push(c);
14312                new_idx += c.len_utf8();
14313                last_char_was_space = false;
14314            }
14315        }
14316    }
14317    offset_map[label.text.len()] = new_idx;
14318
14319    // Only modify the label if newlines were removed.
14320    if !newlines_removed {
14321        return;
14322    }
14323
14324    let last_index = new_idx;
14325    let mut run_ranges_errors = Vec::new();
14326    label.runs.retain_mut(|(range, _)| {
14327        match offset_map.get(range.start) {
14328            Some(&start) => range.start = start,
14329            None => {
14330                run_ranges_errors.push(range.clone());
14331                return false;
14332            }
14333        }
14334
14335        match offset_map.get(range.end) {
14336            Some(&end) => range.end = end,
14337            None => {
14338                run_ranges_errors.push(range.clone());
14339                range.end = last_index;
14340            }
14341        }
14342        true
14343    });
14344    if !run_ranges_errors.is_empty() {
14345        log::error!(
14346            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14347            label.text
14348        );
14349    }
14350
14351    let mut wrong_filter_range = None;
14352    if label.filter_range == (0..label.text.len()) {
14353        label.filter_range = 0..new_text.len();
14354    } else {
14355        let mut original_filter_range = Some(label.filter_range.clone());
14356        match offset_map.get(label.filter_range.start) {
14357            Some(&start) => label.filter_range.start = start,
14358            None => {
14359                wrong_filter_range = original_filter_range.take();
14360                label.filter_range.start = last_index;
14361            }
14362        }
14363
14364        match offset_map.get(label.filter_range.end) {
14365            Some(&end) => label.filter_range.end = end,
14366            None => {
14367                wrong_filter_range = original_filter_range.take();
14368                label.filter_range.end = last_index;
14369            }
14370        }
14371    }
14372    if let Some(wrong_filter_range) = wrong_filter_range {
14373        log::error!(
14374            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14375            label.text
14376        );
14377    }
14378
14379    label.text = new_text;
14380}