lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, ModelineSettings, Patch, PointUtf16, TextBufferSnapshot,
   77    ToOffset, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152pub use semantic_tokens::{
  153    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  154};
  155
  156pub use worktree::{
  157    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  158    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  159};
  160
  161const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  162pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  163const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  164const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  165static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  166
  167#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  168pub enum ProgressToken {
  169    Number(i32),
  170    String(SharedString),
  171}
  172
  173impl std::fmt::Display for ProgressToken {
  174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  175        match self {
  176            Self::Number(number) => write!(f, "{number}"),
  177            Self::String(string) => write!(f, "{string}"),
  178        }
  179    }
  180}
  181
  182impl ProgressToken {
  183    fn from_lsp(value: lsp::NumberOrString) -> Self {
  184        match value {
  185            lsp::NumberOrString::Number(number) => Self::Number(number),
  186            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  187        }
  188    }
  189
  190    fn to_lsp(&self) -> lsp::NumberOrString {
  191        match self {
  192            Self::Number(number) => lsp::NumberOrString::Number(*number),
  193            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  194        }
  195    }
  196
  197    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  198        Some(match value.value? {
  199            proto::progress_token::Value::Number(number) => Self::Number(number),
  200            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  201        })
  202    }
  203
  204    fn to_proto(&self) -> proto::ProgressToken {
  205        proto::ProgressToken {
  206            value: Some(match self {
  207                Self::Number(number) => proto::progress_token::Value::Number(*number),
  208                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  209            }),
  210        }
  211    }
  212}
  213
  214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  215pub enum FormatTrigger {
  216    Save,
  217    Manual,
  218}
  219
  220pub enum LspFormatTarget {
  221    Buffers,
  222    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  223}
  224
  225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  226pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  227
  228struct OpenLspBuffer(Entity<Buffer>);
  229
  230impl FormatTrigger {
  231    fn from_proto(value: i32) -> FormatTrigger {
  232        match value {
  233            0 => FormatTrigger::Save,
  234            1 => FormatTrigger::Manual,
  235            _ => FormatTrigger::Save,
  236        }
  237    }
  238}
  239
  240#[derive(Clone)]
  241struct UnifiedLanguageServer {
  242    id: LanguageServerId,
  243    project_roots: HashSet<Arc<RelPath>>,
  244}
  245
  246/// Settings that affect language server identity.
  247///
  248/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  249/// updated via `workspace/didChangeConfiguration` without restarting the server.
  250#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  251struct LanguageServerSeedSettings {
  252    binary: Option<BinarySettings>,
  253    initialization_options: Option<serde_json::Value>,
  254}
  255
  256#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  257struct LanguageServerSeed {
  258    worktree_id: WorktreeId,
  259    name: LanguageServerName,
  260    toolchain: Option<Toolchain>,
  261    settings: LanguageServerSeedSettings,
  262}
  263
  264#[derive(Debug)]
  265pub struct DocumentDiagnosticsUpdate<'a, D> {
  266    pub diagnostics: D,
  267    pub result_id: Option<SharedString>,
  268    pub registration_id: Option<SharedString>,
  269    pub server_id: LanguageServerId,
  270    pub disk_based_sources: Cow<'a, [String]>,
  271}
  272
  273pub struct DocumentDiagnostics {
  274    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  275    document_abs_path: PathBuf,
  276    version: Option<i32>,
  277}
  278
  279#[derive(Default, Debug)]
  280struct DynamicRegistrations {
  281    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  282    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  283}
  284
  285pub struct LocalLspStore {
  286    weak: WeakEntity<LspStore>,
  287    pub worktree_store: Entity<WorktreeStore>,
  288    toolchain_store: Entity<LocalToolchainStore>,
  289    http_client: Arc<dyn HttpClient>,
  290    environment: Entity<ProjectEnvironment>,
  291    fs: Arc<dyn Fs>,
  292    languages: Arc<LanguageRegistry>,
  293    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  294    yarn: Entity<YarnPathStore>,
  295    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  296    buffers_being_formatted: HashSet<BufferId>,
  297    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  298    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  299    watched_manifest_filenames: HashSet<ManifestName>,
  300    language_server_paths_watched_for_rename:
  301        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  302    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  303    supplementary_language_servers:
  304        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  305    prettier_store: Entity<PrettierStore>,
  306    next_diagnostic_group_id: usize,
  307    diagnostics: HashMap<
  308        WorktreeId,
  309        HashMap<
  310            Arc<RelPath>,
  311            Vec<(
  312                LanguageServerId,
  313                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  314            )>,
  315        >,
  316    >,
  317    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  318    _subscription: gpui::Subscription,
  319    lsp_tree: LanguageServerTree,
  320    registered_buffers: HashMap<BufferId, usize>,
  321    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  322    buffer_pull_diagnostics_result_ids: HashMap<
  323        LanguageServerId,
  324        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  325    >,
  326    workspace_pull_diagnostics_result_ids: HashMap<
  327        LanguageServerId,
  328        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  329    >,
  330    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  331
  332    buffers_to_refresh_hash_set: HashSet<BufferId>,
  333    buffers_to_refresh_queue: VecDeque<BufferId>,
  334    _background_diagnostics_worker: Shared<Task<()>>,
  335}
  336
  337impl LocalLspStore {
  338    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  339    pub fn running_language_server_for_id(
  340        &self,
  341        id: LanguageServerId,
  342    ) -> Option<&Arc<LanguageServer>> {
  343        let language_server_state = self.language_servers.get(&id)?;
  344
  345        match language_server_state {
  346            LanguageServerState::Running { server, .. } => Some(server),
  347            LanguageServerState::Starting { .. } => None,
  348        }
  349    }
  350
  351    fn get_or_insert_language_server(
  352        &mut self,
  353        worktree_handle: &Entity<Worktree>,
  354        delegate: Arc<LocalLspAdapterDelegate>,
  355        disposition: &Arc<LaunchDisposition>,
  356        language_name: &LanguageName,
  357        cx: &mut App,
  358    ) -> LanguageServerId {
  359        let key = LanguageServerSeed {
  360            worktree_id: worktree_handle.read(cx).id(),
  361            name: disposition.server_name.clone(),
  362            settings: LanguageServerSeedSettings {
  363                binary: disposition.settings.binary.clone(),
  364                initialization_options: disposition.settings.initialization_options.clone(),
  365            },
  366            toolchain: disposition.toolchain.clone(),
  367        };
  368        if let Some(state) = self.language_server_ids.get_mut(&key) {
  369            state.project_roots.insert(disposition.path.path.clone());
  370            state.id
  371        } else {
  372            let adapter = self
  373                .languages
  374                .lsp_adapters(language_name)
  375                .into_iter()
  376                .find(|adapter| adapter.name() == disposition.server_name)
  377                .expect("To find LSP adapter");
  378            let new_language_server_id = self.start_language_server(
  379                worktree_handle,
  380                delegate,
  381                adapter,
  382                disposition.settings.clone(),
  383                key.clone(),
  384                language_name.clone(),
  385                cx,
  386            );
  387            if let Some(state) = self.language_server_ids.get_mut(&key) {
  388                state.project_roots.insert(disposition.path.path.clone());
  389            } else {
  390                debug_assert!(
  391                    false,
  392                    "Expected `start_language_server` to ensure that `key` exists in a map"
  393                );
  394            }
  395            new_language_server_id
  396        }
  397    }
  398
  399    fn start_language_server(
  400        &mut self,
  401        worktree_handle: &Entity<Worktree>,
  402        delegate: Arc<LocalLspAdapterDelegate>,
  403        adapter: Arc<CachedLspAdapter>,
  404        settings: Arc<LspSettings>,
  405        key: LanguageServerSeed,
  406        language_name: LanguageName,
  407        cx: &mut App,
  408    ) -> LanguageServerId {
  409        let worktree = worktree_handle.read(cx);
  410
  411        let worktree_id = worktree.id();
  412        let worktree_abs_path = worktree.abs_path();
  413        let toolchain = key.toolchain.clone();
  414        let override_options = settings.initialization_options.clone();
  415
  416        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  417
  418        let server_id = self.languages.next_language_server_id();
  419        log::trace!(
  420            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  421            adapter.name.0
  422        );
  423
  424        let wait_until_worktree_trust =
  425            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  426                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  427                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  428                });
  429                if can_trust {
  430                    self.restricted_worktrees_tasks.remove(&worktree_id);
  431                    None
  432                } else {
  433                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  434                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  435                        hash_map::Entry::Vacant(v) => {
  436                            let (mut tx, rx) = watch::channel::<bool>();
  437                            let lsp_store = self.weak.clone();
  438                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  439                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  440                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  441                                        tx.blocking_send(true).ok();
  442                                        lsp_store
  443                                            .update(cx, |lsp_store, _| {
  444                                                if let Some(local_lsp_store) =
  445                                                    lsp_store.as_local_mut()
  446                                                {
  447                                                    local_lsp_store
  448                                                        .restricted_worktrees_tasks
  449                                                        .remove(&worktree_id);
  450                                                }
  451                                            })
  452                                            .ok();
  453                                    }
  454                                }
  455                            });
  456                            v.insert((subscription, rx.clone()));
  457                            Some(rx)
  458                        }
  459                    }
  460                }
  461            });
  462        let update_binary_status = wait_until_worktree_trust.is_none();
  463
  464        let binary = self.get_language_server_binary(
  465            worktree_abs_path.clone(),
  466            adapter.clone(),
  467            settings,
  468            toolchain.clone(),
  469            delegate.clone(),
  470            true,
  471            wait_until_worktree_trust,
  472            cx,
  473        );
  474        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  475
  476        let pending_server = cx.spawn({
  477            let adapter = adapter.clone();
  478            let server_name = adapter.name.clone();
  479            let stderr_capture = stderr_capture.clone();
  480            #[cfg(any(test, feature = "test-support"))]
  481            let lsp_store = self.weak.clone();
  482            let pending_workspace_folders = pending_workspace_folders.clone();
  483            async move |cx| {
  484                let binary = binary.await?;
  485                #[cfg(any(test, feature = "test-support"))]
  486                if let Some(server) = lsp_store
  487                    .update(&mut cx.clone(), |this, cx| {
  488                        this.languages.create_fake_language_server(
  489                            server_id,
  490                            &server_name,
  491                            binary.clone(),
  492                            &mut cx.to_async(),
  493                        )
  494                    })
  495                    .ok()
  496                    .flatten()
  497                {
  498                    return Ok(server);
  499                }
  500
  501                let code_action_kinds = adapter.code_action_kinds();
  502                lsp::LanguageServer::new(
  503                    stderr_capture,
  504                    server_id,
  505                    server_name,
  506                    binary,
  507                    &worktree_abs_path,
  508                    code_action_kinds,
  509                    Some(pending_workspace_folders),
  510                    cx,
  511                )
  512            }
  513        });
  514
  515        let startup = {
  516            let server_name = adapter.name.0.clone();
  517            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  518            let key = key.clone();
  519            let adapter = adapter.clone();
  520            let lsp_store = self.weak.clone();
  521            let pending_workspace_folders = pending_workspace_folders.clone();
  522            let pull_diagnostics = ProjectSettings::get_global(cx)
  523                .diagnostics
  524                .lsp_pull_diagnostics
  525                .enabled;
  526            let settings_location = SettingsLocation {
  527                worktree_id,
  528                path: RelPath::empty(),
  529            };
  530            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  531                .language(Some(settings_location), Some(&language_name), cx)
  532                .semantic_tokens
  533                .use_tree_sitter();
  534            cx.spawn(async move |cx| {
  535                let result = async {
  536                    let language_server = pending_server.await?;
  537
  538                    let workspace_config = Self::workspace_configuration_for_adapter(
  539                        adapter.adapter.clone(),
  540                        &delegate,
  541                        toolchain,
  542                        None,
  543                        cx,
  544                    )
  545                    .await?;
  546
  547                    let mut initialization_options = Self::initialization_options_for_adapter(
  548                        adapter.adapter.clone(),
  549                        &delegate,
  550                        cx,
  551                    )
  552                    .await?;
  553
  554                    match (&mut initialization_options, override_options) {
  555                        (Some(initialization_options), Some(override_options)) => {
  556                            merge_json_value_into(override_options, initialization_options);
  557                        }
  558                        (None, override_options) => initialization_options = override_options,
  559                        _ => {}
  560                    }
  561
  562                    let initialization_params = cx.update(|cx| {
  563                        let mut params = language_server.default_initialize_params(
  564                            pull_diagnostics,
  565                            augments_syntax_tokens,
  566                            cx,
  567                        );
  568                        params.initialization_options = initialization_options;
  569                        adapter.adapter.prepare_initialize_params(params, cx)
  570                    })?;
  571
  572                    Self::setup_lsp_messages(
  573                        lsp_store.clone(),
  574                        &language_server,
  575                        delegate.clone(),
  576                        adapter.clone(),
  577                    );
  578
  579                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  580                        settings: workspace_config,
  581                    };
  582                    let language_server = cx
  583                        .update(|cx| {
  584                            let request_timeout = ProjectSettings::get_global(cx)
  585                                .global_lsp_settings
  586                                .get_request_timeout();
  587
  588                            language_server.initialize(
  589                                initialization_params,
  590                                Arc::new(did_change_configuration_params.clone()),
  591                                request_timeout,
  592                                cx,
  593                            )
  594                        })
  595                        .await
  596                        .inspect_err(|_| {
  597                            if let Some(lsp_store) = lsp_store.upgrade() {
  598                                lsp_store.update(cx, |lsp_store, cx| {
  599                                    lsp_store.cleanup_lsp_data(server_id);
  600                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  601                                });
  602                            }
  603                        })?;
  604
  605                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  606                        did_change_configuration_params,
  607                    )?;
  608
  609                    anyhow::Ok(language_server)
  610                }
  611                .await;
  612
  613                match result {
  614                    Ok(server) => {
  615                        lsp_store
  616                            .update(cx, |lsp_store, cx| {
  617                                lsp_store.insert_newly_running_language_server(
  618                                    adapter,
  619                                    server.clone(),
  620                                    server_id,
  621                                    key,
  622                                    pending_workspace_folders,
  623                                    cx,
  624                                );
  625                            })
  626                            .ok();
  627                        stderr_capture.lock().take();
  628                        Some(server)
  629                    }
  630
  631                    Err(err) => {
  632                        let log = stderr_capture.lock().take().unwrap_or_default();
  633                        delegate.update_status(
  634                            adapter.name(),
  635                            BinaryStatus::Failed {
  636                                error: if log.is_empty() {
  637                                    format!("{err:#}")
  638                                } else {
  639                                    format!("{err:#}\n-- stderr --\n{log}")
  640                                },
  641                            },
  642                        );
  643                        log::error!(
  644                            "Failed to start language server {server_name:?}: {}",
  645                            redact_command(&format!("{err:?}"))
  646                        );
  647                        if !log.is_empty() {
  648                            log::error!("server stderr: {}", redact_command(&log));
  649                        }
  650                        None
  651                    }
  652                }
  653            })
  654        };
  655        let state = LanguageServerState::Starting {
  656            startup,
  657            pending_workspace_folders,
  658        };
  659
  660        if update_binary_status {
  661            self.languages
  662                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663        }
  664
  665        self.language_servers.insert(server_id, state);
  666        self.language_server_ids
  667            .entry(key)
  668            .or_insert(UnifiedLanguageServer {
  669                id: server_id,
  670                project_roots: Default::default(),
  671            });
  672        server_id
  673    }
  674
  675    fn get_language_server_binary(
  676        &self,
  677        worktree_abs_path: Arc<Path>,
  678        adapter: Arc<CachedLspAdapter>,
  679        settings: Arc<LspSettings>,
  680        toolchain: Option<Toolchain>,
  681        delegate: Arc<dyn LspAdapterDelegate>,
  682        allow_binary_download: bool,
  683        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  684        cx: &mut App,
  685    ) -> Task<Result<LanguageServerBinary>> {
  686        if let Some(settings) = &settings.binary
  687            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  688        {
  689            let settings = settings.clone();
  690            let languages = self.languages.clone();
  691            return cx.background_spawn(async move {
  692                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  693                    let already_trusted =  *wait_until_worktree_trust.borrow();
  694                    if !already_trusted {
  695                        log::info!(
  696                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  697                            adapter.name(),
  698                        );
  699                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  700                            if worktree_trusted {
  701                                break;
  702                            }
  703                        }
  704                        log::info!(
  705                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  706                            adapter.name(),
  707                        );
  708                    }
  709                    languages
  710                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  711                }
  712                let mut env = delegate.shell_env().await;
  713                env.extend(settings.env.unwrap_or_default());
  714
  715                Ok(LanguageServerBinary {
  716                    path: delegate.resolve_relative_path(path),
  717                    env: Some(env),
  718                    arguments: settings
  719                        .arguments
  720                        .unwrap_or_default()
  721                        .iter()
  722                        .map(Into::into)
  723                        .collect(),
  724                })
  725            });
  726        }
  727        let lsp_binary_options = LanguageServerBinaryOptions {
  728            allow_path_lookup: !settings
  729                .binary
  730                .as_ref()
  731                .and_then(|b| b.ignore_system_version)
  732                .unwrap_or_default(),
  733            allow_binary_download,
  734            pre_release: settings
  735                .fetch
  736                .as_ref()
  737                .and_then(|f| f.pre_release)
  738                .unwrap_or(false),
  739        };
  740
  741        cx.spawn(async move |cx| {
  742            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  743                let already_trusted =  *wait_until_worktree_trust.borrow();
  744                if !already_trusted {
  745                    log::info!(
  746                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  747                        adapter.name(),
  748                    );
  749                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  750                        if worktree_trusted {
  751                            break;
  752                        }
  753                    }
  754                    log::info!(
  755                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  756                            adapter.name(),
  757                    );
  758                }
  759            }
  760
  761            let (existing_binary, maybe_download_binary) = adapter
  762                .clone()
  763                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  764                .await
  765                .await;
  766
  767            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  768
  769            let mut binary = match (existing_binary, maybe_download_binary) {
  770                (binary, None) => binary?,
  771                (Err(_), Some(downloader)) => downloader.await?,
  772                (Ok(existing_binary), Some(downloader)) => {
  773                    let mut download_timeout = cx
  774                        .background_executor()
  775                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  776                        .fuse();
  777                    let mut downloader = downloader.fuse();
  778                    futures::select! {
  779                        _ = download_timeout => {
  780                            // Return existing binary and kick the existing work to the background.
  781                            cx.spawn(async move |_| downloader.await).detach();
  782                            Ok(existing_binary)
  783                        },
  784                        downloaded_or_existing_binary = downloader => {
  785                            // If download fails, this results in the existing binary.
  786                            downloaded_or_existing_binary
  787                        }
  788                    }?
  789                }
  790            };
  791            let mut shell_env = delegate.shell_env().await;
  792
  793            shell_env.extend(binary.env.unwrap_or_default());
  794
  795            if let Some(settings) = settings.binary.as_ref() {
  796                if let Some(arguments) = &settings.arguments {
  797                    binary.arguments = arguments.iter().map(Into::into).collect();
  798                }
  799                if let Some(env) = &settings.env {
  800                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  801                }
  802            }
  803
  804            binary.env = Some(shell_env);
  805            Ok(binary)
  806        })
  807    }
  808
  809    fn setup_lsp_messages(
  810        lsp_store: WeakEntity<LspStore>,
  811        language_server: &LanguageServer,
  812        delegate: Arc<dyn LspAdapterDelegate>,
  813        adapter: Arc<CachedLspAdapter>,
  814    ) {
  815        let name = language_server.name();
  816        let server_id = language_server.server_id();
  817        language_server
  818            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  819                let adapter = adapter.clone();
  820                let this = lsp_store.clone();
  821                move |mut params, cx| {
  822                    let adapter = adapter.clone();
  823                    if let Some(this) = this.upgrade() {
  824                        this.update(cx, |this, cx| {
  825                            {
  826                                let buffer = params
  827                                    .uri
  828                                    .to_file_path()
  829                                    .map(|file_path| this.get_buffer(&file_path, cx))
  830                                    .ok()
  831                                    .flatten();
  832                                adapter.process_diagnostics(&mut params, server_id, buffer);
  833                            }
  834
  835                            this.merge_lsp_diagnostics(
  836                                DiagnosticSourceKind::Pushed,
  837                                vec![DocumentDiagnosticsUpdate {
  838                                    server_id,
  839                                    diagnostics: params,
  840                                    result_id: None,
  841                                    disk_based_sources: Cow::Borrowed(
  842                                        &adapter.disk_based_diagnostic_sources,
  843                                    ),
  844                                    registration_id: None,
  845                                }],
  846                                |_, diagnostic, cx| match diagnostic.source_kind {
  847                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  848                                        adapter.retain_old_diagnostic(diagnostic, cx)
  849                                    }
  850                                    DiagnosticSourceKind::Pulled => true,
  851                                },
  852                                cx,
  853                            )
  854                            .log_err();
  855                        });
  856                    }
  857                }
  858            })
  859            .detach();
  860        language_server
  861            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  862                let adapter = adapter.adapter.clone();
  863                let delegate = delegate.clone();
  864                let this = lsp_store.clone();
  865                move |params, cx| {
  866                    let adapter = adapter.clone();
  867                    let delegate = delegate.clone();
  868                    let this = this.clone();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let toolchain_for_id = this
  872                            .update(&mut cx, |this, _| {
  873                                this.as_local()?.language_server_ids.iter().find_map(
  874                                    |(seed, value)| {
  875                                        (value.id == server_id).then(|| seed.toolchain.clone())
  876                                    },
  877                                )
  878                            })?
  879                            .context("Expected the LSP store to be in a local mode")?;
  880
  881                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  882                        for item in &params.items {
  883                            let scope_uri = item.scope_uri.clone();
  884                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  885                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  886                            else {
  887                                // We've already queried workspace configuration of this URI.
  888                                continue;
  889                            };
  890                            let workspace_config = Self::workspace_configuration_for_adapter(
  891                                adapter.clone(),
  892                                &delegate,
  893                                toolchain_for_id.clone(),
  894                                scope_uri,
  895                                &mut cx,
  896                            )
  897                            .await?;
  898                            new_scope_uri.insert(workspace_config);
  899                        }
  900
  901                        Ok(params
  902                            .items
  903                            .into_iter()
  904                            .filter_map(|item| {
  905                                let workspace_config =
  906                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  907                                if let Some(section) = &item.section {
  908                                    Some(
  909                                        workspace_config
  910                                            .get(section)
  911                                            .cloned()
  912                                            .unwrap_or(serde_json::Value::Null),
  913                                    )
  914                                } else {
  915                                    Some(workspace_config.clone())
  916                                }
  917                            })
  918                            .collect())
  919                    }
  920                }
  921            })
  922            .detach();
  923
  924        language_server
  925            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  926                let this = lsp_store.clone();
  927                move |_, cx| {
  928                    let this = this.clone();
  929                    let cx = cx.clone();
  930                    async move {
  931                        let Some(server) =
  932                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  933                        else {
  934                            return Ok(None);
  935                        };
  936                        let root = server.workspace_folders();
  937                        Ok(Some(
  938                            root.into_iter()
  939                                .map(|uri| WorkspaceFolder {
  940                                    uri,
  941                                    name: Default::default(),
  942                                })
  943                                .collect(),
  944                        ))
  945                    }
  946                }
  947            })
  948            .detach();
  949        // Even though we don't have handling for these requests, respond to them to
  950        // avoid stalling any language server like `gopls` which waits for a response
  951        // to these requests when initializing.
  952        language_server
  953            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  954                let this = lsp_store.clone();
  955                move |params, cx| {
  956                    let this = this.clone();
  957                    let mut cx = cx.clone();
  958                    async move {
  959                        this.update(&mut cx, |this, _| {
  960                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  961                            {
  962                                status
  963                                    .progress_tokens
  964                                    .insert(ProgressToken::from_lsp(params.token));
  965                            }
  966                        })?;
  967
  968                        Ok(())
  969                    }
  970                }
  971            })
  972            .detach();
  973
  974        language_server
  975            .on_request::<lsp::request::RegisterCapability, _, _>({
  976                let lsp_store = lsp_store.clone();
  977                move |params, cx| {
  978                    let lsp_store = lsp_store.clone();
  979                    let mut cx = cx.clone();
  980                    async move {
  981                        lsp_store
  982                            .update(&mut cx, |lsp_store, cx| {
  983                                if lsp_store.as_local().is_some() {
  984                                    match lsp_store
  985                                        .register_server_capabilities(server_id, params, cx)
  986                                    {
  987                                        Ok(()) => {}
  988                                        Err(e) => {
  989                                            log::error!(
  990                                                "Failed to register server capabilities: {e:#}"
  991                                            );
  992                                        }
  993                                    };
  994                                }
  995                            })
  996                            .ok();
  997                        Ok(())
  998                    }
  999                }
 1000            })
 1001            .detach();
 1002
 1003        language_server
 1004            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1005                let lsp_store = lsp_store.clone();
 1006                move |params, cx| {
 1007                    let lsp_store = lsp_store.clone();
 1008                    let mut cx = cx.clone();
 1009                    async move {
 1010                        lsp_store
 1011                            .update(&mut cx, |lsp_store, cx| {
 1012                                if lsp_store.as_local().is_some() {
 1013                                    match lsp_store
 1014                                        .unregister_server_capabilities(server_id, params, cx)
 1015                                    {
 1016                                        Ok(()) => {}
 1017                                        Err(e) => {
 1018                                            log::error!(
 1019                                                "Failed to unregister server capabilities: {e:#}"
 1020                                            );
 1021                                        }
 1022                                    }
 1023                                }
 1024                            })
 1025                            .ok();
 1026                        Ok(())
 1027                    }
 1028                }
 1029            })
 1030            .detach();
 1031
 1032        language_server
 1033            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1034                let this = lsp_store.clone();
 1035                move |params, cx| {
 1036                    let mut cx = cx.clone();
 1037                    let this = this.clone();
 1038                    async move {
 1039                        LocalLspStore::on_lsp_workspace_edit(
 1040                            this.clone(),
 1041                            params,
 1042                            server_id,
 1043                            &mut cx,
 1044                        )
 1045                        .await
 1046                    }
 1047                }
 1048            })
 1049            .detach();
 1050
 1051        language_server
 1052            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1053                let lsp_store = lsp_store.clone();
 1054                let request_id = Arc::new(AtomicUsize::new(0));
 1055                move |(), cx| {
 1056                    let lsp_store = lsp_store.clone();
 1057                    let request_id = request_id.clone();
 1058                    let mut cx = cx.clone();
 1059                    async move {
 1060                        lsp_store
 1061                            .update(&mut cx, |lsp_store, cx| {
 1062                                let request_id =
 1063                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1064                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1065                                    server_id,
 1066                                    request_id,
 1067                                });
 1068                                lsp_store
 1069                                    .downstream_client
 1070                                    .as_ref()
 1071                                    .map(|(client, project_id)| {
 1072                                        client.send(proto::RefreshInlayHints {
 1073                                            project_id: *project_id,
 1074                                            server_id: server_id.to_proto(),
 1075                                            request_id: request_id.map(|id| id as u64),
 1076                                        })
 1077                                    })
 1078                            })?
 1079                            .transpose()?;
 1080                        Ok(())
 1081                    }
 1082                }
 1083            })
 1084            .detach();
 1085
 1086        language_server
 1087            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1088                let this = lsp_store.clone();
 1089                move |(), cx| {
 1090                    let this = this.clone();
 1091                    let mut cx = cx.clone();
 1092                    async move {
 1093                        this.update(&mut cx, |this, cx| {
 1094                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1095                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1096                                client.send(proto::RefreshCodeLens {
 1097                                    project_id: *project_id,
 1098                                })
 1099                            })
 1100                        })?
 1101                        .transpose()?;
 1102                        Ok(())
 1103                    }
 1104                }
 1105            })
 1106            .detach();
 1107
 1108        language_server
 1109            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1110                let lsp_store = lsp_store.clone();
 1111                let request_id = Arc::new(AtomicUsize::new(0));
 1112                move |(), cx| {
 1113                    let lsp_store = lsp_store.clone();
 1114                    let request_id = request_id.clone();
 1115                    let mut cx = cx.clone();
 1116                    async move {
 1117                        lsp_store
 1118                            .update(&mut cx, |lsp_store, cx| {
 1119                                let request_id =
 1120                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1121                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1122                                    server_id,
 1123                                    request_id,
 1124                                });
 1125                                lsp_store
 1126                                    .downstream_client
 1127                                    .as_ref()
 1128                                    .map(|(client, project_id)| {
 1129                                        client.send(proto::RefreshSemanticTokens {
 1130                                            project_id: *project_id,
 1131                                            server_id: server_id.to_proto(),
 1132                                            request_id: request_id.map(|id| id as u64),
 1133                                        })
 1134                                    })
 1135                            })?
 1136                            .transpose()?;
 1137                        Ok(())
 1138                    }
 1139                }
 1140            })
 1141            .detach();
 1142
 1143        language_server
 1144            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1145                let this = lsp_store.clone();
 1146                move |(), cx| {
 1147                    let this = this.clone();
 1148                    let mut cx = cx.clone();
 1149                    async move {
 1150                        this.update(&mut cx, |lsp_store, cx| {
 1151                            lsp_store.pull_workspace_diagnostics(server_id);
 1152                            lsp_store
 1153                                .downstream_client
 1154                                .as_ref()
 1155                                .map(|(client, project_id)| {
 1156                                    client.send(proto::PullWorkspaceDiagnostics {
 1157                                        project_id: *project_id,
 1158                                        server_id: server_id.to_proto(),
 1159                                    })
 1160                                })
 1161                                .transpose()?;
 1162                            anyhow::Ok(
 1163                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1164                            )
 1165                        })??
 1166                        .await;
 1167                        Ok(())
 1168                    }
 1169                }
 1170            })
 1171            .detach();
 1172
 1173        language_server
 1174            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1175                let this = lsp_store.clone();
 1176                let name = name.to_string();
 1177                let adapter = adapter.clone();
 1178                move |params, cx| {
 1179                    let this = this.clone();
 1180                    let name = name.to_string();
 1181                    let adapter = adapter.clone();
 1182                    let mut cx = cx.clone();
 1183                    async move {
 1184                        let actions = params.actions.unwrap_or_default();
 1185                        let message = params.message.clone();
 1186                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1187                        let level = match params.typ {
 1188                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1189                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1190                            _ => PromptLevel::Info,
 1191                        };
 1192                        let request = LanguageServerPromptRequest::new(
 1193                            level,
 1194                            params.message,
 1195                            actions,
 1196                            name.clone(),
 1197                            tx,
 1198                        );
 1199
 1200                        let did_update = this
 1201                            .update(&mut cx, |_, cx| {
 1202                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1203                            })
 1204                            .is_ok();
 1205                        if did_update {
 1206                            let response = rx.recv().await.ok();
 1207                            if let Some(ref selected_action) = response {
 1208                                let context = language::PromptResponseContext {
 1209                                    message,
 1210                                    selected_action: selected_action.clone(),
 1211                                };
 1212                                adapter.process_prompt_response(&context, &mut cx)
 1213                            }
 1214
 1215                            Ok(response)
 1216                        } else {
 1217                            Ok(None)
 1218                        }
 1219                    }
 1220                }
 1221            })
 1222            .detach();
 1223        language_server
 1224            .on_notification::<lsp::notification::ShowMessage, _>({
 1225                let this = lsp_store.clone();
 1226                let name = name.to_string();
 1227                move |params, cx| {
 1228                    let this = this.clone();
 1229                    let name = name.to_string();
 1230                    let mut cx = cx.clone();
 1231
 1232                    let (tx, _) = smol::channel::bounded(1);
 1233                    let level = match params.typ {
 1234                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1235                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1236                        _ => PromptLevel::Info,
 1237                    };
 1238                    let request =
 1239                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1240
 1241                    let _ = this.update(&mut cx, |_, cx| {
 1242                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1243                    });
 1244                }
 1245            })
 1246            .detach();
 1247
 1248        let disk_based_diagnostics_progress_token =
 1249            adapter.disk_based_diagnostics_progress_token.clone();
 1250
 1251        language_server
 1252            .on_notification::<lsp::notification::Progress, _>({
 1253                let this = lsp_store.clone();
 1254                move |params, cx| {
 1255                    if let Some(this) = this.upgrade() {
 1256                        this.update(cx, |this, cx| {
 1257                            this.on_lsp_progress(
 1258                                params,
 1259                                server_id,
 1260                                disk_based_diagnostics_progress_token.clone(),
 1261                                cx,
 1262                            );
 1263                        });
 1264                    }
 1265                }
 1266            })
 1267            .detach();
 1268
 1269        language_server
 1270            .on_notification::<lsp::notification::LogMessage, _>({
 1271                let this = lsp_store.clone();
 1272                move |params, cx| {
 1273                    if let Some(this) = this.upgrade() {
 1274                        this.update(cx, |_, cx| {
 1275                            cx.emit(LspStoreEvent::LanguageServerLog(
 1276                                server_id,
 1277                                LanguageServerLogType::Log(params.typ),
 1278                                params.message,
 1279                            ));
 1280                        });
 1281                    }
 1282                }
 1283            })
 1284            .detach();
 1285
 1286        language_server
 1287            .on_notification::<lsp::notification::LogTrace, _>({
 1288                let this = lsp_store.clone();
 1289                move |params, cx| {
 1290                    let mut cx = cx.clone();
 1291                    if let Some(this) = this.upgrade() {
 1292                        this.update(&mut cx, |_, cx| {
 1293                            cx.emit(LspStoreEvent::LanguageServerLog(
 1294                                server_id,
 1295                                LanguageServerLogType::Trace {
 1296                                    verbose_info: params.verbose,
 1297                                },
 1298                                params.message,
 1299                            ));
 1300                        });
 1301                    }
 1302                }
 1303            })
 1304            .detach();
 1305
 1306        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1307        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1309        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1310    }
 1311
 1312    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1313        let shutdown_futures = self
 1314            .language_servers
 1315            .drain()
 1316            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1317            .collect::<Vec<_>>();
 1318
 1319        async move {
 1320            join_all(shutdown_futures).await;
 1321        }
 1322    }
 1323
 1324    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1325        match server_state {
 1326            LanguageServerState::Running { server, .. } => {
 1327                if let Some(shutdown) = server.shutdown() {
 1328                    shutdown.await;
 1329                }
 1330            }
 1331            LanguageServerState::Starting { startup, .. } => {
 1332                if let Some(server) = startup.await
 1333                    && let Some(shutdown) = server.shutdown()
 1334                {
 1335                    shutdown.await;
 1336                }
 1337            }
 1338        }
 1339        Ok(())
 1340    }
 1341
 1342    fn language_servers_for_worktree(
 1343        &self,
 1344        worktree_id: WorktreeId,
 1345    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1346        self.language_server_ids
 1347            .iter()
 1348            .filter_map(move |(seed, state)| {
 1349                if seed.worktree_id != worktree_id {
 1350                    return None;
 1351                }
 1352
 1353                if let Some(LanguageServerState::Running { server, .. }) =
 1354                    self.language_servers.get(&state.id)
 1355                {
 1356                    Some(server)
 1357                } else {
 1358                    None
 1359                }
 1360            })
 1361    }
 1362
 1363    fn language_server_ids_for_project_path(
 1364        &self,
 1365        project_path: ProjectPath,
 1366        language: &Language,
 1367        cx: &mut App,
 1368    ) -> Vec<LanguageServerId> {
 1369        let Some(worktree) = self
 1370            .worktree_store
 1371            .read(cx)
 1372            .worktree_for_id(project_path.worktree_id, cx)
 1373        else {
 1374            return Vec::new();
 1375        };
 1376        let delegate: Arc<dyn ManifestDelegate> =
 1377            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1378
 1379        self.lsp_tree
 1380            .get(
 1381                project_path,
 1382                language.name(),
 1383                language.manifest(),
 1384                &delegate,
 1385                cx,
 1386            )
 1387            .collect::<Vec<_>>()
 1388    }
 1389
 1390    fn language_server_ids_for_buffer(
 1391        &self,
 1392        buffer: &Buffer,
 1393        cx: &mut App,
 1394    ) -> Vec<LanguageServerId> {
 1395        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1396            let worktree_id = file.worktree_id(cx);
 1397
 1398            let path: Arc<RelPath> = file
 1399                .path()
 1400                .parent()
 1401                .map(Arc::from)
 1402                .unwrap_or_else(|| file.path().clone());
 1403            let worktree_path = ProjectPath { worktree_id, path };
 1404            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1405        } else {
 1406            Vec::new()
 1407        }
 1408    }
 1409
 1410    fn language_servers_for_buffer<'a>(
 1411        &'a self,
 1412        buffer: &'a Buffer,
 1413        cx: &'a mut App,
 1414    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1415        self.language_server_ids_for_buffer(buffer, cx)
 1416            .into_iter()
 1417            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1418                LanguageServerState::Running {
 1419                    adapter, server, ..
 1420                } => Some((adapter, server)),
 1421                _ => None,
 1422            })
 1423    }
 1424
 1425    async fn execute_code_action_kind_locally(
 1426        lsp_store: WeakEntity<LspStore>,
 1427        mut buffers: Vec<Entity<Buffer>>,
 1428        kind: CodeActionKind,
 1429        push_to_history: bool,
 1430        cx: &mut AsyncApp,
 1431    ) -> anyhow::Result<ProjectTransaction> {
 1432        // Do not allow multiple concurrent code actions requests for the
 1433        // same buffer.
 1434        lsp_store.update(cx, |this, cx| {
 1435            let this = this.as_local_mut().unwrap();
 1436            buffers.retain(|buffer| {
 1437                this.buffers_being_formatted
 1438                    .insert(buffer.read(cx).remote_id())
 1439            });
 1440        })?;
 1441        let _cleanup = defer({
 1442            let this = lsp_store.clone();
 1443            let mut cx = cx.clone();
 1444            let buffers = &buffers;
 1445            move || {
 1446                this.update(&mut cx, |this, cx| {
 1447                    let this = this.as_local_mut().unwrap();
 1448                    for buffer in buffers {
 1449                        this.buffers_being_formatted
 1450                            .remove(&buffer.read(cx).remote_id());
 1451                    }
 1452                })
 1453                .ok();
 1454            }
 1455        });
 1456        let mut project_transaction = ProjectTransaction::default();
 1457
 1458        for buffer in &buffers {
 1459            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1460                buffer.update(cx, |buffer, cx| {
 1461                    lsp_store
 1462                        .as_local()
 1463                        .unwrap()
 1464                        .language_servers_for_buffer(buffer, cx)
 1465                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1466                        .collect::<Vec<_>>()
 1467                })
 1468            })?;
 1469            for (_, language_server) in adapters_and_servers.iter() {
 1470                let actions = Self::get_server_code_actions_from_action_kinds(
 1471                    &lsp_store,
 1472                    language_server.server_id(),
 1473                    vec![kind.clone()],
 1474                    buffer,
 1475                    cx,
 1476                )
 1477                .await?;
 1478                Self::execute_code_actions_on_server(
 1479                    &lsp_store,
 1480                    language_server,
 1481                    actions,
 1482                    push_to_history,
 1483                    &mut project_transaction,
 1484                    cx,
 1485                )
 1486                .await?;
 1487            }
 1488        }
 1489        Ok(project_transaction)
 1490    }
 1491
 1492    async fn format_locally(
 1493        lsp_store: WeakEntity<LspStore>,
 1494        mut buffers: Vec<FormattableBuffer>,
 1495        push_to_history: bool,
 1496        trigger: FormatTrigger,
 1497        logger: zlog::Logger,
 1498        cx: &mut AsyncApp,
 1499    ) -> anyhow::Result<ProjectTransaction> {
 1500        // Do not allow multiple concurrent formatting requests for the
 1501        // same buffer.
 1502        lsp_store.update(cx, |this, cx| {
 1503            let this = this.as_local_mut().unwrap();
 1504            buffers.retain(|buffer| {
 1505                this.buffers_being_formatted
 1506                    .insert(buffer.handle.read(cx).remote_id())
 1507            });
 1508        })?;
 1509
 1510        let _cleanup = defer({
 1511            let this = lsp_store.clone();
 1512            let mut cx = cx.clone();
 1513            let buffers = &buffers;
 1514            move || {
 1515                this.update(&mut cx, |this, cx| {
 1516                    let this = this.as_local_mut().unwrap();
 1517                    for buffer in buffers {
 1518                        this.buffers_being_formatted
 1519                            .remove(&buffer.handle.read(cx).remote_id());
 1520                    }
 1521                })
 1522                .ok();
 1523            }
 1524        });
 1525
 1526        let mut project_transaction = ProjectTransaction::default();
 1527
 1528        for buffer in &buffers {
 1529            zlog::debug!(
 1530                logger =>
 1531                "formatting buffer '{:?}'",
 1532                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1533            );
 1534            // Create an empty transaction to hold all of the formatting edits.
 1535            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1536                // ensure no transactions created while formatting are
 1537                // grouped with the previous transaction in the history
 1538                // based on the transaction group interval
 1539                buffer.finalize_last_transaction();
 1540                buffer
 1541                    .start_transaction()
 1542                    .context("transaction already open")?;
 1543                buffer.end_transaction(cx);
 1544                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1545                buffer.finalize_last_transaction();
 1546                anyhow::Ok(transaction_id)
 1547            })?;
 1548
 1549            let result = Self::format_buffer_locally(
 1550                lsp_store.clone(),
 1551                buffer,
 1552                formatting_transaction_id,
 1553                trigger,
 1554                logger,
 1555                cx,
 1556            )
 1557            .await;
 1558
 1559            buffer.handle.update(cx, |buffer, cx| {
 1560                let Some(formatting_transaction) =
 1561                    buffer.get_transaction(formatting_transaction_id).cloned()
 1562                else {
 1563                    zlog::warn!(logger => "no formatting transaction");
 1564                    return;
 1565                };
 1566                if formatting_transaction.edit_ids.is_empty() {
 1567                    zlog::debug!(logger => "no changes made while formatting");
 1568                    buffer.forget_transaction(formatting_transaction_id);
 1569                    return;
 1570                }
 1571                if !push_to_history {
 1572                    zlog::trace!(logger => "forgetting format transaction");
 1573                    buffer.forget_transaction(formatting_transaction.id);
 1574                }
 1575                project_transaction
 1576                    .0
 1577                    .insert(cx.entity(), formatting_transaction);
 1578            });
 1579
 1580            result?;
 1581        }
 1582
 1583        Ok(project_transaction)
 1584    }
 1585
 1586    async fn format_buffer_locally(
 1587        lsp_store: WeakEntity<LspStore>,
 1588        buffer: &FormattableBuffer,
 1589        formatting_transaction_id: clock::Lamport,
 1590        trigger: FormatTrigger,
 1591        logger: zlog::Logger,
 1592        cx: &mut AsyncApp,
 1593    ) -> Result<()> {
 1594        let (adapters_and_servers, settings, request_timeout) =
 1595            lsp_store.update(cx, |lsp_store, cx| {
 1596                buffer.handle.update(cx, |buffer, cx| {
 1597                    let adapters_and_servers = lsp_store
 1598                        .as_local()
 1599                        .unwrap()
 1600                        .language_servers_for_buffer(buffer, cx)
 1601                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1602                        .collect::<Vec<_>>();
 1603                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1604                    let request_timeout = ProjectSettings::get_global(cx)
 1605                        .global_lsp_settings
 1606                        .get_request_timeout();
 1607                    (adapters_and_servers, settings, request_timeout)
 1608                })
 1609            })?;
 1610
 1611        /// 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 => adapters_and_servers
 1779                            .iter()
 1780                            .find(|(_, server)| Self::server_supports_formatting(server))
 1781                            .map(|(_, server)| server.clone()),
 1782                    };
 1783
 1784                    let Some(language_server) = language_server else {
 1785                        log::debug!(
 1786                            "No language server found to format buffer '{:?}'. Skipping",
 1787                            buffer_path_abs.as_path().to_string_lossy()
 1788                        );
 1789                        continue;
 1790                    };
 1791
 1792                    zlog::trace!(
 1793                        logger =>
 1794                        "Formatting buffer '{:?}' using language server '{:?}'",
 1795                        buffer_path_abs.as_path().to_string_lossy(),
 1796                        language_server.name()
 1797                    );
 1798
 1799                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1800                        zlog::trace!(logger => "formatting ranges");
 1801                        Self::format_ranges_via_lsp(
 1802                            &lsp_store,
 1803                            &buffer.handle,
 1804                            ranges,
 1805                            buffer_path_abs,
 1806                            &language_server,
 1807                            &settings,
 1808                            cx,
 1809                        )
 1810                        .await
 1811                        .context("Failed to format ranges via language server")?
 1812                    } else {
 1813                        zlog::trace!(logger => "formatting full");
 1814                        Self::format_via_lsp(
 1815                            &lsp_store,
 1816                            &buffer.handle,
 1817                            buffer_path_abs,
 1818                            &language_server,
 1819                            &settings,
 1820                            cx,
 1821                        )
 1822                        .await
 1823                        .context("failed to format via language server")?
 1824                    };
 1825
 1826                    if edits.is_empty() {
 1827                        zlog::trace!(logger => "No changes");
 1828                        continue;
 1829                    }
 1830                    extend_formatting_transaction(
 1831                        buffer,
 1832                        formatting_transaction_id,
 1833                        cx,
 1834                        |buffer, cx| {
 1835                            buffer.edit(edits, None, cx);
 1836                        },
 1837                    )?;
 1838                }
 1839                Formatter::CodeAction(code_action_name) => {
 1840                    let logger = zlog::scoped!(logger => "code-actions");
 1841                    zlog::trace!(logger => "formatting");
 1842                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1843
 1844                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1845                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1846                        continue;
 1847                    };
 1848
 1849                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1850                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1851
 1852                    let mut actions_and_servers = Vec::new();
 1853
 1854                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1855                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1856                            &lsp_store,
 1857                            language_server.server_id(),
 1858                            vec![code_action_kind.clone()],
 1859                            &buffer.handle,
 1860                            cx,
 1861                        )
 1862                        .await
 1863                        .with_context(|| {
 1864                            format!(
 1865                                "Failed to resolve code action {:?} with language server {}",
 1866                                code_action_kind,
 1867                                language_server.name()
 1868                            )
 1869                        });
 1870                        let Ok(actions) = actions_result else {
 1871                            // note: it may be better to set result to the error and break formatters here
 1872                            // but for now we try to execute the actions that we can resolve and skip the rest
 1873                            zlog::error!(
 1874                                logger =>
 1875                                "Failed to resolve code action {:?} with language server {}",
 1876                                code_action_kind,
 1877                                language_server.name()
 1878                            );
 1879                            continue;
 1880                        };
 1881                        for action in actions {
 1882                            actions_and_servers.push((action, index));
 1883                        }
 1884                    }
 1885
 1886                    if actions_and_servers.is_empty() {
 1887                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1888                        continue;
 1889                    }
 1890
 1891                    'actions: for (mut action, server_index) in actions_and_servers {
 1892                        let server = &adapters_and_servers[server_index].1;
 1893
 1894                        let describe_code_action = |action: &CodeAction| {
 1895                            format!(
 1896                                "code action '{}' with title \"{}\" on server {}",
 1897                                action
 1898                                    .lsp_action
 1899                                    .action_kind()
 1900                                    .unwrap_or("unknown".into())
 1901                                    .as_str(),
 1902                                action.lsp_action.title(),
 1903                                server.name(),
 1904                            )
 1905                        };
 1906
 1907                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1908
 1909                        if let Err(err) =
 1910                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1911                                .await
 1912                        {
 1913                            zlog::error!(
 1914                                logger =>
 1915                                "Failed to resolve {}. Error: {}",
 1916                                describe_code_action(&action),
 1917                                err
 1918                            );
 1919                            continue;
 1920                        }
 1921
 1922                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1923                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1924                            // but filters out and logs warnings for code actions that require unreasonably
 1925                            // difficult handling on our part, such as:
 1926                            // - applying edits that call commands
 1927                            //   which can result in arbitrary workspace edits being sent from the server that
 1928                            //   have no way of being tied back to the command that initiated them (i.e. we
 1929                            //   can't know which edits are part of the format request, or if the server is done sending
 1930                            //   actions in response to the command)
 1931                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1932                            //   as we then would need to handle such changes correctly in the local history as well
 1933                            //   as the remote history through the ProjectTransaction
 1934                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1935                            // Supporting these actions is not impossible, but not supported as of yet.
 1936                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1937                                zlog::trace!(
 1938                                    logger =>
 1939                                    "No changes for code action. Skipping {}",
 1940                                    describe_code_action(&action),
 1941                                );
 1942                                continue;
 1943                            }
 1944
 1945                            let mut operations = Vec::new();
 1946                            if let Some(document_changes) = edit.document_changes {
 1947                                match document_changes {
 1948                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1949                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1950                                    ),
 1951                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1952                                }
 1953                            } else if let Some(changes) = edit.changes {
 1954                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1955                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1956                                        text_document:
 1957                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1958                                                uri,
 1959                                                version: None,
 1960                                            },
 1961                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1962                                    })
 1963                                }));
 1964                            }
 1965
 1966                            let mut edits = Vec::with_capacity(operations.len());
 1967
 1968                            if operations.is_empty() {
 1969                                zlog::trace!(
 1970                                    logger =>
 1971                                    "No changes for code action. Skipping {}",
 1972                                    describe_code_action(&action),
 1973                                );
 1974                                continue;
 1975                            }
 1976                            for operation in operations {
 1977                                let op = match operation {
 1978                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1979                                    lsp::DocumentChangeOperation::Op(_) => {
 1980                                        zlog::warn!(
 1981                                            logger =>
 1982                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1983                                            describe_code_action(&action),
 1984                                        );
 1985                                        continue 'actions;
 1986                                    }
 1987                                };
 1988                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1989                                    zlog::warn!(
 1990                                        logger =>
 1991                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1992                                        &op.text_document.uri,
 1993                                        describe_code_action(&action),
 1994                                    );
 1995                                    continue 'actions;
 1996                                };
 1997                                if &file_path != buffer_path_abs {
 1998                                    zlog::warn!(
 1999                                        logger =>
 2000                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2001                                        file_path,
 2002                                        buffer_path_abs,
 2003                                        describe_code_action(&action),
 2004                                    );
 2005                                    continue 'actions;
 2006                                }
 2007
 2008                                let mut lsp_edits = Vec::new();
 2009                                for edit in op.edits {
 2010                                    match edit {
 2011                                        Edit::Plain(edit) => {
 2012                                            if !lsp_edits.contains(&edit) {
 2013                                                lsp_edits.push(edit);
 2014                                            }
 2015                                        }
 2016                                        Edit::Annotated(edit) => {
 2017                                            if !lsp_edits.contains(&edit.text_edit) {
 2018                                                lsp_edits.push(edit.text_edit);
 2019                                            }
 2020                                        }
 2021                                        Edit::Snippet(_) => {
 2022                                            zlog::warn!(
 2023                                                logger =>
 2024                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2025                                                describe_code_action(&action),
 2026                                            );
 2027                                            continue 'actions;
 2028                                        }
 2029                                    }
 2030                                }
 2031                                let edits_result = lsp_store
 2032                                    .update(cx, |lsp_store, cx| {
 2033                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2034                                            &buffer.handle,
 2035                                            lsp_edits,
 2036                                            server.server_id(),
 2037                                            op.text_document.version,
 2038                                            cx,
 2039                                        )
 2040                                    })?
 2041                                    .await;
 2042                                let Ok(resolved_edits) = edits_result else {
 2043                                    zlog::warn!(
 2044                                        logger =>
 2045                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2046                                        buffer_path_abs.as_path(),
 2047                                        describe_code_action(&action),
 2048                                    );
 2049                                    continue 'actions;
 2050                                };
 2051                                edits.extend(resolved_edits);
 2052                            }
 2053
 2054                            if edits.is_empty() {
 2055                                zlog::warn!(logger => "No edits resolved from LSP");
 2056                                continue;
 2057                            }
 2058
 2059                            extend_formatting_transaction(
 2060                                buffer,
 2061                                formatting_transaction_id,
 2062                                cx,
 2063                                |buffer, cx| {
 2064                                    zlog::info!(
 2065                                        "Applying edits {edits:?}. Content: {:?}",
 2066                                        buffer.text()
 2067                                    );
 2068                                    buffer.edit(edits, None, cx);
 2069                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2070                                },
 2071                            )?;
 2072                        }
 2073
 2074                        // bail early if command is invalid
 2075                        let Some(command) = action.lsp_action.command() else {
 2076                            continue;
 2077                        };
 2078
 2079                        zlog::warn!(
 2080                            logger =>
 2081                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2082                            &command.command,
 2083                        );
 2084
 2085                        let server_capabilities = server.capabilities();
 2086                        let available_commands = server_capabilities
 2087                            .execute_command_provider
 2088                            .as_ref()
 2089                            .map(|options| options.commands.as_slice())
 2090                            .unwrap_or_default();
 2091                        if !available_commands.contains(&command.command) {
 2092                            zlog::warn!(
 2093                                logger =>
 2094                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2095                                command.command,
 2096                                server.name(),
 2097                            );
 2098                            continue;
 2099                        }
 2100
 2101                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2102                        extend_formatting_transaction(
 2103                            buffer,
 2104                            formatting_transaction_id,
 2105                            cx,
 2106                            |_, _| {},
 2107                        )?;
 2108                        zlog::info!(logger => "Executing command {}", &command.command);
 2109
 2110                        lsp_store.update(cx, |this, _| {
 2111                            this.as_local_mut()
 2112                                .unwrap()
 2113                                .last_workspace_edits_by_language_server
 2114                                .remove(&server.server_id());
 2115                        })?;
 2116
 2117                        let execute_command_result = server
 2118                            .request::<lsp::request::ExecuteCommand>(
 2119                                lsp::ExecuteCommandParams {
 2120                                    command: command.command.clone(),
 2121                                    arguments: command.arguments.clone().unwrap_or_default(),
 2122                                    ..Default::default()
 2123                                },
 2124                                request_timeout,
 2125                            )
 2126                            .await
 2127                            .into_response();
 2128
 2129                        if execute_command_result.is_err() {
 2130                            zlog::error!(
 2131                                logger =>
 2132                                "Failed to execute command '{}' as part of {}",
 2133                                &command.command,
 2134                                describe_code_action(&action),
 2135                            );
 2136                            continue 'actions;
 2137                        }
 2138
 2139                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2140                            this.as_local_mut()
 2141                                .unwrap()
 2142                                .last_workspace_edits_by_language_server
 2143                                .remove(&server.server_id())
 2144                                .unwrap_or_default()
 2145                        })?;
 2146
 2147                        if let Some(transaction) =
 2148                            project_transaction_command.0.remove(&buffer.handle)
 2149                        {
 2150                            zlog::trace!(
 2151                                logger =>
 2152                                "Successfully captured {} edits that resulted from command {}",
 2153                                transaction.edit_ids.len(),
 2154                                &command.command,
 2155                            );
 2156                            let transaction_id_project_transaction = transaction.id;
 2157                            buffer.handle.update(cx, |buffer, _| {
 2158                                // it may have been removed from history if push_to_history was
 2159                                // false in deserialize_workspace_edit. If so push it so we
 2160                                // can merge it with the format transaction
 2161                                // and pop the combined transaction off the history stack
 2162                                // later if push_to_history is false
 2163                                if buffer.get_transaction(transaction.id).is_none() {
 2164                                    buffer.push_transaction(transaction, Instant::now());
 2165                                }
 2166                                buffer.merge_transactions(
 2167                                    transaction_id_project_transaction,
 2168                                    formatting_transaction_id,
 2169                                );
 2170                            });
 2171                        }
 2172
 2173                        if project_transaction_command.0.is_empty() {
 2174                            continue;
 2175                        }
 2176
 2177                        let mut extra_buffers = String::new();
 2178                        for buffer in project_transaction_command.0.keys() {
 2179                            buffer.read_with(cx, |b, cx| {
 2180                                let Some(path) = b.project_path(cx) else {
 2181                                    return;
 2182                                };
 2183
 2184                                if !extra_buffers.is_empty() {
 2185                                    extra_buffers.push_str(", ");
 2186                                }
 2187                                extra_buffers.push_str(path.path.as_unix_str());
 2188                            });
 2189                        }
 2190                        zlog::warn!(
 2191                            logger =>
 2192                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2193                            &command.command,
 2194                            extra_buffers,
 2195                        );
 2196                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2197                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2198                        // add it so it's included, and merge it into the format transaction when its created later
 2199                    }
 2200                }
 2201            }
 2202        }
 2203
 2204        Ok(())
 2205    }
 2206
 2207    pub async fn format_ranges_via_lsp(
 2208        this: &WeakEntity<LspStore>,
 2209        buffer_handle: &Entity<Buffer>,
 2210        ranges: &[Range<Anchor>],
 2211        abs_path: &Path,
 2212        language_server: &Arc<LanguageServer>,
 2213        settings: &LanguageSettings,
 2214        cx: &mut AsyncApp,
 2215    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2216        let capabilities = &language_server.capabilities();
 2217        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2218        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2219            anyhow::bail!(
 2220                "{} language server does not support range formatting",
 2221                language_server.name()
 2222            );
 2223        }
 2224
 2225        let uri = file_path_to_lsp_url(abs_path)?;
 2226        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2227
 2228        let request_timeout = cx.update(|app| {
 2229            ProjectSettings::get_global(app)
 2230                .global_lsp_settings
 2231                .get_request_timeout()
 2232        });
 2233        let lsp_edits = {
 2234            let mut lsp_ranges = Vec::new();
 2235            this.update(cx, |_this, cx| {
 2236                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2237                // not have been sent to the language server. This seems like a fairly systemic
 2238                // issue, though, the resolution probably is not specific to formatting.
 2239                //
 2240                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2241                // LSP.
 2242                let snapshot = buffer_handle.read(cx).snapshot();
 2243                for range in ranges {
 2244                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2245                }
 2246                anyhow::Ok(())
 2247            })??;
 2248
 2249            let mut edits = None;
 2250            for range in lsp_ranges {
 2251                if let Some(mut edit) = language_server
 2252                    .request::<lsp::request::RangeFormatting>(
 2253                        lsp::DocumentRangeFormattingParams {
 2254                            text_document: text_document.clone(),
 2255                            range,
 2256                            options: lsp_command::lsp_formatting_options(settings),
 2257                            work_done_progress_params: Default::default(),
 2258                        },
 2259                        request_timeout,
 2260                    )
 2261                    .await
 2262                    .into_response()?
 2263                {
 2264                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2265                }
 2266            }
 2267            edits
 2268        };
 2269
 2270        if let Some(lsp_edits) = lsp_edits {
 2271            this.update(cx, |this, cx| {
 2272                this.as_local_mut().unwrap().edits_from_lsp(
 2273                    buffer_handle,
 2274                    lsp_edits,
 2275                    language_server.server_id(),
 2276                    None,
 2277                    cx,
 2278                )
 2279            })?
 2280            .await
 2281        } else {
 2282            Ok(Vec::with_capacity(0))
 2283        }
 2284    }
 2285
 2286    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2287        let capabilities = server.capabilities();
 2288        let formatting = capabilities.document_formatting_provider.as_ref();
 2289        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2290        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2291            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2292    }
 2293
 2294    async fn format_via_lsp(
 2295        this: &WeakEntity<LspStore>,
 2296        buffer: &Entity<Buffer>,
 2297        abs_path: &Path,
 2298        language_server: &Arc<LanguageServer>,
 2299        settings: &LanguageSettings,
 2300        cx: &mut AsyncApp,
 2301    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2302        let logger = zlog::scoped!("lsp_format");
 2303        zlog::debug!(logger => "Formatting via LSP");
 2304
 2305        let uri = file_path_to_lsp_url(abs_path)?;
 2306        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2307        let capabilities = &language_server.capabilities();
 2308
 2309        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2310        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2311
 2312        let request_timeout = cx.update(|app| {
 2313            ProjectSettings::get_global(app)
 2314                .global_lsp_settings
 2315                .get_request_timeout()
 2316        });
 2317
 2318        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2319            let _timer = zlog::time!(logger => "format-full");
 2320            language_server
 2321                .request::<lsp::request::Formatting>(
 2322                    lsp::DocumentFormattingParams {
 2323                        text_document,
 2324                        options: lsp_command::lsp_formatting_options(settings),
 2325                        work_done_progress_params: Default::default(),
 2326                    },
 2327                    request_timeout,
 2328                )
 2329                .await
 2330                .into_response()?
 2331        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2332            let _timer = zlog::time!(logger => "format-range");
 2333            let buffer_start = lsp::Position::new(0, 0);
 2334            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2335            language_server
 2336                .request::<lsp::request::RangeFormatting>(
 2337                    lsp::DocumentRangeFormattingParams {
 2338                        text_document: text_document.clone(),
 2339                        range: lsp::Range::new(buffer_start, buffer_end),
 2340                        options: lsp_command::lsp_formatting_options(settings),
 2341                        work_done_progress_params: Default::default(),
 2342                    },
 2343                    request_timeout,
 2344                )
 2345                .await
 2346                .into_response()?
 2347        } else {
 2348            None
 2349        };
 2350
 2351        if let Some(lsp_edits) = lsp_edits {
 2352            this.update(cx, |this, cx| {
 2353                this.as_local_mut().unwrap().edits_from_lsp(
 2354                    buffer,
 2355                    lsp_edits,
 2356                    language_server.server_id(),
 2357                    None,
 2358                    cx,
 2359                )
 2360            })?
 2361            .await
 2362        } else {
 2363            Ok(Vec::with_capacity(0))
 2364        }
 2365    }
 2366
 2367    async fn format_via_external_command(
 2368        buffer: &FormattableBuffer,
 2369        command: &str,
 2370        arguments: Option<&[String]>,
 2371        cx: &mut AsyncApp,
 2372    ) -> Result<Option<Diff>> {
 2373        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2374            let file = File::from_dyn(buffer.file())?;
 2375            let worktree = file.worktree.read(cx);
 2376            let mut worktree_path = worktree.abs_path().to_path_buf();
 2377            if worktree.root_entry()?.is_file() {
 2378                worktree_path.pop();
 2379            }
 2380            Some(worktree_path)
 2381        });
 2382
 2383        use util::command::Stdio;
 2384        let mut child = util::command::new_command(command);
 2385
 2386        if let Some(buffer_env) = buffer.env.as_ref() {
 2387            child.envs(buffer_env);
 2388        }
 2389
 2390        if let Some(working_dir_path) = working_dir_path {
 2391            child.current_dir(working_dir_path);
 2392        }
 2393
 2394        if let Some(arguments) = arguments {
 2395            child.args(arguments.iter().map(|arg| {
 2396                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2397                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2398                } else {
 2399                    arg.replace("{buffer_path}", "Untitled")
 2400                }
 2401            }));
 2402        }
 2403
 2404        let mut child = child
 2405            .stdin(Stdio::piped())
 2406            .stdout(Stdio::piped())
 2407            .stderr(Stdio::piped())
 2408            .spawn()?;
 2409
 2410        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2411        let text = buffer
 2412            .handle
 2413            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2414        for chunk in text.chunks() {
 2415            stdin.write_all(chunk.as_bytes()).await?;
 2416        }
 2417        stdin.flush().await?;
 2418
 2419        let output = child.output().await?;
 2420        anyhow::ensure!(
 2421            output.status.success(),
 2422            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2423            output.status.code(),
 2424            String::from_utf8_lossy(&output.stdout),
 2425            String::from_utf8_lossy(&output.stderr),
 2426        );
 2427
 2428        let stdout = String::from_utf8(output.stdout)?;
 2429        Ok(Some(
 2430            buffer
 2431                .handle
 2432                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2433                .await,
 2434        ))
 2435    }
 2436
 2437    async fn try_resolve_code_action(
 2438        lang_server: &LanguageServer,
 2439        action: &mut CodeAction,
 2440        request_timeout: Duration,
 2441    ) -> anyhow::Result<()> {
 2442        match &mut action.lsp_action {
 2443            LspAction::Action(lsp_action) => {
 2444                if !action.resolved
 2445                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2446                    && lsp_action.data.is_some()
 2447                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2448                {
 2449                    **lsp_action = lang_server
 2450                        .request::<lsp::request::CodeActionResolveRequest>(
 2451                            *lsp_action.clone(),
 2452                            request_timeout,
 2453                        )
 2454                        .await
 2455                        .into_response()?;
 2456                }
 2457            }
 2458            LspAction::CodeLens(lens) => {
 2459                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2460                    *lens = lang_server
 2461                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2462                        .await
 2463                        .into_response()?;
 2464                }
 2465            }
 2466            LspAction::Command(_) => {}
 2467        }
 2468
 2469        action.resolved = true;
 2470        anyhow::Ok(())
 2471    }
 2472
 2473    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2474        let buffer = buffer_handle.read(cx);
 2475
 2476        let file = buffer.file().cloned();
 2477
 2478        let Some(file) = File::from_dyn(file.as_ref()) else {
 2479            return;
 2480        };
 2481        if !file.is_local() {
 2482            return;
 2483        }
 2484        let path = ProjectPath::from_file(file, cx);
 2485        let worktree_id = file.worktree_id(cx);
 2486        let language = buffer.language().cloned();
 2487
 2488        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2489            for (server_id, diagnostics) in
 2490                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2491            {
 2492                self.update_buffer_diagnostics(
 2493                    buffer_handle,
 2494                    server_id,
 2495                    None,
 2496                    None,
 2497                    None,
 2498                    Vec::new(),
 2499                    diagnostics,
 2500                    cx,
 2501                )
 2502                .log_err();
 2503            }
 2504        }
 2505        let Some(language) = language else {
 2506            return;
 2507        };
 2508        let Some(snapshot) = self
 2509            .worktree_store
 2510            .read(cx)
 2511            .worktree_for_id(worktree_id, cx)
 2512            .map(|worktree| worktree.read(cx).snapshot())
 2513        else {
 2514            return;
 2515        };
 2516        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2517
 2518        for server_id in
 2519            self.lsp_tree
 2520                .get(path, language.name(), language.manifest(), &delegate, cx)
 2521        {
 2522            let server = self
 2523                .language_servers
 2524                .get(&server_id)
 2525                .and_then(|server_state| {
 2526                    if let LanguageServerState::Running { server, .. } = server_state {
 2527                        Some(server.clone())
 2528                    } else {
 2529                        None
 2530                    }
 2531                });
 2532            let server = match server {
 2533                Some(server) => server,
 2534                None => continue,
 2535            };
 2536
 2537            buffer_handle.update(cx, |buffer, cx| {
 2538                buffer.set_completion_triggers(
 2539                    server.server_id(),
 2540                    server
 2541                        .capabilities()
 2542                        .completion_provider
 2543                        .as_ref()
 2544                        .and_then(|provider| {
 2545                            provider
 2546                                .trigger_characters
 2547                                .as_ref()
 2548                                .map(|characters| characters.iter().cloned().collect())
 2549                        })
 2550                        .unwrap_or_default(),
 2551                    cx,
 2552                );
 2553            });
 2554        }
 2555    }
 2556
 2557    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2558        buffer.update(cx, |buffer, cx| {
 2559            let Some(language) = buffer.language() else {
 2560                return;
 2561            };
 2562            let path = ProjectPath {
 2563                worktree_id: old_file.worktree_id(cx),
 2564                path: old_file.path.clone(),
 2565            };
 2566            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2567                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2568                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2569            }
 2570        });
 2571    }
 2572
 2573    fn update_buffer_diagnostics(
 2574        &mut self,
 2575        buffer: &Entity<Buffer>,
 2576        server_id: LanguageServerId,
 2577        registration_id: Option<Option<SharedString>>,
 2578        result_id: Option<SharedString>,
 2579        version: Option<i32>,
 2580        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2581        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2582        cx: &mut Context<LspStore>,
 2583    ) -> Result<()> {
 2584        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2585            Ordering::Equal
 2586                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2587                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2588                .then_with(|| a.severity.cmp(&b.severity))
 2589                .then_with(|| a.message.cmp(&b.message))
 2590        }
 2591
 2592        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2593        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2594        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2595
 2596        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2597            Ordering::Equal
 2598                .then_with(|| a.range.start.cmp(&b.range.start))
 2599                .then_with(|| b.range.end.cmp(&a.range.end))
 2600                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2601        });
 2602
 2603        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2604
 2605        let edits_since_save = std::cell::LazyCell::new(|| {
 2606            let saved_version = buffer.read(cx).saved_version();
 2607            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2608        });
 2609
 2610        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2611
 2612        for (new_diagnostic, entry) in diagnostics {
 2613            let start;
 2614            let end;
 2615            if new_diagnostic && entry.diagnostic.is_disk_based {
 2616                // Some diagnostics are based on files on disk instead of buffers'
 2617                // current contents. Adjust these diagnostics' ranges to reflect
 2618                // any unsaved edits.
 2619                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2620                // and were properly adjusted on reuse.
 2621                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2622                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2623            } else {
 2624                start = entry.range.start;
 2625                end = entry.range.end;
 2626            }
 2627
 2628            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2629                ..snapshot.clip_point_utf16(end, Bias::Right);
 2630
 2631            // Expand empty ranges by one codepoint
 2632            if range.start == range.end {
 2633                // This will be go to the next boundary when being clipped
 2634                range.end.column += 1;
 2635                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2636                if range.start == range.end && range.end.column > 0 {
 2637                    range.start.column -= 1;
 2638                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2639                }
 2640            }
 2641
 2642            sanitized_diagnostics.push(DiagnosticEntry {
 2643                range,
 2644                diagnostic: entry.diagnostic,
 2645            });
 2646        }
 2647        drop(edits_since_save);
 2648
 2649        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2650        buffer.update(cx, |buffer, cx| {
 2651            if let Some(registration_id) = registration_id {
 2652                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2653                    self.buffer_pull_diagnostics_result_ids
 2654                        .entry(server_id)
 2655                        .or_default()
 2656                        .entry(registration_id)
 2657                        .or_default()
 2658                        .insert(abs_path, result_id);
 2659                }
 2660            }
 2661
 2662            buffer.update_diagnostics(server_id, set, cx)
 2663        });
 2664
 2665        Ok(())
 2666    }
 2667
 2668    fn register_language_server_for_invisible_worktree(
 2669        &mut self,
 2670        worktree: &Entity<Worktree>,
 2671        language_server_id: LanguageServerId,
 2672        cx: &mut App,
 2673    ) {
 2674        let worktree = worktree.read(cx);
 2675        let worktree_id = worktree.id();
 2676        debug_assert!(!worktree.is_visible());
 2677        let Some(mut origin_seed) = self
 2678            .language_server_ids
 2679            .iter()
 2680            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2681        else {
 2682            return;
 2683        };
 2684        origin_seed.worktree_id = worktree_id;
 2685        self.language_server_ids
 2686            .entry(origin_seed)
 2687            .or_insert_with(|| UnifiedLanguageServer {
 2688                id: language_server_id,
 2689                project_roots: Default::default(),
 2690            });
 2691    }
 2692
 2693    fn register_buffer_with_language_servers(
 2694        &mut self,
 2695        buffer_handle: &Entity<Buffer>,
 2696        only_register_servers: HashSet<LanguageServerSelector>,
 2697        cx: &mut Context<LspStore>,
 2698    ) {
 2699        let buffer = buffer_handle.read(cx);
 2700        let buffer_id = buffer.remote_id();
 2701
 2702        let Some(file) = File::from_dyn(buffer.file()) else {
 2703            return;
 2704        };
 2705        if !file.is_local() {
 2706            return;
 2707        }
 2708
 2709        let abs_path = file.abs_path(cx);
 2710        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2711            return;
 2712        };
 2713        let initial_snapshot = buffer.text_snapshot();
 2714        let worktree_id = file.worktree_id(cx);
 2715
 2716        let Some(language) = buffer.language().cloned() else {
 2717            return;
 2718        };
 2719        let path: Arc<RelPath> = file
 2720            .path()
 2721            .parent()
 2722            .map(Arc::from)
 2723            .unwrap_or_else(|| file.path().clone());
 2724        let Some(worktree) = self
 2725            .worktree_store
 2726            .read(cx)
 2727            .worktree_for_id(worktree_id, cx)
 2728        else {
 2729            return;
 2730        };
 2731        let language_name = language.name();
 2732        let (reused, delegate, servers) = self
 2733            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2734            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2735            .unwrap_or_else(|| {
 2736                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2737                let delegate: Arc<dyn ManifestDelegate> =
 2738                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2739
 2740                let servers = self
 2741                    .lsp_tree
 2742                    .walk(
 2743                        ProjectPath { worktree_id, path },
 2744                        language.name(),
 2745                        language.manifest(),
 2746                        &delegate,
 2747                        cx,
 2748                    )
 2749                    .collect::<Vec<_>>();
 2750                (false, lsp_delegate, servers)
 2751            });
 2752        let servers_and_adapters = servers
 2753            .into_iter()
 2754            .filter_map(|server_node| {
 2755                if reused && server_node.server_id().is_none() {
 2756                    return None;
 2757                }
 2758                if !only_register_servers.is_empty() {
 2759                    if let Some(server_id) = server_node.server_id()
 2760                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2761                    {
 2762                        return None;
 2763                    }
 2764                    if let Some(name) = server_node.name()
 2765                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2766                    {
 2767                        return None;
 2768                    }
 2769                }
 2770
 2771                let server_id = server_node.server_id_or_init(|disposition| {
 2772                    let path = &disposition.path;
 2773
 2774                    {
 2775                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2776
 2777                        let server_id = self.get_or_insert_language_server(
 2778                            &worktree,
 2779                            delegate.clone(),
 2780                            disposition,
 2781                            &language_name,
 2782                            cx,
 2783                        );
 2784
 2785                        if let Some(state) = self.language_servers.get(&server_id)
 2786                            && let Ok(uri) = uri
 2787                        {
 2788                            state.add_workspace_folder(uri);
 2789                        };
 2790                        server_id
 2791                    }
 2792                })?;
 2793                let server_state = self.language_servers.get(&server_id)?;
 2794                if let LanguageServerState::Running {
 2795                    server, adapter, ..
 2796                } = server_state
 2797                {
 2798                    Some((server.clone(), adapter.clone()))
 2799                } else {
 2800                    None
 2801                }
 2802            })
 2803            .collect::<Vec<_>>();
 2804        for (server, adapter) in servers_and_adapters {
 2805            buffer_handle.update(cx, |buffer, cx| {
 2806                buffer.set_completion_triggers(
 2807                    server.server_id(),
 2808                    server
 2809                        .capabilities()
 2810                        .completion_provider
 2811                        .as_ref()
 2812                        .and_then(|provider| {
 2813                            provider
 2814                                .trigger_characters
 2815                                .as_ref()
 2816                                .map(|characters| characters.iter().cloned().collect())
 2817                        })
 2818                        .unwrap_or_default(),
 2819                    cx,
 2820                );
 2821            });
 2822
 2823            let snapshot = LspBufferSnapshot {
 2824                version: 0,
 2825                snapshot: initial_snapshot.clone(),
 2826            };
 2827
 2828            let mut registered = false;
 2829            self.buffer_snapshots
 2830                .entry(buffer_id)
 2831                .or_default()
 2832                .entry(server.server_id())
 2833                .or_insert_with(|| {
 2834                    registered = true;
 2835                    server.register_buffer(
 2836                        uri.clone(),
 2837                        adapter.language_id(&language.name()),
 2838                        0,
 2839                        initial_snapshot.text(),
 2840                    );
 2841
 2842                    vec![snapshot]
 2843                });
 2844
 2845            self.buffers_opened_in_servers
 2846                .entry(buffer_id)
 2847                .or_default()
 2848                .insert(server.server_id());
 2849            if registered {
 2850                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2851                    language_server_id: server.server_id(),
 2852                    name: None,
 2853                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2854                        proto::RegisteredForBuffer {
 2855                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2856                            buffer_id: buffer_id.to_proto(),
 2857                        },
 2858                    ),
 2859                });
 2860            }
 2861        }
 2862    }
 2863
 2864    fn reuse_existing_language_server<'lang_name>(
 2865        &self,
 2866        server_tree: &LanguageServerTree,
 2867        worktree: &Entity<Worktree>,
 2868        language_name: &'lang_name LanguageName,
 2869        cx: &mut App,
 2870    ) -> Option<(
 2871        Arc<LocalLspAdapterDelegate>,
 2872        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2873    )> {
 2874        if worktree.read(cx).is_visible() {
 2875            return None;
 2876        }
 2877
 2878        let worktree_store = self.worktree_store.read(cx);
 2879        let servers = server_tree
 2880            .instances
 2881            .iter()
 2882            .filter(|(worktree_id, _)| {
 2883                worktree_store
 2884                    .worktree_for_id(**worktree_id, cx)
 2885                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2886            })
 2887            .flat_map(|(worktree_id, servers)| {
 2888                servers
 2889                    .roots
 2890                    .iter()
 2891                    .flat_map(|(_, language_servers)| language_servers)
 2892                    .map(move |(_, (server_node, server_languages))| {
 2893                        (worktree_id, server_node, server_languages)
 2894                    })
 2895                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2896                    .map(|(worktree_id, server_node, _)| {
 2897                        (
 2898                            *worktree_id,
 2899                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2900                        )
 2901                    })
 2902            })
 2903            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2904                acc.entry(worktree_id)
 2905                    .or_insert_with(Vec::new)
 2906                    .push(server_node);
 2907                acc
 2908            })
 2909            .into_values()
 2910            .max_by_key(|servers| servers.len())?;
 2911
 2912        let worktree_id = worktree.read(cx).id();
 2913        let apply = move |tree: &mut LanguageServerTree| {
 2914            for server_node in &servers {
 2915                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2916            }
 2917            servers
 2918        };
 2919
 2920        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2921        Some((delegate, apply))
 2922    }
 2923
 2924    pub(crate) fn unregister_old_buffer_from_language_servers(
 2925        &mut self,
 2926        buffer: &Entity<Buffer>,
 2927        old_file: &File,
 2928        cx: &mut App,
 2929    ) {
 2930        let old_path = match old_file.as_local() {
 2931            Some(local) => local.abs_path(cx),
 2932            None => return,
 2933        };
 2934
 2935        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2936            debug_panic!("{old_path:?} is not parseable as an URI");
 2937            return;
 2938        };
 2939        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2940    }
 2941
 2942    pub(crate) fn unregister_buffer_from_language_servers(
 2943        &mut self,
 2944        buffer: &Entity<Buffer>,
 2945        file_url: &lsp::Uri,
 2946        cx: &mut App,
 2947    ) {
 2948        buffer.update(cx, |buffer, cx| {
 2949            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2950
 2951            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2952                if snapshots
 2953                    .as_mut()
 2954                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2955                {
 2956                    language_server.unregister_buffer(file_url.clone());
 2957                }
 2958            }
 2959        });
 2960    }
 2961
 2962    fn buffer_snapshot_for_lsp_version(
 2963        &mut self,
 2964        buffer: &Entity<Buffer>,
 2965        server_id: LanguageServerId,
 2966        version: Option<i32>,
 2967        cx: &App,
 2968    ) -> Result<TextBufferSnapshot> {
 2969        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2970
 2971        if let Some(version) = version {
 2972            let buffer_id = buffer.read(cx).remote_id();
 2973            let snapshots = if let Some(snapshots) = self
 2974                .buffer_snapshots
 2975                .get_mut(&buffer_id)
 2976                .and_then(|m| m.get_mut(&server_id))
 2977            {
 2978                snapshots
 2979            } else if version == 0 {
 2980                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2981                // We detect this case and treat it as if the version was `None`.
 2982                return Ok(buffer.read(cx).text_snapshot());
 2983            } else {
 2984                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2985            };
 2986
 2987            let found_snapshot = snapshots
 2988                    .binary_search_by_key(&version, |e| e.version)
 2989                    .map(|ix| snapshots[ix].snapshot.clone())
 2990                    .map_err(|_| {
 2991                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2992                    })?;
 2993
 2994            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2995            Ok(found_snapshot)
 2996        } else {
 2997            Ok((buffer.read(cx)).text_snapshot())
 2998        }
 2999    }
 3000
 3001    async fn get_server_code_actions_from_action_kinds(
 3002        lsp_store: &WeakEntity<LspStore>,
 3003        language_server_id: LanguageServerId,
 3004        code_action_kinds: Vec<lsp::CodeActionKind>,
 3005        buffer: &Entity<Buffer>,
 3006        cx: &mut AsyncApp,
 3007    ) -> Result<Vec<CodeAction>> {
 3008        let actions = lsp_store
 3009            .update(cx, move |this, cx| {
 3010                let request = GetCodeActions {
 3011                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3012                    kinds: Some(code_action_kinds),
 3013                };
 3014                let server = LanguageServerToQuery::Other(language_server_id);
 3015                this.request_lsp(buffer.clone(), server, request, cx)
 3016            })?
 3017            .await?;
 3018        Ok(actions)
 3019    }
 3020
 3021    pub async fn execute_code_actions_on_server(
 3022        lsp_store: &WeakEntity<LspStore>,
 3023        language_server: &Arc<LanguageServer>,
 3024        actions: Vec<CodeAction>,
 3025        push_to_history: bool,
 3026        project_transaction: &mut ProjectTransaction,
 3027        cx: &mut AsyncApp,
 3028    ) -> anyhow::Result<()> {
 3029        let request_timeout = cx.update(|app| {
 3030            ProjectSettings::get_global(app)
 3031                .global_lsp_settings
 3032                .get_request_timeout()
 3033        });
 3034
 3035        for mut action in actions {
 3036            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3037                .await
 3038                .context("resolving a formatting code action")?;
 3039
 3040            if let Some(edit) = action.lsp_action.edit() {
 3041                if edit.changes.is_none() && edit.document_changes.is_none() {
 3042                    continue;
 3043                }
 3044
 3045                let new = Self::deserialize_workspace_edit(
 3046                    lsp_store.upgrade().context("project dropped")?,
 3047                    edit.clone(),
 3048                    push_to_history,
 3049                    language_server.clone(),
 3050                    cx,
 3051                )
 3052                .await?;
 3053                project_transaction.0.extend(new.0);
 3054            }
 3055
 3056            let Some(command) = action.lsp_action.command() else {
 3057                continue;
 3058            };
 3059
 3060            let server_capabilities = language_server.capabilities();
 3061            let available_commands = server_capabilities
 3062                .execute_command_provider
 3063                .as_ref()
 3064                .map(|options| options.commands.as_slice())
 3065                .unwrap_or_default();
 3066            if !available_commands.contains(&command.command) {
 3067                log::warn!(
 3068                    "Cannot execute a command {} not listed in the language server capabilities",
 3069                    command.command
 3070                );
 3071                continue;
 3072            }
 3073
 3074            lsp_store.update(cx, |lsp_store, _| {
 3075                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3076                    mode.last_workspace_edits_by_language_server
 3077                        .remove(&language_server.server_id());
 3078                }
 3079            })?;
 3080
 3081            language_server
 3082                .request::<lsp::request::ExecuteCommand>(
 3083                    lsp::ExecuteCommandParams {
 3084                        command: command.command.clone(),
 3085                        arguments: command.arguments.clone().unwrap_or_default(),
 3086                        ..Default::default()
 3087                    },
 3088                    request_timeout,
 3089                )
 3090                .await
 3091                .into_response()
 3092                .context("execute command")?;
 3093
 3094            lsp_store.update(cx, |this, _| {
 3095                if let LspStoreMode::Local(mode) = &mut this.mode {
 3096                    project_transaction.0.extend(
 3097                        mode.last_workspace_edits_by_language_server
 3098                            .remove(&language_server.server_id())
 3099                            .unwrap_or_default()
 3100                            .0,
 3101                    )
 3102                }
 3103            })?;
 3104        }
 3105        Ok(())
 3106    }
 3107
 3108    pub async fn deserialize_text_edits(
 3109        this: Entity<LspStore>,
 3110        buffer_to_edit: Entity<Buffer>,
 3111        edits: Vec<lsp::TextEdit>,
 3112        push_to_history: bool,
 3113        _: Arc<CachedLspAdapter>,
 3114        language_server: Arc<LanguageServer>,
 3115        cx: &mut AsyncApp,
 3116    ) -> Result<Option<Transaction>> {
 3117        let edits = this
 3118            .update(cx, |this, cx| {
 3119                this.as_local_mut().unwrap().edits_from_lsp(
 3120                    &buffer_to_edit,
 3121                    edits,
 3122                    language_server.server_id(),
 3123                    None,
 3124                    cx,
 3125                )
 3126            })
 3127            .await?;
 3128
 3129        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3130            buffer.finalize_last_transaction();
 3131            buffer.start_transaction();
 3132            for (range, text) in edits {
 3133                buffer.edit([(range, text)], None, cx);
 3134            }
 3135
 3136            if buffer.end_transaction(cx).is_some() {
 3137                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3138                if !push_to_history {
 3139                    buffer.forget_transaction(transaction.id);
 3140                }
 3141                Some(transaction)
 3142            } else {
 3143                None
 3144            }
 3145        });
 3146
 3147        Ok(transaction)
 3148    }
 3149
 3150    #[allow(clippy::type_complexity)]
 3151    pub fn edits_from_lsp(
 3152        &mut self,
 3153        buffer: &Entity<Buffer>,
 3154        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3155        server_id: LanguageServerId,
 3156        version: Option<i32>,
 3157        cx: &mut Context<LspStore>,
 3158    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3159        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3160        cx.background_spawn(async move {
 3161            let snapshot = snapshot?;
 3162            let mut lsp_edits = lsp_edits
 3163                .into_iter()
 3164                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3165                .collect::<Vec<_>>();
 3166
 3167            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3168
 3169            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3170            let mut edits = Vec::new();
 3171            while let Some((range, mut new_text)) = lsp_edits.next() {
 3172                // Clip invalid ranges provided by the language server.
 3173                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3174                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3175
 3176                // Combine any LSP edits that are adjacent.
 3177                //
 3178                // Also, combine LSP edits that are separated from each other by only
 3179                // a newline. This is important because for some code actions,
 3180                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3181                // are separated by unchanged newline characters.
 3182                //
 3183                // In order for the diffing logic below to work properly, any edits that
 3184                // cancel each other out must be combined into one.
 3185                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3186                    if next_range.start.0 > range.end {
 3187                        if next_range.start.0.row > range.end.row + 1
 3188                            || next_range.start.0.column > 0
 3189                            || snapshot.clip_point_utf16(
 3190                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3191                                Bias::Left,
 3192                            ) > range.end
 3193                        {
 3194                            break;
 3195                        }
 3196                        new_text.push('\n');
 3197                    }
 3198                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3199                    new_text.push_str(next_text);
 3200                    lsp_edits.next();
 3201                }
 3202
 3203                // For multiline edits, perform a diff of the old and new text so that
 3204                // we can identify the changes more precisely, preserving the locations
 3205                // of any anchors positioned in the unchanged regions.
 3206                if range.end.row > range.start.row {
 3207                    let offset = range.start.to_offset(&snapshot);
 3208                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3209                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3210                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3211                        (
 3212                            snapshot.anchor_after(offset + range.start)
 3213                                ..snapshot.anchor_before(offset + range.end),
 3214                            replacement,
 3215                        )
 3216                    }));
 3217                } else if range.end == range.start {
 3218                    let anchor = snapshot.anchor_after(range.start);
 3219                    edits.push((anchor..anchor, new_text.into()));
 3220                } else {
 3221                    let edit_start = snapshot.anchor_after(range.start);
 3222                    let edit_end = snapshot.anchor_before(range.end);
 3223                    edits.push((edit_start..edit_end, new_text.into()));
 3224                }
 3225            }
 3226
 3227            Ok(edits)
 3228        })
 3229    }
 3230
 3231    pub(crate) async fn deserialize_workspace_edit(
 3232        this: Entity<LspStore>,
 3233        edit: lsp::WorkspaceEdit,
 3234        push_to_history: bool,
 3235        language_server: Arc<LanguageServer>,
 3236        cx: &mut AsyncApp,
 3237    ) -> Result<ProjectTransaction> {
 3238        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3239
 3240        let mut operations = Vec::new();
 3241        if let Some(document_changes) = edit.document_changes {
 3242            match document_changes {
 3243                lsp::DocumentChanges::Edits(edits) => {
 3244                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3245                }
 3246                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3247            }
 3248        } else if let Some(changes) = edit.changes {
 3249            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3250                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3251                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3252                        uri,
 3253                        version: None,
 3254                    },
 3255                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3256                })
 3257            }));
 3258        }
 3259
 3260        let mut project_transaction = ProjectTransaction::default();
 3261        for operation in operations {
 3262            match operation {
 3263                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3264                    let abs_path = op
 3265                        .uri
 3266                        .to_file_path()
 3267                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3268
 3269                    if let Some(parent_path) = abs_path.parent() {
 3270                        fs.create_dir(parent_path).await?;
 3271                    }
 3272                    if abs_path.ends_with("/") {
 3273                        fs.create_dir(&abs_path).await?;
 3274                    } else {
 3275                        fs.create_file(
 3276                            &abs_path,
 3277                            op.options
 3278                                .map(|options| fs::CreateOptions {
 3279                                    overwrite: options.overwrite.unwrap_or(false),
 3280                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3281                                })
 3282                                .unwrap_or_default(),
 3283                        )
 3284                        .await?;
 3285                    }
 3286                }
 3287
 3288                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3289                    let source_abs_path = op
 3290                        .old_uri
 3291                        .to_file_path()
 3292                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3293                    let target_abs_path = op
 3294                        .new_uri
 3295                        .to_file_path()
 3296                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3297
 3298                    let options = fs::RenameOptions {
 3299                        overwrite: op
 3300                            .options
 3301                            .as_ref()
 3302                            .and_then(|options| options.overwrite)
 3303                            .unwrap_or(false),
 3304                        ignore_if_exists: op
 3305                            .options
 3306                            .as_ref()
 3307                            .and_then(|options| options.ignore_if_exists)
 3308                            .unwrap_or(false),
 3309                        create_parents: true,
 3310                    };
 3311
 3312                    fs.rename(&source_abs_path, &target_abs_path, options)
 3313                        .await?;
 3314                }
 3315
 3316                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3317                    let abs_path = op
 3318                        .uri
 3319                        .to_file_path()
 3320                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3321                    let options = op
 3322                        .options
 3323                        .map(|options| fs::RemoveOptions {
 3324                            recursive: options.recursive.unwrap_or(false),
 3325                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3326                        })
 3327                        .unwrap_or_default();
 3328                    if abs_path.ends_with("/") {
 3329                        fs.remove_dir(&abs_path, options).await?;
 3330                    } else {
 3331                        fs.remove_file(&abs_path, options).await?;
 3332                    }
 3333                }
 3334
 3335                lsp::DocumentChangeOperation::Edit(op) => {
 3336                    let buffer_to_edit = this
 3337                        .update(cx, |this, cx| {
 3338                            this.open_local_buffer_via_lsp(
 3339                                op.text_document.uri.clone(),
 3340                                language_server.server_id(),
 3341                                cx,
 3342                            )
 3343                        })
 3344                        .await?;
 3345
 3346                    let edits = this
 3347                        .update(cx, |this, cx| {
 3348                            let path = buffer_to_edit.read(cx).project_path(cx);
 3349                            let active_entry = this.active_entry;
 3350                            let is_active_entry = path.is_some_and(|project_path| {
 3351                                this.worktree_store
 3352                                    .read(cx)
 3353                                    .entry_for_path(&project_path, cx)
 3354                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3355                            });
 3356                            let local = this.as_local_mut().unwrap();
 3357
 3358                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3359                            for edit in op.edits {
 3360                                match edit {
 3361                                    Edit::Plain(edit) => {
 3362                                        if !edits.contains(&edit) {
 3363                                            edits.push(edit)
 3364                                        }
 3365                                    }
 3366                                    Edit::Annotated(edit) => {
 3367                                        if !edits.contains(&edit.text_edit) {
 3368                                            edits.push(edit.text_edit)
 3369                                        }
 3370                                    }
 3371                                    Edit::Snippet(edit) => {
 3372                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3373                                        else {
 3374                                            continue;
 3375                                        };
 3376
 3377                                        if is_active_entry {
 3378                                            snippet_edits.push((edit.range, snippet));
 3379                                        } else {
 3380                                            // Since this buffer is not focused, apply a normal edit.
 3381                                            let new_edit = TextEdit {
 3382                                                range: edit.range,
 3383                                                new_text: snippet.text,
 3384                                            };
 3385                                            if !edits.contains(&new_edit) {
 3386                                                edits.push(new_edit);
 3387                                            }
 3388                                        }
 3389                                    }
 3390                                }
 3391                            }
 3392                            if !snippet_edits.is_empty() {
 3393                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3394                                let version = if let Some(buffer_version) = op.text_document.version
 3395                                {
 3396                                    local
 3397                                        .buffer_snapshot_for_lsp_version(
 3398                                            &buffer_to_edit,
 3399                                            language_server.server_id(),
 3400                                            Some(buffer_version),
 3401                                            cx,
 3402                                        )
 3403                                        .ok()
 3404                                        .map(|snapshot| snapshot.version)
 3405                                } else {
 3406                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3407                                };
 3408
 3409                                let most_recent_edit =
 3410                                    version.and_then(|version| version.most_recent());
 3411                                // Check if the edit that triggered that edit has been made by this participant.
 3412
 3413                                if let Some(most_recent_edit) = most_recent_edit {
 3414                                    cx.emit(LspStoreEvent::SnippetEdit {
 3415                                        buffer_id,
 3416                                        edits: snippet_edits,
 3417                                        most_recent_edit,
 3418                                    });
 3419                                }
 3420                            }
 3421
 3422                            local.edits_from_lsp(
 3423                                &buffer_to_edit,
 3424                                edits,
 3425                                language_server.server_id(),
 3426                                op.text_document.version,
 3427                                cx,
 3428                            )
 3429                        })
 3430                        .await?;
 3431
 3432                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3433                        buffer.finalize_last_transaction();
 3434                        buffer.start_transaction();
 3435                        for (range, text) in edits {
 3436                            buffer.edit([(range, text)], None, cx);
 3437                        }
 3438
 3439                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3440                            if push_to_history {
 3441                                buffer.finalize_last_transaction();
 3442                                buffer.get_transaction(transaction_id).cloned()
 3443                            } else {
 3444                                buffer.forget_transaction(transaction_id)
 3445                            }
 3446                        })
 3447                    });
 3448                    if let Some(transaction) = transaction {
 3449                        project_transaction.0.insert(buffer_to_edit, transaction);
 3450                    }
 3451                }
 3452            }
 3453        }
 3454
 3455        Ok(project_transaction)
 3456    }
 3457
 3458    async fn on_lsp_workspace_edit(
 3459        this: WeakEntity<LspStore>,
 3460        params: lsp::ApplyWorkspaceEditParams,
 3461        server_id: LanguageServerId,
 3462        cx: &mut AsyncApp,
 3463    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3464        let this = this.upgrade().context("project project closed")?;
 3465        let language_server = this
 3466            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3467            .context("language server not found")?;
 3468        let transaction = Self::deserialize_workspace_edit(
 3469            this.clone(),
 3470            params.edit,
 3471            true,
 3472            language_server.clone(),
 3473            cx,
 3474        )
 3475        .await
 3476        .log_err();
 3477        this.update(cx, |this, cx| {
 3478            if let Some(transaction) = transaction {
 3479                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3480
 3481                this.as_local_mut()
 3482                    .unwrap()
 3483                    .last_workspace_edits_by_language_server
 3484                    .insert(server_id, transaction);
 3485            }
 3486        });
 3487        Ok(lsp::ApplyWorkspaceEditResponse {
 3488            applied: true,
 3489            failed_change: None,
 3490            failure_reason: None,
 3491        })
 3492    }
 3493
 3494    fn remove_worktree(
 3495        &mut self,
 3496        id_to_remove: WorktreeId,
 3497        cx: &mut Context<LspStore>,
 3498    ) -> Vec<LanguageServerId> {
 3499        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3500        self.diagnostics.remove(&id_to_remove);
 3501        self.prettier_store.update(cx, |prettier_store, cx| {
 3502            prettier_store.remove_worktree(id_to_remove, cx);
 3503        });
 3504
 3505        let mut servers_to_remove = BTreeSet::default();
 3506        let mut servers_to_preserve = HashSet::default();
 3507        for (seed, state) in &self.language_server_ids {
 3508            if seed.worktree_id == id_to_remove {
 3509                servers_to_remove.insert(state.id);
 3510            } else {
 3511                servers_to_preserve.insert(state.id);
 3512            }
 3513        }
 3514        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3515        self.language_server_ids
 3516            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3517        for server_id_to_remove in &servers_to_remove {
 3518            self.language_server_watched_paths
 3519                .remove(server_id_to_remove);
 3520            self.language_server_paths_watched_for_rename
 3521                .remove(server_id_to_remove);
 3522            self.last_workspace_edits_by_language_server
 3523                .remove(server_id_to_remove);
 3524            self.language_servers.remove(server_id_to_remove);
 3525            self.buffer_pull_diagnostics_result_ids
 3526                .remove(server_id_to_remove);
 3527            self.workspace_pull_diagnostics_result_ids
 3528                .remove(server_id_to_remove);
 3529            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3530                buffer_servers.remove(server_id_to_remove);
 3531            }
 3532            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3533        }
 3534        servers_to_remove.into_iter().collect()
 3535    }
 3536
 3537    fn rebuild_watched_paths_inner<'a>(
 3538        &'a self,
 3539        language_server_id: LanguageServerId,
 3540        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3541        cx: &mut Context<LspStore>,
 3542    ) -> LanguageServerWatchedPathsBuilder {
 3543        let worktrees = self
 3544            .worktree_store
 3545            .read(cx)
 3546            .worktrees()
 3547            .filter_map(|worktree| {
 3548                self.language_servers_for_worktree(worktree.read(cx).id())
 3549                    .find(|server| server.server_id() == language_server_id)
 3550                    .map(|_| worktree)
 3551            })
 3552            .collect::<Vec<_>>();
 3553
 3554        let mut worktree_globs = HashMap::default();
 3555        let mut abs_globs = HashMap::default();
 3556        log::trace!(
 3557            "Processing new watcher paths for language server with id {}",
 3558            language_server_id
 3559        );
 3560
 3561        for watcher in watchers {
 3562            if let Some((worktree, literal_prefix, pattern)) =
 3563                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3564            {
 3565                worktree.update(cx, |worktree, _| {
 3566                    if let Some((tree, glob)) =
 3567                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3568                    {
 3569                        tree.add_path_prefix_to_scan(literal_prefix);
 3570                        worktree_globs
 3571                            .entry(tree.id())
 3572                            .or_insert_with(GlobSetBuilder::new)
 3573                            .add(glob);
 3574                    }
 3575                });
 3576            } else {
 3577                let (path, pattern) = match &watcher.glob_pattern {
 3578                    lsp::GlobPattern::String(s) => {
 3579                        let watcher_path = SanitizedPath::new(s);
 3580                        let path = glob_literal_prefix(watcher_path.as_path());
 3581                        let pattern = watcher_path
 3582                            .as_path()
 3583                            .strip_prefix(&path)
 3584                            .map(|p| p.to_string_lossy().into_owned())
 3585                            .unwrap_or_else(|e| {
 3586                                debug_panic!(
 3587                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3588                                    s,
 3589                                    path.display(),
 3590                                    e
 3591                                );
 3592                                watcher_path.as_path().to_string_lossy().into_owned()
 3593                            });
 3594                        (path, pattern)
 3595                    }
 3596                    lsp::GlobPattern::Relative(rp) => {
 3597                        let Ok(mut base_uri) = match &rp.base_uri {
 3598                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3599                            lsp::OneOf::Right(base_uri) => base_uri,
 3600                        }
 3601                        .to_file_path() else {
 3602                            continue;
 3603                        };
 3604
 3605                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3606                        let pattern = Path::new(&rp.pattern)
 3607                            .strip_prefix(&path)
 3608                            .map(|p| p.to_string_lossy().into_owned())
 3609                            .unwrap_or_else(|e| {
 3610                                debug_panic!(
 3611                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3612                                    rp.pattern,
 3613                                    path.display(),
 3614                                    e
 3615                                );
 3616                                rp.pattern.clone()
 3617                            });
 3618                        base_uri.push(path);
 3619                        (base_uri, pattern)
 3620                    }
 3621                };
 3622
 3623                if let Some(glob) = Glob::new(&pattern).log_err() {
 3624                    if !path
 3625                        .components()
 3626                        .any(|c| matches!(c, path::Component::Normal(_)))
 3627                    {
 3628                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3629                        // rather than adding a new watcher for `/`.
 3630                        for worktree in &worktrees {
 3631                            worktree_globs
 3632                                .entry(worktree.read(cx).id())
 3633                                .or_insert_with(GlobSetBuilder::new)
 3634                                .add(glob.clone());
 3635                        }
 3636                    } else {
 3637                        abs_globs
 3638                            .entry(path.into())
 3639                            .or_insert_with(GlobSetBuilder::new)
 3640                            .add(glob);
 3641                    }
 3642                }
 3643            }
 3644        }
 3645
 3646        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3647        for (worktree_id, builder) in worktree_globs {
 3648            if let Ok(globset) = builder.build() {
 3649                watch_builder.watch_worktree(worktree_id, globset);
 3650            }
 3651        }
 3652        for (abs_path, builder) in abs_globs {
 3653            if let Ok(globset) = builder.build() {
 3654                watch_builder.watch_abs_path(abs_path, globset);
 3655            }
 3656        }
 3657        watch_builder
 3658    }
 3659
 3660    fn worktree_and_path_for_file_watcher(
 3661        worktrees: &[Entity<Worktree>],
 3662        watcher: &FileSystemWatcher,
 3663        cx: &App,
 3664    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3665        worktrees.iter().find_map(|worktree| {
 3666            let tree = worktree.read(cx);
 3667            let worktree_root_path = tree.abs_path();
 3668            let path_style = tree.path_style();
 3669            match &watcher.glob_pattern {
 3670                lsp::GlobPattern::String(s) => {
 3671                    let watcher_path = SanitizedPath::new(s);
 3672                    let relative = watcher_path
 3673                        .as_path()
 3674                        .strip_prefix(&worktree_root_path)
 3675                        .ok()?;
 3676                    let literal_prefix = glob_literal_prefix(relative);
 3677                    Some((
 3678                        worktree.clone(),
 3679                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3680                        relative.to_string_lossy().into_owned(),
 3681                    ))
 3682                }
 3683                lsp::GlobPattern::Relative(rp) => {
 3684                    let base_uri = match &rp.base_uri {
 3685                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3686                        lsp::OneOf::Right(base_uri) => base_uri,
 3687                    }
 3688                    .to_file_path()
 3689                    .ok()?;
 3690                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3691                    let mut literal_prefix = relative.to_owned();
 3692                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3693                    Some((
 3694                        worktree.clone(),
 3695                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3696                        rp.pattern.clone(),
 3697                    ))
 3698                }
 3699            }
 3700        })
 3701    }
 3702
 3703    fn rebuild_watched_paths(
 3704        &mut self,
 3705        language_server_id: LanguageServerId,
 3706        cx: &mut Context<LspStore>,
 3707    ) {
 3708        let Some(registrations) = self
 3709            .language_server_dynamic_registrations
 3710            .get(&language_server_id)
 3711        else {
 3712            return;
 3713        };
 3714
 3715        let watch_builder = self.rebuild_watched_paths_inner(
 3716            language_server_id,
 3717            registrations.did_change_watched_files.values().flatten(),
 3718            cx,
 3719        );
 3720        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3721        self.language_server_watched_paths
 3722            .insert(language_server_id, watcher);
 3723
 3724        cx.notify();
 3725    }
 3726
 3727    fn on_lsp_did_change_watched_files(
 3728        &mut self,
 3729        language_server_id: LanguageServerId,
 3730        registration_id: &str,
 3731        params: DidChangeWatchedFilesRegistrationOptions,
 3732        cx: &mut Context<LspStore>,
 3733    ) {
 3734        let registrations = self
 3735            .language_server_dynamic_registrations
 3736            .entry(language_server_id)
 3737            .or_default();
 3738
 3739        registrations
 3740            .did_change_watched_files
 3741            .insert(registration_id.to_string(), params.watchers);
 3742
 3743        self.rebuild_watched_paths(language_server_id, cx);
 3744    }
 3745
 3746    fn on_lsp_unregister_did_change_watched_files(
 3747        &mut self,
 3748        language_server_id: LanguageServerId,
 3749        registration_id: &str,
 3750        cx: &mut Context<LspStore>,
 3751    ) {
 3752        let registrations = self
 3753            .language_server_dynamic_registrations
 3754            .entry(language_server_id)
 3755            .or_default();
 3756
 3757        if registrations
 3758            .did_change_watched_files
 3759            .remove(registration_id)
 3760            .is_some()
 3761        {
 3762            log::info!(
 3763                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3764                language_server_id,
 3765                registration_id
 3766            );
 3767        } else {
 3768            log::warn!(
 3769                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3770                language_server_id,
 3771                registration_id
 3772            );
 3773        }
 3774
 3775        self.rebuild_watched_paths(language_server_id, cx);
 3776    }
 3777
 3778    async fn initialization_options_for_adapter(
 3779        adapter: Arc<dyn LspAdapter>,
 3780        delegate: &Arc<dyn LspAdapterDelegate>,
 3781        cx: &mut AsyncApp,
 3782    ) -> Result<Option<serde_json::Value>> {
 3783        let Some(mut initialization_config) =
 3784            adapter.clone().initialization_options(delegate, cx).await?
 3785        else {
 3786            return Ok(None);
 3787        };
 3788
 3789        for other_adapter in delegate.registered_lsp_adapters() {
 3790            if other_adapter.name() == adapter.name() {
 3791                continue;
 3792            }
 3793            if let Ok(Some(target_config)) = other_adapter
 3794                .clone()
 3795                .additional_initialization_options(adapter.name(), delegate)
 3796                .await
 3797            {
 3798                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3799            }
 3800        }
 3801
 3802        Ok(Some(initialization_config))
 3803    }
 3804
 3805    async fn workspace_configuration_for_adapter(
 3806        adapter: Arc<dyn LspAdapter>,
 3807        delegate: &Arc<dyn LspAdapterDelegate>,
 3808        toolchain: Option<Toolchain>,
 3809        requested_uri: Option<Uri>,
 3810        cx: &mut AsyncApp,
 3811    ) -> Result<serde_json::Value> {
 3812        let mut workspace_config = adapter
 3813            .clone()
 3814            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3815            .await?;
 3816
 3817        for other_adapter in delegate.registered_lsp_adapters() {
 3818            if other_adapter.name() == adapter.name() {
 3819                continue;
 3820            }
 3821            if let Ok(Some(target_config)) = other_adapter
 3822                .clone()
 3823                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3824                .await
 3825            {
 3826                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3827            }
 3828        }
 3829
 3830        Ok(workspace_config)
 3831    }
 3832
 3833    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3834        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3835            Some(server.clone())
 3836        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3837            Some(Arc::clone(server))
 3838        } else {
 3839            None
 3840        }
 3841    }
 3842}
 3843
 3844fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3845    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3846        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3847            language_server_id: server.server_id(),
 3848            name: Some(server.name()),
 3849            message: proto::update_language_server::Variant::MetadataUpdated(
 3850                proto::ServerMetadataUpdated {
 3851                    capabilities: Some(capabilities),
 3852                    binary: Some(proto::LanguageServerBinaryInfo {
 3853                        path: server.binary().path.to_string_lossy().into_owned(),
 3854                        arguments: server
 3855                            .binary()
 3856                            .arguments
 3857                            .iter()
 3858                            .map(|arg| arg.to_string_lossy().into_owned())
 3859                            .collect(),
 3860                    }),
 3861                    configuration: serde_json::to_string(server.configuration()).ok(),
 3862                    workspace_folders: server
 3863                        .workspace_folders()
 3864                        .iter()
 3865                        .map(|uri| uri.to_string())
 3866                        .collect(),
 3867                },
 3868            ),
 3869        });
 3870    }
 3871}
 3872
 3873#[derive(Debug)]
 3874pub struct FormattableBuffer {
 3875    handle: Entity<Buffer>,
 3876    abs_path: Option<PathBuf>,
 3877    env: Option<HashMap<String, String>>,
 3878    ranges: Option<Vec<Range<Anchor>>>,
 3879}
 3880
 3881pub struct RemoteLspStore {
 3882    upstream_client: Option<AnyProtoClient>,
 3883    upstream_project_id: u64,
 3884}
 3885
 3886pub(crate) enum LspStoreMode {
 3887    Local(LocalLspStore),   // ssh host and collab host
 3888    Remote(RemoteLspStore), // collab guest
 3889}
 3890
 3891impl LspStoreMode {
 3892    fn is_local(&self) -> bool {
 3893        matches!(self, LspStoreMode::Local(_))
 3894    }
 3895}
 3896
 3897pub struct LspStore {
 3898    mode: LspStoreMode,
 3899    last_formatting_failure: Option<String>,
 3900    downstream_client: Option<(AnyProtoClient, u64)>,
 3901    nonce: u128,
 3902    buffer_store: Entity<BufferStore>,
 3903    worktree_store: Entity<WorktreeStore>,
 3904    pub languages: Arc<LanguageRegistry>,
 3905    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3906    active_entry: Option<ProjectEntryId>,
 3907    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3908    _maintain_buffer_languages: Task<()>,
 3909    diagnostic_summaries:
 3910        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3911    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3912    semantic_token_config: SemanticTokenConfig,
 3913    lsp_data: HashMap<BufferId, BufferLspData>,
 3914    next_hint_id: Arc<AtomicUsize>,
 3915}
 3916
 3917#[derive(Debug)]
 3918pub struct BufferLspData {
 3919    buffer_version: Global,
 3920    document_colors: Option<DocumentColorData>,
 3921    code_lens: Option<CodeLensData>,
 3922    semantic_tokens: Option<SemanticTokensData>,
 3923    folding_ranges: Option<FoldingRangeData>,
 3924    document_symbols: Option<DocumentSymbolsData>,
 3925    inlay_hints: BufferInlayHints,
 3926    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3927    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3928}
 3929
 3930#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3931struct LspKey {
 3932    request_type: TypeId,
 3933    server_queried: Option<LanguageServerId>,
 3934}
 3935
 3936impl BufferLspData {
 3937    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3938        Self {
 3939            buffer_version: buffer.read(cx).version(),
 3940            document_colors: None,
 3941            code_lens: None,
 3942            semantic_tokens: None,
 3943            folding_ranges: None,
 3944            document_symbols: None,
 3945            inlay_hints: BufferInlayHints::new(buffer, cx),
 3946            lsp_requests: HashMap::default(),
 3947            chunk_lsp_requests: HashMap::default(),
 3948        }
 3949    }
 3950
 3951    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3952        if let Some(document_colors) = &mut self.document_colors {
 3953            document_colors.remove_server_data(for_server);
 3954        }
 3955
 3956        if let Some(code_lens) = &mut self.code_lens {
 3957            code_lens.remove_server_data(for_server);
 3958        }
 3959
 3960        self.inlay_hints.remove_server_data(for_server);
 3961
 3962        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3963            semantic_tokens.raw_tokens.servers.remove(&for_server);
 3964            semantic_tokens
 3965                .latest_invalidation_requests
 3966                .remove(&for_server);
 3967        }
 3968
 3969        if let Some(folding_ranges) = &mut self.folding_ranges {
 3970            folding_ranges.ranges.remove(&for_server);
 3971        }
 3972
 3973        if let Some(document_symbols) = &mut self.document_symbols {
 3974            document_symbols.remove_server_data(for_server);
 3975        }
 3976    }
 3977
 3978    #[cfg(any(test, feature = "test-support"))]
 3979    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3980        &self.inlay_hints
 3981    }
 3982}
 3983
 3984#[derive(Debug)]
 3985pub enum LspStoreEvent {
 3986    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3987    LanguageServerRemoved(LanguageServerId),
 3988    LanguageServerUpdate {
 3989        language_server_id: LanguageServerId,
 3990        name: Option<LanguageServerName>,
 3991        message: proto::update_language_server::Variant,
 3992    },
 3993    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3994    LanguageServerPrompt(LanguageServerPromptRequest),
 3995    LanguageDetected {
 3996        buffer: Entity<Buffer>,
 3997        new_language: Option<Arc<Language>>,
 3998    },
 3999    Notification(String),
 4000    RefreshInlayHints {
 4001        server_id: LanguageServerId,
 4002        request_id: Option<usize>,
 4003    },
 4004    RefreshSemanticTokens {
 4005        server_id: LanguageServerId,
 4006        request_id: Option<usize>,
 4007    },
 4008    RefreshCodeLens,
 4009    DiagnosticsUpdated {
 4010        server_id: LanguageServerId,
 4011        paths: Vec<ProjectPath>,
 4012    },
 4013    DiskBasedDiagnosticsStarted {
 4014        language_server_id: LanguageServerId,
 4015    },
 4016    DiskBasedDiagnosticsFinished {
 4017        language_server_id: LanguageServerId,
 4018    },
 4019    SnippetEdit {
 4020        buffer_id: BufferId,
 4021        edits: Vec<(lsp::Range, Snippet)>,
 4022        most_recent_edit: clock::Lamport,
 4023    },
 4024    WorkspaceEditApplied(ProjectTransaction),
 4025}
 4026
 4027#[derive(Clone, Debug, Serialize)]
 4028pub struct LanguageServerStatus {
 4029    pub name: LanguageServerName,
 4030    pub server_version: Option<SharedString>,
 4031    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4032    pub has_pending_diagnostic_updates: bool,
 4033    pub progress_tokens: HashSet<ProgressToken>,
 4034    pub worktree: Option<WorktreeId>,
 4035    pub binary: Option<LanguageServerBinary>,
 4036    pub configuration: Option<Value>,
 4037    pub workspace_folders: BTreeSet<Uri>,
 4038    pub process_id: Option<u32>,
 4039}
 4040
 4041#[derive(Clone, Debug)]
 4042struct CoreSymbol {
 4043    pub language_server_name: LanguageServerName,
 4044    pub source_worktree_id: WorktreeId,
 4045    pub source_language_server_id: LanguageServerId,
 4046    pub path: SymbolLocation,
 4047    pub name: String,
 4048    pub kind: lsp::SymbolKind,
 4049    pub range: Range<Unclipped<PointUtf16>>,
 4050    pub container_name: Option<String>,
 4051}
 4052
 4053#[derive(Clone, Debug, PartialEq, Eq)]
 4054pub enum SymbolLocation {
 4055    InProject(ProjectPath),
 4056    OutsideProject {
 4057        abs_path: Arc<Path>,
 4058        signature: [u8; 32],
 4059    },
 4060}
 4061
 4062impl SymbolLocation {
 4063    fn file_name(&self) -> Option<&str> {
 4064        match self {
 4065            Self::InProject(path) => path.path.file_name(),
 4066            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4067        }
 4068    }
 4069}
 4070
 4071impl LspStore {
 4072    pub fn init(client: &AnyProtoClient) {
 4073        client.add_entity_request_handler(Self::handle_lsp_query);
 4074        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4075        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4076        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4077        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4078        client.add_entity_message_handler(Self::handle_start_language_server);
 4079        client.add_entity_message_handler(Self::handle_update_language_server);
 4080        client.add_entity_message_handler(Self::handle_language_server_log);
 4081        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4082        client.add_entity_request_handler(Self::handle_format_buffers);
 4083        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4084        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4085        client.add_entity_request_handler(Self::handle_apply_code_action);
 4086        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4087        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4088        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4089        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4090        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4091        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4092        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4093        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4094        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4095        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4096        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4097        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4098        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4099        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4100        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4101        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4102        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4103        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4104
 4105        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4106        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4107        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4109        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4110        client.add_entity_request_handler(
 4111            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4112        );
 4113        client.add_entity_request_handler(
 4114            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4115        );
 4116        client.add_entity_request_handler(
 4117            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4118        );
 4119    }
 4120
 4121    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4122        match &self.mode {
 4123            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4124            _ => None,
 4125        }
 4126    }
 4127
 4128    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4129        match &self.mode {
 4130            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4131            _ => None,
 4132        }
 4133    }
 4134
 4135    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4136        match &mut self.mode {
 4137            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4138            _ => None,
 4139        }
 4140    }
 4141
 4142    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4143        match &self.mode {
 4144            LspStoreMode::Remote(RemoteLspStore {
 4145                upstream_client: Some(upstream_client),
 4146                upstream_project_id,
 4147                ..
 4148            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4149
 4150            LspStoreMode::Remote(RemoteLspStore {
 4151                upstream_client: None,
 4152                ..
 4153            }) => None,
 4154            LspStoreMode::Local(_) => None,
 4155        }
 4156    }
 4157
 4158    pub fn new_local(
 4159        buffer_store: Entity<BufferStore>,
 4160        worktree_store: Entity<WorktreeStore>,
 4161        prettier_store: Entity<PrettierStore>,
 4162        toolchain_store: Entity<LocalToolchainStore>,
 4163        environment: Entity<ProjectEnvironment>,
 4164        manifest_tree: Entity<ManifestTree>,
 4165        languages: Arc<LanguageRegistry>,
 4166        http_client: Arc<dyn HttpClient>,
 4167        fs: Arc<dyn Fs>,
 4168        cx: &mut Context<Self>,
 4169    ) -> Self {
 4170        let yarn = YarnPathStore::new(fs.clone(), cx);
 4171        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4172            .detach();
 4173        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4174            .detach();
 4175        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4176            .detach();
 4177        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4178            .detach();
 4179        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4180            .detach();
 4181        subscribe_to_binary_statuses(&languages, cx).detach();
 4182
 4183        let _maintain_workspace_config = {
 4184            let (sender, receiver) = watch::channel();
 4185            (Self::maintain_workspace_config(receiver, cx), sender)
 4186        };
 4187
 4188        Self {
 4189            mode: LspStoreMode::Local(LocalLspStore {
 4190                weak: cx.weak_entity(),
 4191                worktree_store: worktree_store.clone(),
 4192
 4193                supplementary_language_servers: Default::default(),
 4194                languages: languages.clone(),
 4195                language_server_ids: Default::default(),
 4196                language_servers: Default::default(),
 4197                last_workspace_edits_by_language_server: Default::default(),
 4198                language_server_watched_paths: Default::default(),
 4199                language_server_paths_watched_for_rename: Default::default(),
 4200                language_server_dynamic_registrations: Default::default(),
 4201                buffers_being_formatted: Default::default(),
 4202                buffers_to_refresh_hash_set: HashSet::default(),
 4203                buffers_to_refresh_queue: VecDeque::new(),
 4204                _background_diagnostics_worker: Task::ready(()).shared(),
 4205                buffer_snapshots: Default::default(),
 4206                prettier_store,
 4207                environment,
 4208                http_client,
 4209                fs,
 4210                yarn,
 4211                next_diagnostic_group_id: Default::default(),
 4212                diagnostics: Default::default(),
 4213                _subscription: cx.on_app_quit(|this, _| {
 4214                    this.as_local_mut()
 4215                        .unwrap()
 4216                        .shutdown_language_servers_on_quit()
 4217                }),
 4218                lsp_tree: LanguageServerTree::new(
 4219                    manifest_tree,
 4220                    languages.clone(),
 4221                    toolchain_store.clone(),
 4222                ),
 4223                toolchain_store,
 4224                registered_buffers: HashMap::default(),
 4225                buffers_opened_in_servers: HashMap::default(),
 4226                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4227                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4228                restricted_worktrees_tasks: HashMap::default(),
 4229                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4230                    .manifest_file_names(),
 4231            }),
 4232            last_formatting_failure: None,
 4233            downstream_client: None,
 4234            buffer_store,
 4235            worktree_store,
 4236            languages: languages.clone(),
 4237            language_server_statuses: Default::default(),
 4238            nonce: StdRng::from_os_rng().random(),
 4239            diagnostic_summaries: HashMap::default(),
 4240            lsp_server_capabilities: HashMap::default(),
 4241            semantic_token_config: SemanticTokenConfig::new(cx),
 4242            lsp_data: HashMap::default(),
 4243            next_hint_id: Arc::default(),
 4244            active_entry: None,
 4245            _maintain_workspace_config,
 4246            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4247        }
 4248    }
 4249
 4250    fn send_lsp_proto_request<R: LspCommand>(
 4251        &self,
 4252        buffer: Entity<Buffer>,
 4253        client: AnyProtoClient,
 4254        upstream_project_id: u64,
 4255        request: R,
 4256        cx: &mut Context<LspStore>,
 4257    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4258        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4259            return Task::ready(Ok(R::Response::default()));
 4260        }
 4261        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4262        cx.spawn(async move |this, cx| {
 4263            let response = client.request(message).await?;
 4264            let this = this.upgrade().context("project dropped")?;
 4265            request
 4266                .response_from_proto(response, this, buffer, cx.clone())
 4267                .await
 4268        })
 4269    }
 4270
 4271    pub(super) fn new_remote(
 4272        buffer_store: Entity<BufferStore>,
 4273        worktree_store: Entity<WorktreeStore>,
 4274        languages: Arc<LanguageRegistry>,
 4275        upstream_client: AnyProtoClient,
 4276        project_id: u64,
 4277        cx: &mut Context<Self>,
 4278    ) -> Self {
 4279        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4280            .detach();
 4281        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4282            .detach();
 4283        subscribe_to_binary_statuses(&languages, cx).detach();
 4284        let _maintain_workspace_config = {
 4285            let (sender, receiver) = watch::channel();
 4286            (Self::maintain_workspace_config(receiver, cx), sender)
 4287        };
 4288        Self {
 4289            mode: LspStoreMode::Remote(RemoteLspStore {
 4290                upstream_client: Some(upstream_client),
 4291                upstream_project_id: project_id,
 4292            }),
 4293            downstream_client: None,
 4294            last_formatting_failure: None,
 4295            buffer_store,
 4296            worktree_store,
 4297            languages: languages.clone(),
 4298            language_server_statuses: Default::default(),
 4299            nonce: StdRng::from_os_rng().random(),
 4300            diagnostic_summaries: HashMap::default(),
 4301            lsp_server_capabilities: HashMap::default(),
 4302            semantic_token_config: SemanticTokenConfig::new(cx),
 4303            next_hint_id: Arc::default(),
 4304            lsp_data: HashMap::default(),
 4305            active_entry: None,
 4306
 4307            _maintain_workspace_config,
 4308            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4309        }
 4310    }
 4311
 4312    fn on_buffer_store_event(
 4313        &mut self,
 4314        _: Entity<BufferStore>,
 4315        event: &BufferStoreEvent,
 4316        cx: &mut Context<Self>,
 4317    ) {
 4318        match event {
 4319            BufferStoreEvent::BufferAdded(buffer) => {
 4320                self.on_buffer_added(buffer, cx).log_err();
 4321            }
 4322            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4323                let buffer_id = buffer.read(cx).remote_id();
 4324                if let Some(local) = self.as_local_mut()
 4325                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4326                {
 4327                    local.reset_buffer(buffer, old_file, cx);
 4328
 4329                    if local.registered_buffers.contains_key(&buffer_id) {
 4330                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4331                    }
 4332                }
 4333
 4334                self.detect_language_for_buffer(buffer, cx);
 4335                if let Some(local) = self.as_local_mut() {
 4336                    local.initialize_buffer(buffer, cx);
 4337                    if local.registered_buffers.contains_key(&buffer_id) {
 4338                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4339                    }
 4340                }
 4341            }
 4342            _ => {}
 4343        }
 4344    }
 4345
 4346    fn on_worktree_store_event(
 4347        &mut self,
 4348        _: Entity<WorktreeStore>,
 4349        event: &WorktreeStoreEvent,
 4350        cx: &mut Context<Self>,
 4351    ) {
 4352        match event {
 4353            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4354                if !worktree.read(cx).is_local() {
 4355                    return;
 4356                }
 4357                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4358                    worktree::Event::UpdatedEntries(changes) => {
 4359                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4360                    }
 4361                    worktree::Event::UpdatedGitRepositories(_)
 4362                    | worktree::Event::DeletedEntry(_) => {}
 4363                })
 4364                .detach()
 4365            }
 4366            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4367            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4368                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4369            }
 4370            WorktreeStoreEvent::WorktreeReleased(..)
 4371            | WorktreeStoreEvent::WorktreeOrderChanged
 4372            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4373            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4374            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4375        }
 4376    }
 4377
 4378    fn on_prettier_store_event(
 4379        &mut self,
 4380        _: Entity<PrettierStore>,
 4381        event: &PrettierStoreEvent,
 4382        cx: &mut Context<Self>,
 4383    ) {
 4384        match event {
 4385            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4386                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4387            }
 4388            PrettierStoreEvent::LanguageServerAdded {
 4389                new_server_id,
 4390                name,
 4391                prettier_server,
 4392            } => {
 4393                self.register_supplementary_language_server(
 4394                    *new_server_id,
 4395                    name.clone(),
 4396                    prettier_server.clone(),
 4397                    cx,
 4398                );
 4399            }
 4400        }
 4401    }
 4402
 4403    fn on_toolchain_store_event(
 4404        &mut self,
 4405        _: Entity<LocalToolchainStore>,
 4406        event: &ToolchainStoreEvent,
 4407        _: &mut Context<Self>,
 4408    ) {
 4409        if let ToolchainStoreEvent::ToolchainActivated = event {
 4410            self.request_workspace_config_refresh()
 4411        }
 4412    }
 4413
 4414    fn request_workspace_config_refresh(&mut self) {
 4415        *self._maintain_workspace_config.1.borrow_mut() = ();
 4416    }
 4417
 4418    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4419        self.as_local().map(|local| local.prettier_store.clone())
 4420    }
 4421
 4422    fn on_buffer_event(
 4423        &mut self,
 4424        buffer: Entity<Buffer>,
 4425        event: &language::BufferEvent,
 4426        cx: &mut Context<Self>,
 4427    ) {
 4428        match event {
 4429            language::BufferEvent::Edited { .. } => {
 4430                self.on_buffer_edited(buffer, cx);
 4431            }
 4432
 4433            language::BufferEvent::Saved => {
 4434                self.on_buffer_saved(buffer, cx);
 4435            }
 4436
 4437            language::BufferEvent::Reloaded => {
 4438                self.on_buffer_reloaded(buffer, cx);
 4439            }
 4440
 4441            _ => {}
 4442        }
 4443    }
 4444
 4445    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4446        buffer
 4447            .read(cx)
 4448            .set_language_registry(self.languages.clone());
 4449
 4450        cx.subscribe(buffer, |this, buffer, event, cx| {
 4451            this.on_buffer_event(buffer, event, cx);
 4452        })
 4453        .detach();
 4454
 4455        self.parse_modeline(buffer, cx);
 4456        self.detect_language_for_buffer(buffer, cx);
 4457        if let Some(local) = self.as_local_mut() {
 4458            local.initialize_buffer(buffer, cx);
 4459        }
 4460
 4461        Ok(())
 4462    }
 4463
 4464    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4465        if self.parse_modeline(&buffer, cx) {
 4466            self.detect_language_for_buffer(&buffer, cx);
 4467        }
 4468    }
 4469
 4470    pub fn refresh_background_diagnostics_for_buffers(
 4471        &mut self,
 4472        buffers: HashSet<BufferId>,
 4473        cx: &mut Context<Self>,
 4474    ) -> Shared<Task<()>> {
 4475        let Some(local) = self.as_local_mut() else {
 4476            return Task::ready(()).shared();
 4477        };
 4478        for buffer in buffers {
 4479            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4480                local.buffers_to_refresh_queue.push_back(buffer);
 4481                if local.buffers_to_refresh_queue.len() == 1 {
 4482                    local._background_diagnostics_worker =
 4483                        Self::background_diagnostics_worker(cx).shared();
 4484                }
 4485            }
 4486        }
 4487
 4488        local._background_diagnostics_worker.clone()
 4489    }
 4490
 4491    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4492        let buffer_store = self.buffer_store.clone();
 4493        let local = self.as_local_mut()?;
 4494        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4495            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4496            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4497                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4498            }
 4499        }
 4500        None
 4501    }
 4502
 4503    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4504        cx.spawn(async move |this, cx| {
 4505            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4506                task.await.log_err();
 4507            }
 4508        })
 4509    }
 4510    pub(crate) fn register_buffer_with_language_servers(
 4511        &mut self,
 4512        buffer: &Entity<Buffer>,
 4513        only_register_servers: HashSet<LanguageServerSelector>,
 4514        ignore_refcounts: bool,
 4515        cx: &mut Context<Self>,
 4516    ) -> OpenLspBufferHandle {
 4517        let buffer_id = buffer.read(cx).remote_id();
 4518        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4519        if let Some(local) = self.as_local_mut() {
 4520            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4521            if !ignore_refcounts {
 4522                *refcount += 1;
 4523            }
 4524
 4525            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4526            // 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
 4527            // 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
 4528            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4529            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4530                return handle;
 4531            };
 4532            if !file.is_local() {
 4533                return handle;
 4534            }
 4535
 4536            if ignore_refcounts || *refcount == 1 {
 4537                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4538            }
 4539            if !ignore_refcounts {
 4540                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4541                    let refcount = {
 4542                        let local = lsp_store.as_local_mut().unwrap();
 4543                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4544                            debug_panic!("bad refcounting");
 4545                            return;
 4546                        };
 4547
 4548                        *refcount -= 1;
 4549                        *refcount
 4550                    };
 4551                    if refcount == 0 {
 4552                        lsp_store.lsp_data.remove(&buffer_id);
 4553                        let local = lsp_store.as_local_mut().unwrap();
 4554                        local.registered_buffers.remove(&buffer_id);
 4555
 4556                        local.buffers_opened_in_servers.remove(&buffer_id);
 4557                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4558                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4559
 4560                            let buffer_abs_path = file.abs_path(cx);
 4561                            for (_, buffer_pull_diagnostics_result_ids) in
 4562                                &mut local.buffer_pull_diagnostics_result_ids
 4563                            {
 4564                                buffer_pull_diagnostics_result_ids.retain(
 4565                                    |_, buffer_result_ids| {
 4566                                        buffer_result_ids.remove(&buffer_abs_path);
 4567                                        !buffer_result_ids.is_empty()
 4568                                    },
 4569                                );
 4570                            }
 4571
 4572                            let diagnostic_updates = local
 4573                                .language_servers
 4574                                .keys()
 4575                                .cloned()
 4576                                .map(|server_id| DocumentDiagnosticsUpdate {
 4577                                    diagnostics: DocumentDiagnostics {
 4578                                        document_abs_path: buffer_abs_path.clone(),
 4579                                        version: None,
 4580                                        diagnostics: Vec::new(),
 4581                                    },
 4582                                    result_id: None,
 4583                                    registration_id: None,
 4584                                    server_id,
 4585                                    disk_based_sources: Cow::Borrowed(&[]),
 4586                                })
 4587                                .collect::<Vec<_>>();
 4588
 4589                            lsp_store
 4590                                .merge_diagnostic_entries(
 4591                                    diagnostic_updates,
 4592                                    |_, diagnostic, _| {
 4593                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4594                                    },
 4595                                    cx,
 4596                                )
 4597                                .context("Clearing diagnostics for the closed buffer")
 4598                                .log_err();
 4599                        }
 4600                    }
 4601                })
 4602                .detach();
 4603            }
 4604        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4605            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4606            cx.background_spawn(async move {
 4607                upstream_client
 4608                    .request(proto::RegisterBufferWithLanguageServers {
 4609                        project_id: upstream_project_id,
 4610                        buffer_id,
 4611                        only_servers: only_register_servers
 4612                            .into_iter()
 4613                            .map(|selector| {
 4614                                let selector = match selector {
 4615                                    LanguageServerSelector::Id(language_server_id) => {
 4616                                        proto::language_server_selector::Selector::ServerId(
 4617                                            language_server_id.to_proto(),
 4618                                        )
 4619                                    }
 4620                                    LanguageServerSelector::Name(language_server_name) => {
 4621                                        proto::language_server_selector::Selector::Name(
 4622                                            language_server_name.to_string(),
 4623                                        )
 4624                                    }
 4625                                };
 4626                                proto::LanguageServerSelector {
 4627                                    selector: Some(selector),
 4628                                }
 4629                            })
 4630                            .collect(),
 4631                    })
 4632                    .await
 4633            })
 4634            .detach();
 4635        } else {
 4636            // Our remote connection got closed
 4637        }
 4638        handle
 4639    }
 4640
 4641    fn maintain_buffer_languages(
 4642        languages: Arc<LanguageRegistry>,
 4643        cx: &mut Context<Self>,
 4644    ) -> Task<()> {
 4645        let mut subscription = languages.subscribe();
 4646        let mut prev_reload_count = languages.reload_count();
 4647        cx.spawn(async move |this, cx| {
 4648            while let Some(()) = subscription.next().await {
 4649                if let Some(this) = this.upgrade() {
 4650                    // If the language registry has been reloaded, then remove and
 4651                    // re-assign the languages on all open buffers.
 4652                    let reload_count = languages.reload_count();
 4653                    if reload_count > prev_reload_count {
 4654                        prev_reload_count = reload_count;
 4655                        this.update(cx, |this, cx| {
 4656                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4657                                for buffer in buffer_store.buffers() {
 4658                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4659                                    {
 4660                                        buffer.update(cx, |buffer, cx| {
 4661                                            buffer.set_language_async(None, cx)
 4662                                        });
 4663                                        if let Some(local) = this.as_local_mut() {
 4664                                            local.reset_buffer(&buffer, &f, cx);
 4665
 4666                                            if local
 4667                                                .registered_buffers
 4668                                                .contains_key(&buffer.read(cx).remote_id())
 4669                                                && let Some(file_url) =
 4670                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4671                                            {
 4672                                                local.unregister_buffer_from_language_servers(
 4673                                                    &buffer, &file_url, cx,
 4674                                                );
 4675                                            }
 4676                                        }
 4677                                    }
 4678                                }
 4679                            });
 4680                        });
 4681                    }
 4682
 4683                    this.update(cx, |this, cx| {
 4684                        let mut plain_text_buffers = Vec::new();
 4685                        let mut buffers_with_unknown_injections = Vec::new();
 4686                        for handle in this.buffer_store.read(cx).buffers() {
 4687                            let buffer = handle.read(cx);
 4688                            if buffer.language().is_none()
 4689                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4690                            {
 4691                                plain_text_buffers.push(handle);
 4692                            } else if buffer.contains_unknown_injections() {
 4693                                buffers_with_unknown_injections.push(handle);
 4694                            }
 4695                        }
 4696
 4697                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4698                        // and reused later in the invisible worktrees.
 4699                        plain_text_buffers.sort_by_key(|buffer| {
 4700                            Reverse(
 4701                                File::from_dyn(buffer.read(cx).file())
 4702                                    .map(|file| file.worktree.read(cx).is_visible()),
 4703                            )
 4704                        });
 4705
 4706                        for buffer in plain_text_buffers {
 4707                            this.detect_language_for_buffer(&buffer, cx);
 4708                            if let Some(local) = this.as_local_mut() {
 4709                                local.initialize_buffer(&buffer, cx);
 4710                                if local
 4711                                    .registered_buffers
 4712                                    .contains_key(&buffer.read(cx).remote_id())
 4713                                {
 4714                                    local.register_buffer_with_language_servers(
 4715                                        &buffer,
 4716                                        HashSet::default(),
 4717                                        cx,
 4718                                    );
 4719                                }
 4720                            }
 4721                        }
 4722
 4723                        for buffer in buffers_with_unknown_injections {
 4724                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4725                        }
 4726                    });
 4727                }
 4728            }
 4729        })
 4730    }
 4731
 4732    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4733        let buffer = buffer_handle.read(cx);
 4734        let content = buffer.as_rope();
 4735
 4736        let modeline_settings = {
 4737            let settings_store = cx.global::<SettingsStore>();
 4738            let modeline_lines = settings_store
 4739                .raw_user_settings()
 4740                .and_then(|s| s.content.modeline_lines)
 4741                .or(settings_store.raw_default_settings().modeline_lines)
 4742                .unwrap_or(5);
 4743
 4744            const MAX_MODELINE_BYTES: usize = 1024;
 4745
 4746            let first_bytes = content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4747            let mut first_lines = Vec::new();
 4748            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4749            for _ in 0..modeline_lines {
 4750                if let Some(line) = lines.next() {
 4751                    first_lines.push(line.to_string());
 4752                } else {
 4753                    break;
 4754                }
 4755            }
 4756            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4757
 4758            let last_start = content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4759            let mut last_lines = Vec::new();
 4760            let mut lines = content
 4761                .reversed_chunks_in_range(last_start..content.len())
 4762                .lines();
 4763            for _ in 0..modeline_lines {
 4764                if let Some(line) = lines.next() {
 4765                    last_lines.push(line.to_string());
 4766                } else {
 4767                    break;
 4768                }
 4769            }
 4770            let last_lines_ref: Vec<_> =
 4771                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4772            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4773        };
 4774
 4775        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4776
 4777        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4778    }
 4779
 4780    fn detect_language_for_buffer(
 4781        &mut self,
 4782        buffer_handle: &Entity<Buffer>,
 4783        cx: &mut Context<Self>,
 4784    ) -> Option<language::AvailableLanguage> {
 4785        // If the buffer has a language, set it and start the language server if we haven't already.
 4786        let buffer = buffer_handle.read(cx);
 4787        let file = buffer.file()?;
 4788        let content = buffer.as_rope();
 4789        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4790
 4791        let available_language = if let Some(ModelineSettings {
 4792            mode: Some(mode_name),
 4793            ..
 4794        }) = modeline_settings
 4795        {
 4796            self.languages
 4797                .available_language_for_modeline_name(mode_name)
 4798        } else {
 4799            self.languages.language_for_file(file, Some(content), cx)
 4800        };
 4801        if let Some(available_language) = &available_language {
 4802            if let Some(Ok(Ok(new_language))) = self
 4803                .languages
 4804                .load_language(available_language)
 4805                .now_or_never()
 4806            {
 4807                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4808            }
 4809        } else {
 4810            cx.emit(LspStoreEvent::LanguageDetected {
 4811                buffer: buffer_handle.clone(),
 4812                new_language: None,
 4813            });
 4814        }
 4815
 4816        available_language
 4817    }
 4818
 4819    pub(crate) fn set_language_for_buffer(
 4820        &mut self,
 4821        buffer_entity: &Entity<Buffer>,
 4822        new_language: Arc<Language>,
 4823        cx: &mut Context<Self>,
 4824    ) {
 4825        let buffer = buffer_entity.read(cx);
 4826        let buffer_file = buffer.file().cloned();
 4827        let buffer_id = buffer.remote_id();
 4828        if let Some(local_store) = self.as_local_mut()
 4829            && local_store.registered_buffers.contains_key(&buffer_id)
 4830            && let Some(abs_path) =
 4831                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4832            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4833        {
 4834            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4835        }
 4836        buffer_entity.update(cx, |buffer, cx| {
 4837            if buffer
 4838                .language()
 4839                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4840            {
 4841                buffer.set_language_async(Some(new_language.clone()), cx);
 4842            }
 4843        });
 4844
 4845        let settings = LanguageSettings::resolve(
 4846            Some(&buffer_entity.read(cx)),
 4847            Some(&new_language.name()),
 4848            cx,
 4849        )
 4850        .into_owned();
 4851        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4852
 4853        let worktree_id = if let Some(file) = buffer_file {
 4854            let worktree = file.worktree.clone();
 4855
 4856            if let Some(local) = self.as_local_mut()
 4857                && local.registered_buffers.contains_key(&buffer_id)
 4858            {
 4859                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4860            }
 4861            Some(worktree.read(cx).id())
 4862        } else {
 4863            None
 4864        };
 4865
 4866        if settings.prettier.allowed
 4867            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4868        {
 4869            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4870            if let Some(prettier_store) = prettier_store {
 4871                prettier_store.update(cx, |prettier_store, cx| {
 4872                    prettier_store.install_default_prettier(
 4873                        worktree_id,
 4874                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4875                        cx,
 4876                    )
 4877                })
 4878            }
 4879        }
 4880
 4881        cx.emit(LspStoreEvent::LanguageDetected {
 4882            buffer: buffer_entity.clone(),
 4883            new_language: Some(new_language),
 4884        })
 4885    }
 4886
 4887    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4888        self.buffer_store.clone()
 4889    }
 4890
 4891    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4892        self.active_entry = active_entry;
 4893    }
 4894
 4895    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4896        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4897            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4898        {
 4899            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4900                summaries
 4901                    .iter()
 4902                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4903            });
 4904            if let Some(summary) = summaries.next() {
 4905                client
 4906                    .send(proto::UpdateDiagnosticSummary {
 4907                        project_id: downstream_project_id,
 4908                        worktree_id: worktree.id().to_proto(),
 4909                        summary: Some(summary),
 4910                        more_summaries: summaries.collect(),
 4911                    })
 4912                    .log_err();
 4913            }
 4914        }
 4915    }
 4916
 4917    fn is_capable_for_proto_request<R>(
 4918        &self,
 4919        buffer: &Entity<Buffer>,
 4920        request: &R,
 4921        cx: &App,
 4922    ) -> bool
 4923    where
 4924        R: LspCommand,
 4925    {
 4926        self.check_if_capable_for_proto_request(
 4927            buffer,
 4928            |capabilities| {
 4929                request.check_capabilities(AdapterServerCapabilities {
 4930                    server_capabilities: capabilities.clone(),
 4931                    code_action_kinds: None,
 4932                })
 4933            },
 4934            cx,
 4935        )
 4936    }
 4937
 4938    fn check_if_capable_for_proto_request<F>(
 4939        &self,
 4940        buffer: &Entity<Buffer>,
 4941        check: F,
 4942        cx: &App,
 4943    ) -> bool
 4944    where
 4945        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4946    {
 4947        let Some(language) = buffer.read(cx).language().cloned() else {
 4948            return false;
 4949        };
 4950        let registered_language_servers = self
 4951            .languages
 4952            .lsp_adapters(&language.name())
 4953            .into_iter()
 4954            .map(|lsp_adapter| lsp_adapter.name())
 4955            .collect::<HashSet<_>>();
 4956        self.language_server_statuses
 4957            .iter()
 4958            .filter_map(|(server_id, server_status)| {
 4959                // Include servers that are either registered for this language OR
 4960                // available to be loaded (for SSH remote mode where adapters like
 4961                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4962                // but only loaded on the server side)
 4963                let is_relevant = registered_language_servers.contains(&server_status.name)
 4964                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4965                is_relevant.then_some(server_id)
 4966            })
 4967            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4968            .any(check)
 4969    }
 4970
 4971    fn all_capable_for_proto_request<F>(
 4972        &self,
 4973        buffer: &Entity<Buffer>,
 4974        mut check: F,
 4975        cx: &App,
 4976    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4977    where
 4978        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4979    {
 4980        let Some(language) = buffer.read(cx).language().cloned() else {
 4981            return Vec::default();
 4982        };
 4983        let registered_language_servers = self
 4984            .languages
 4985            .lsp_adapters(&language.name())
 4986            .into_iter()
 4987            .map(|lsp_adapter| lsp_adapter.name())
 4988            .collect::<HashSet<_>>();
 4989        self.language_server_statuses
 4990            .iter()
 4991            .filter_map(|(server_id, server_status)| {
 4992                // Include servers that are either registered for this language OR
 4993                // available to be loaded (for SSH remote mode where adapters like
 4994                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4995                // but only loaded on the server side)
 4996                let is_relevant = registered_language_servers.contains(&server_status.name)
 4997                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4998                is_relevant.then_some((server_id, &server_status.name))
 4999            })
 5000            .filter_map(|(server_id, server_name)| {
 5001                self.lsp_server_capabilities
 5002                    .get(server_id)
 5003                    .map(|c| (server_id, server_name, c))
 5004            })
 5005            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5006            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5007            .collect()
 5008    }
 5009
 5010    pub fn request_lsp<R>(
 5011        &mut self,
 5012        buffer: Entity<Buffer>,
 5013        server: LanguageServerToQuery,
 5014        request: R,
 5015        cx: &mut Context<Self>,
 5016    ) -> Task<Result<R::Response>>
 5017    where
 5018        R: LspCommand,
 5019        <R::LspRequest as lsp::request::Request>::Result: Send,
 5020        <R::LspRequest as lsp::request::Request>::Params: Send,
 5021    {
 5022        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5023            return self.send_lsp_proto_request(
 5024                buffer,
 5025                upstream_client,
 5026                upstream_project_id,
 5027                request,
 5028                cx,
 5029            );
 5030        }
 5031
 5032        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5033            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5034                local
 5035                    .language_servers_for_buffer(buffer, cx)
 5036                    .find(|(_, server)| {
 5037                        request.check_capabilities(server.adapter_server_capabilities())
 5038                    })
 5039                    .map(|(_, server)| server.clone())
 5040            }),
 5041            LanguageServerToQuery::Other(id) => self
 5042                .language_server_for_local_buffer(buffer, id, cx)
 5043                .and_then(|(_, server)| {
 5044                    request
 5045                        .check_capabilities(server.adapter_server_capabilities())
 5046                        .then(|| Arc::clone(server))
 5047                }),
 5048        }) else {
 5049            return Task::ready(Ok(Default::default()));
 5050        };
 5051
 5052        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5053
 5054        let Some(file) = file else {
 5055            return Task::ready(Ok(Default::default()));
 5056        };
 5057
 5058        let lsp_params = match request.to_lsp_params_or_response(
 5059            &file.abs_path(cx),
 5060            buffer.read(cx),
 5061            &language_server,
 5062            cx,
 5063        ) {
 5064            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5065            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5066            Err(err) => {
 5067                let message = format!(
 5068                    "{} via {} failed: {}",
 5069                    request.display_name(),
 5070                    language_server.name(),
 5071                    err
 5072                );
 5073                // rust-analyzer likes to error with this when its still loading up
 5074                if !message.ends_with("content modified") {
 5075                    log::warn!("{message}");
 5076                }
 5077                return Task::ready(Err(anyhow!(message)));
 5078            }
 5079        };
 5080
 5081        let status = request.status();
 5082        let request_timeout = ProjectSettings::get_global(cx)
 5083            .global_lsp_settings
 5084            .get_request_timeout();
 5085
 5086        cx.spawn(async move |this, cx| {
 5087            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5088
 5089            let id = lsp_request.id();
 5090            let _cleanup = if status.is_some() {
 5091                cx.update(|cx| {
 5092                    this.update(cx, |this, cx| {
 5093                        this.on_lsp_work_start(
 5094                            language_server.server_id(),
 5095                            ProgressToken::Number(id),
 5096                            LanguageServerProgress {
 5097                                is_disk_based_diagnostics_progress: false,
 5098                                is_cancellable: false,
 5099                                title: None,
 5100                                message: status.clone(),
 5101                                percentage: None,
 5102                                last_update_at: cx.background_executor().now(),
 5103                            },
 5104                            cx,
 5105                        );
 5106                    })
 5107                })
 5108                .log_err();
 5109
 5110                Some(defer(|| {
 5111                    cx.update(|cx| {
 5112                        this.update(cx, |this, cx| {
 5113                            this.on_lsp_work_end(
 5114                                language_server.server_id(),
 5115                                ProgressToken::Number(id),
 5116                                cx,
 5117                            );
 5118                        })
 5119                    })
 5120                    .log_err();
 5121                }))
 5122            } else {
 5123                None
 5124            };
 5125
 5126            let result = lsp_request.await.into_response();
 5127
 5128            let response = result.map_err(|err| {
 5129                let message = format!(
 5130                    "{} via {} failed: {}",
 5131                    request.display_name(),
 5132                    language_server.name(),
 5133                    err
 5134                );
 5135                // rust-analyzer likes to error with this when its still loading up
 5136                if !message.ends_with("content modified") {
 5137                    log::warn!("{message}");
 5138                }
 5139                anyhow::anyhow!(message)
 5140            })?;
 5141
 5142            request
 5143                .response_from_lsp(
 5144                    response,
 5145                    this.upgrade().context("no app context")?,
 5146                    buffer,
 5147                    language_server.server_id(),
 5148                    cx.clone(),
 5149                )
 5150                .await
 5151        })
 5152    }
 5153
 5154    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5155        let mut language_formatters_to_check = Vec::new();
 5156        for buffer in self.buffer_store.read(cx).buffers() {
 5157            let buffer = buffer.read(cx);
 5158            let settings = LanguageSettings::for_buffer(buffer, cx);
 5159            if buffer.language().is_some() {
 5160                let buffer_file = File::from_dyn(buffer.file());
 5161                language_formatters_to_check.push((
 5162                    buffer_file.map(|f| f.worktree_id(cx)),
 5163                    settings.into_owned(),
 5164                ));
 5165            }
 5166        }
 5167
 5168        self.request_workspace_config_refresh();
 5169
 5170        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5171            prettier_store.update(cx, |prettier_store, cx| {
 5172                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5173            })
 5174        }
 5175
 5176        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5177            .global_lsp_settings
 5178            .semantic_token_rules
 5179            .clone();
 5180        self.semantic_token_config
 5181            .update_rules(new_semantic_token_rules);
 5182        // Always clear cached stylizers so that changes to language-specific
 5183        // semantic token rules (e.g. from extension install/uninstall) are
 5184        // picked up. Stylizers are recreated lazily, so this is cheap.
 5185        self.semantic_token_config.clear_stylizers();
 5186
 5187        let new_global_semantic_tokens_mode =
 5188            all_language_settings(None, cx).defaults.semantic_tokens;
 5189        if self
 5190            .semantic_token_config
 5191            .update_global_mode(new_global_semantic_tokens_mode)
 5192        {
 5193            self.restart_all_language_servers(cx);
 5194        }
 5195
 5196        cx.notify();
 5197    }
 5198
 5199    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5200        let buffer_store = self.buffer_store.clone();
 5201        let Some(local) = self.as_local_mut() else {
 5202            return;
 5203        };
 5204        let mut adapters = BTreeMap::default();
 5205        let get_adapter = {
 5206            let languages = local.languages.clone();
 5207            let environment = local.environment.clone();
 5208            let weak = local.weak.clone();
 5209            let worktree_store = local.worktree_store.clone();
 5210            let http_client = local.http_client.clone();
 5211            let fs = local.fs.clone();
 5212            move |worktree_id, cx: &mut App| {
 5213                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5214                Some(LocalLspAdapterDelegate::new(
 5215                    languages.clone(),
 5216                    &environment,
 5217                    weak.clone(),
 5218                    &worktree,
 5219                    http_client.clone(),
 5220                    fs.clone(),
 5221                    cx,
 5222                ))
 5223            }
 5224        };
 5225
 5226        let mut messages_to_report = Vec::new();
 5227        let (new_tree, to_stop) = {
 5228            let mut rebase = local.lsp_tree.rebase();
 5229            let buffers = buffer_store
 5230                .read(cx)
 5231                .buffers()
 5232                .filter_map(|buffer| {
 5233                    let raw_buffer = buffer.read(cx);
 5234                    if !local
 5235                        .registered_buffers
 5236                        .contains_key(&raw_buffer.remote_id())
 5237                    {
 5238                        return None;
 5239                    }
 5240                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5241                    let language = raw_buffer.language().cloned()?;
 5242                    Some((file, language, raw_buffer.remote_id()))
 5243                })
 5244                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5245            for (file, language, buffer_id) in buffers {
 5246                let worktree_id = file.worktree_id(cx);
 5247                let Some(worktree) = local
 5248                    .worktree_store
 5249                    .read(cx)
 5250                    .worktree_for_id(worktree_id, cx)
 5251                else {
 5252                    continue;
 5253                };
 5254
 5255                if let Some((_, apply)) = local.reuse_existing_language_server(
 5256                    rebase.server_tree(),
 5257                    &worktree,
 5258                    &language.name(),
 5259                    cx,
 5260                ) {
 5261                    (apply)(rebase.server_tree());
 5262                } else if let Some(lsp_delegate) = adapters
 5263                    .entry(worktree_id)
 5264                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5265                    .clone()
 5266                {
 5267                    let delegate =
 5268                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5269                    let path = file
 5270                        .path()
 5271                        .parent()
 5272                        .map(Arc::from)
 5273                        .unwrap_or_else(|| file.path().clone());
 5274                    let worktree_path = ProjectPath { worktree_id, path };
 5275                    let abs_path = file.abs_path(cx);
 5276                    let nodes = rebase
 5277                        .walk(
 5278                            worktree_path,
 5279                            language.name(),
 5280                            language.manifest(),
 5281                            delegate.clone(),
 5282                            cx,
 5283                        )
 5284                        .collect::<Vec<_>>();
 5285                    for node in nodes {
 5286                        let server_id = node.server_id_or_init(|disposition| {
 5287                            let path = &disposition.path;
 5288                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5289                            let key = LanguageServerSeed {
 5290                                worktree_id,
 5291                                name: disposition.server_name.clone(),
 5292                                settings: LanguageServerSeedSettings {
 5293                                    binary: disposition.settings.binary.clone(),
 5294                                    initialization_options: disposition
 5295                                        .settings
 5296                                        .initialization_options
 5297                                        .clone(),
 5298                                },
 5299                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5300                                    path.worktree_id,
 5301                                    &path.path,
 5302                                    language.name(),
 5303                                ),
 5304                            };
 5305                            local.language_server_ids.remove(&key);
 5306
 5307                            let server_id = local.get_or_insert_language_server(
 5308                                &worktree,
 5309                                lsp_delegate.clone(),
 5310                                disposition,
 5311                                &language.name(),
 5312                                cx,
 5313                            );
 5314                            if let Some(state) = local.language_servers.get(&server_id)
 5315                                && let Ok(uri) = uri
 5316                            {
 5317                                state.add_workspace_folder(uri);
 5318                            };
 5319                            server_id
 5320                        });
 5321
 5322                        if let Some(language_server_id) = server_id {
 5323                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5324                                language_server_id,
 5325                                name: node.name(),
 5326                                message:
 5327                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5328                                        proto::RegisteredForBuffer {
 5329                                            buffer_abs_path: abs_path
 5330                                                .to_string_lossy()
 5331                                                .into_owned(),
 5332                                            buffer_id: buffer_id.to_proto(),
 5333                                        },
 5334                                    ),
 5335                            });
 5336                        }
 5337                    }
 5338                } else {
 5339                    continue;
 5340                }
 5341            }
 5342            rebase.finish()
 5343        };
 5344        for message in messages_to_report {
 5345            cx.emit(message);
 5346        }
 5347        local.lsp_tree = new_tree;
 5348        for (id, _) in to_stop {
 5349            self.stop_local_language_server(id, cx).detach();
 5350        }
 5351    }
 5352
 5353    pub fn apply_code_action(
 5354        &self,
 5355        buffer_handle: Entity<Buffer>,
 5356        mut action: CodeAction,
 5357        push_to_history: bool,
 5358        cx: &mut Context<Self>,
 5359    ) -> Task<Result<ProjectTransaction>> {
 5360        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5361            let request = proto::ApplyCodeAction {
 5362                project_id,
 5363                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5364                action: Some(Self::serialize_code_action(&action)),
 5365            };
 5366            let buffer_store = self.buffer_store();
 5367            cx.spawn(async move |_, cx| {
 5368                let response = upstream_client
 5369                    .request(request)
 5370                    .await?
 5371                    .transaction
 5372                    .context("missing transaction")?;
 5373
 5374                buffer_store
 5375                    .update(cx, |buffer_store, cx| {
 5376                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5377                    })
 5378                    .await
 5379            })
 5380        } else if self.mode.is_local() {
 5381            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5382                let request_timeout = ProjectSettings::get_global(cx)
 5383                    .global_lsp_settings
 5384                    .get_request_timeout();
 5385                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5386                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5387            }) else {
 5388                return Task::ready(Ok(ProjectTransaction::default()));
 5389            };
 5390
 5391            cx.spawn(async move |this, cx| {
 5392                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5393                    .await
 5394                    .context("resolving a code action")?;
 5395                if let Some(edit) = action.lsp_action.edit()
 5396                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5397                        return LocalLspStore::deserialize_workspace_edit(
 5398                            this.upgrade().context("no app present")?,
 5399                            edit.clone(),
 5400                            push_to_history,
 5401
 5402                            lang_server.clone(),
 5403                            cx,
 5404                        )
 5405                        .await;
 5406                    }
 5407
 5408                let Some(command) = action.lsp_action.command() else {
 5409                    return Ok(ProjectTransaction::default())
 5410                };
 5411
 5412                let server_capabilities = lang_server.capabilities();
 5413                let available_commands = server_capabilities
 5414                    .execute_command_provider
 5415                    .as_ref()
 5416                    .map(|options| options.commands.as_slice())
 5417                    .unwrap_or_default();
 5418
 5419                if !available_commands.contains(&command.command) {
 5420                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5421                    return Ok(ProjectTransaction::default())
 5422                }
 5423
 5424                let request_timeout = cx.update(|app|
 5425                    ProjectSettings::get_global(app)
 5426                    .global_lsp_settings
 5427                    .get_request_timeout()
 5428                );
 5429
 5430                this.update(cx, |this, _| {
 5431                    this.as_local_mut()
 5432                        .unwrap()
 5433                        .last_workspace_edits_by_language_server
 5434                        .remove(&lang_server.server_id());
 5435                })?;
 5436
 5437                let _result = lang_server
 5438                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5439                        command: command.command.clone(),
 5440                        arguments: command.arguments.clone().unwrap_or_default(),
 5441                        ..lsp::ExecuteCommandParams::default()
 5442                    }, request_timeout)
 5443                    .await.into_response()
 5444                    .context("execute command")?;
 5445
 5446                return this.update(cx, |this, _| {
 5447                    this.as_local_mut()
 5448                        .unwrap()
 5449                        .last_workspace_edits_by_language_server
 5450                        .remove(&lang_server.server_id())
 5451                        .unwrap_or_default()
 5452                });
 5453            })
 5454        } else {
 5455            Task::ready(Err(anyhow!("no upstream client and not local")))
 5456        }
 5457    }
 5458
 5459    pub fn apply_code_action_kind(
 5460        &mut self,
 5461        buffers: HashSet<Entity<Buffer>>,
 5462        kind: CodeActionKind,
 5463        push_to_history: bool,
 5464        cx: &mut Context<Self>,
 5465    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5466        if self.as_local().is_some() {
 5467            cx.spawn(async move |lsp_store, cx| {
 5468                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5469                let result = LocalLspStore::execute_code_action_kind_locally(
 5470                    lsp_store.clone(),
 5471                    buffers,
 5472                    kind,
 5473                    push_to_history,
 5474                    cx,
 5475                )
 5476                .await;
 5477                lsp_store.update(cx, |lsp_store, _| {
 5478                    lsp_store.update_last_formatting_failure(&result);
 5479                })?;
 5480                result
 5481            })
 5482        } else if let Some((client, project_id)) = self.upstream_client() {
 5483            let buffer_store = self.buffer_store();
 5484            cx.spawn(async move |lsp_store, cx| {
 5485                let result = client
 5486                    .request(proto::ApplyCodeActionKind {
 5487                        project_id,
 5488                        kind: kind.as_str().to_owned(),
 5489                        buffer_ids: buffers
 5490                            .iter()
 5491                            .map(|buffer| {
 5492                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5493                            })
 5494                            .collect(),
 5495                    })
 5496                    .await
 5497                    .and_then(|result| result.transaction.context("missing transaction"));
 5498                lsp_store.update(cx, |lsp_store, _| {
 5499                    lsp_store.update_last_formatting_failure(&result);
 5500                })?;
 5501
 5502                let transaction_response = result?;
 5503                buffer_store
 5504                    .update(cx, |buffer_store, cx| {
 5505                        buffer_store.deserialize_project_transaction(
 5506                            transaction_response,
 5507                            push_to_history,
 5508                            cx,
 5509                        )
 5510                    })
 5511                    .await
 5512            })
 5513        } else {
 5514            Task::ready(Ok(ProjectTransaction::default()))
 5515        }
 5516    }
 5517
 5518    pub fn resolved_hint(
 5519        &mut self,
 5520        buffer_id: BufferId,
 5521        id: InlayId,
 5522        cx: &mut Context<Self>,
 5523    ) -> Option<ResolvedHint> {
 5524        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5525
 5526        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5527        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5528        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5529        let (server_id, resolve_data) = match &hint.resolve_state {
 5530            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5531            ResolveState::Resolving => {
 5532                return Some(ResolvedHint::Resolving(
 5533                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5534                ));
 5535            }
 5536            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5537        };
 5538
 5539        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5540        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5541        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5542            id,
 5543            cx.spawn(async move |lsp_store, cx| {
 5544                let resolved_hint = resolve_task.await;
 5545                lsp_store
 5546                    .update(cx, |lsp_store, _| {
 5547                        if let Some(old_inlay_hint) = lsp_store
 5548                            .lsp_data
 5549                            .get_mut(&buffer_id)
 5550                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5551                        {
 5552                            match resolved_hint {
 5553                                Ok(resolved_hint) => {
 5554                                    *old_inlay_hint = resolved_hint;
 5555                                }
 5556                                Err(e) => {
 5557                                    old_inlay_hint.resolve_state =
 5558                                        ResolveState::CanResolve(server_id, resolve_data);
 5559                                    log::error!("Inlay hint resolve failed: {e:#}");
 5560                                }
 5561                            }
 5562                        }
 5563                    })
 5564                    .ok();
 5565            })
 5566            .shared(),
 5567        );
 5568        debug_assert!(
 5569            previous_task.is_none(),
 5570            "Did not change hint's resolve state after spawning its resolve"
 5571        );
 5572        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5573        None
 5574    }
 5575
 5576    pub(crate) fn linked_edits(
 5577        &mut self,
 5578        buffer: &Entity<Buffer>,
 5579        position: Anchor,
 5580        cx: &mut Context<Self>,
 5581    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5582        let snapshot = buffer.read(cx).snapshot();
 5583        let scope = snapshot.language_scope_at(position);
 5584        let Some(server_id) = self
 5585            .as_local()
 5586            .and_then(|local| {
 5587                buffer.update(cx, |buffer, cx| {
 5588                    local
 5589                        .language_servers_for_buffer(buffer, cx)
 5590                        .filter(|(_, server)| {
 5591                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5592                        })
 5593                        .filter(|(adapter, _)| {
 5594                            scope
 5595                                .as_ref()
 5596                                .map(|scope| scope.language_allowed(&adapter.name))
 5597                                .unwrap_or(true)
 5598                        })
 5599                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5600                        .next()
 5601                })
 5602            })
 5603            .or_else(|| {
 5604                self.upstream_client()
 5605                    .is_some()
 5606                    .then_some(LanguageServerToQuery::FirstCapable)
 5607            })
 5608            .filter(|_| {
 5609                maybe!({
 5610                    buffer.read(cx).language_at(position)?;
 5611                    Some(
 5612                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5613                            .linked_edits,
 5614                    )
 5615                }) == Some(true)
 5616            })
 5617        else {
 5618            return Task::ready(Ok(Vec::new()));
 5619        };
 5620
 5621        self.request_lsp(
 5622            buffer.clone(),
 5623            server_id,
 5624            LinkedEditingRange { position },
 5625            cx,
 5626        )
 5627    }
 5628
 5629    fn apply_on_type_formatting(
 5630        &mut self,
 5631        buffer: Entity<Buffer>,
 5632        position: Anchor,
 5633        trigger: String,
 5634        cx: &mut Context<Self>,
 5635    ) -> Task<Result<Option<Transaction>>> {
 5636        if let Some((client, project_id)) = self.upstream_client() {
 5637            if !self.check_if_capable_for_proto_request(
 5638                &buffer,
 5639                |capabilities| {
 5640                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5641                },
 5642                cx,
 5643            ) {
 5644                return Task::ready(Ok(None));
 5645            }
 5646            let request = proto::OnTypeFormatting {
 5647                project_id,
 5648                buffer_id: buffer.read(cx).remote_id().into(),
 5649                position: Some(serialize_anchor(&position)),
 5650                trigger,
 5651                version: serialize_version(&buffer.read(cx).version()),
 5652            };
 5653            cx.background_spawn(async move {
 5654                client
 5655                    .request(request)
 5656                    .await?
 5657                    .transaction
 5658                    .map(language::proto::deserialize_transaction)
 5659                    .transpose()
 5660            })
 5661        } else if let Some(local) = self.as_local_mut() {
 5662            let buffer_id = buffer.read(cx).remote_id();
 5663            local.buffers_being_formatted.insert(buffer_id);
 5664            cx.spawn(async move |this, cx| {
 5665                let _cleanup = defer({
 5666                    let this = this.clone();
 5667                    let mut cx = cx.clone();
 5668                    move || {
 5669                        this.update(&mut cx, |this, _| {
 5670                            if let Some(local) = this.as_local_mut() {
 5671                                local.buffers_being_formatted.remove(&buffer_id);
 5672                            }
 5673                        })
 5674                        .ok();
 5675                    }
 5676                });
 5677
 5678                buffer
 5679                    .update(cx, |buffer, _| {
 5680                        buffer.wait_for_edits(Some(position.timestamp()))
 5681                    })
 5682                    .await?;
 5683                this.update(cx, |this, cx| {
 5684                    let position = position.to_point_utf16(buffer.read(cx));
 5685                    this.on_type_format(buffer, position, trigger, false, cx)
 5686                })?
 5687                .await
 5688            })
 5689        } else {
 5690            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5691        }
 5692    }
 5693
 5694    pub fn on_type_format<T: ToPointUtf16>(
 5695        &mut self,
 5696        buffer: Entity<Buffer>,
 5697        position: T,
 5698        trigger: String,
 5699        push_to_history: bool,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Transaction>>> {
 5702        let position = position.to_point_utf16(buffer.read(cx));
 5703        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5704    }
 5705
 5706    fn on_type_format_impl(
 5707        &mut self,
 5708        buffer: Entity<Buffer>,
 5709        position: PointUtf16,
 5710        trigger: String,
 5711        push_to_history: bool,
 5712        cx: &mut Context<Self>,
 5713    ) -> Task<Result<Option<Transaction>>> {
 5714        let options = buffer.update(cx, |buffer, cx| {
 5715            lsp_command::lsp_formatting_options(
 5716                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5717            )
 5718        });
 5719
 5720        cx.spawn(async move |this, cx| {
 5721            if let Some(waiter) =
 5722                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5723            {
 5724                waiter.await?;
 5725            }
 5726            cx.update(|cx| {
 5727                this.update(cx, |this, cx| {
 5728                    this.request_lsp(
 5729                        buffer.clone(),
 5730                        LanguageServerToQuery::FirstCapable,
 5731                        OnTypeFormatting {
 5732                            position,
 5733                            trigger,
 5734                            options,
 5735                            push_to_history,
 5736                        },
 5737                        cx,
 5738                    )
 5739                })
 5740            })?
 5741            .await
 5742        })
 5743    }
 5744
 5745    pub fn definitions(
 5746        &mut self,
 5747        buffer: &Entity<Buffer>,
 5748        position: PointUtf16,
 5749        cx: &mut Context<Self>,
 5750    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5751        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5752            let request = GetDefinitions { position };
 5753            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5754                return Task::ready(Ok(None));
 5755            }
 5756
 5757            let request_timeout = ProjectSettings::get_global(cx)
 5758                .global_lsp_settings
 5759                .get_request_timeout();
 5760
 5761            let request_task = upstream_client.request_lsp(
 5762                project_id,
 5763                None,
 5764                request_timeout,
 5765                cx.background_executor().clone(),
 5766                request.to_proto(project_id, buffer.read(cx)),
 5767            );
 5768            let buffer = buffer.clone();
 5769            cx.spawn(async move |weak_lsp_store, cx| {
 5770                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5771                    return Ok(None);
 5772                };
 5773                let Some(responses) = request_task.await? else {
 5774                    return Ok(None);
 5775                };
 5776                let actions = join_all(responses.payload.into_iter().map(|response| {
 5777                    GetDefinitions { position }.response_from_proto(
 5778                        response.response,
 5779                        lsp_store.clone(),
 5780                        buffer.clone(),
 5781                        cx.clone(),
 5782                    )
 5783                }))
 5784                .await;
 5785
 5786                Ok(Some(
 5787                    actions
 5788                        .into_iter()
 5789                        .collect::<Result<Vec<Vec<_>>>>()?
 5790                        .into_iter()
 5791                        .flatten()
 5792                        .dedup()
 5793                        .collect(),
 5794                ))
 5795            })
 5796        } else {
 5797            let definitions_task = self.request_multiple_lsp_locally(
 5798                buffer,
 5799                Some(position),
 5800                GetDefinitions { position },
 5801                cx,
 5802            );
 5803            cx.background_spawn(async move {
 5804                Ok(Some(
 5805                    definitions_task
 5806                        .await
 5807                        .into_iter()
 5808                        .flat_map(|(_, definitions)| definitions)
 5809                        .dedup()
 5810                        .collect(),
 5811                ))
 5812            })
 5813        }
 5814    }
 5815
 5816    pub fn declarations(
 5817        &mut self,
 5818        buffer: &Entity<Buffer>,
 5819        position: PointUtf16,
 5820        cx: &mut Context<Self>,
 5821    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5822        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5823            let request = GetDeclarations { position };
 5824            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5825                return Task::ready(Ok(None));
 5826            }
 5827            let request_timeout = ProjectSettings::get_global(cx)
 5828                .global_lsp_settings
 5829                .get_request_timeout();
 5830            let request_task = upstream_client.request_lsp(
 5831                project_id,
 5832                None,
 5833                request_timeout,
 5834                cx.background_executor().clone(),
 5835                request.to_proto(project_id, buffer.read(cx)),
 5836            );
 5837            let buffer = buffer.clone();
 5838            cx.spawn(async move |weak_lsp_store, cx| {
 5839                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5840                    return Ok(None);
 5841                };
 5842                let Some(responses) = request_task.await? else {
 5843                    return Ok(None);
 5844                };
 5845                let actions = join_all(responses.payload.into_iter().map(|response| {
 5846                    GetDeclarations { position }.response_from_proto(
 5847                        response.response,
 5848                        lsp_store.clone(),
 5849                        buffer.clone(),
 5850                        cx.clone(),
 5851                    )
 5852                }))
 5853                .await;
 5854
 5855                Ok(Some(
 5856                    actions
 5857                        .into_iter()
 5858                        .collect::<Result<Vec<Vec<_>>>>()?
 5859                        .into_iter()
 5860                        .flatten()
 5861                        .dedup()
 5862                        .collect(),
 5863                ))
 5864            })
 5865        } else {
 5866            let declarations_task = self.request_multiple_lsp_locally(
 5867                buffer,
 5868                Some(position),
 5869                GetDeclarations { position },
 5870                cx,
 5871            );
 5872            cx.background_spawn(async move {
 5873                Ok(Some(
 5874                    declarations_task
 5875                        .await
 5876                        .into_iter()
 5877                        .flat_map(|(_, declarations)| declarations)
 5878                        .dedup()
 5879                        .collect(),
 5880                ))
 5881            })
 5882        }
 5883    }
 5884
 5885    pub fn type_definitions(
 5886        &mut self,
 5887        buffer: &Entity<Buffer>,
 5888        position: PointUtf16,
 5889        cx: &mut Context<Self>,
 5890    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5891        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5892            let request = GetTypeDefinitions { position };
 5893            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5894                return Task::ready(Ok(None));
 5895            }
 5896            let request_timeout = ProjectSettings::get_global(cx)
 5897                .global_lsp_settings
 5898                .get_request_timeout();
 5899            let request_task = upstream_client.request_lsp(
 5900                project_id,
 5901                None,
 5902                request_timeout,
 5903                cx.background_executor().clone(),
 5904                request.to_proto(project_id, buffer.read(cx)),
 5905            );
 5906            let buffer = buffer.clone();
 5907            cx.spawn(async move |weak_lsp_store, cx| {
 5908                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5909                    return Ok(None);
 5910                };
 5911                let Some(responses) = request_task.await? else {
 5912                    return Ok(None);
 5913                };
 5914                let actions = join_all(responses.payload.into_iter().map(|response| {
 5915                    GetTypeDefinitions { position }.response_from_proto(
 5916                        response.response,
 5917                        lsp_store.clone(),
 5918                        buffer.clone(),
 5919                        cx.clone(),
 5920                    )
 5921                }))
 5922                .await;
 5923
 5924                Ok(Some(
 5925                    actions
 5926                        .into_iter()
 5927                        .collect::<Result<Vec<Vec<_>>>>()?
 5928                        .into_iter()
 5929                        .flatten()
 5930                        .dedup()
 5931                        .collect(),
 5932                ))
 5933            })
 5934        } else {
 5935            let type_definitions_task = self.request_multiple_lsp_locally(
 5936                buffer,
 5937                Some(position),
 5938                GetTypeDefinitions { position },
 5939                cx,
 5940            );
 5941            cx.background_spawn(async move {
 5942                Ok(Some(
 5943                    type_definitions_task
 5944                        .await
 5945                        .into_iter()
 5946                        .flat_map(|(_, type_definitions)| type_definitions)
 5947                        .dedup()
 5948                        .collect(),
 5949                ))
 5950            })
 5951        }
 5952    }
 5953
 5954    pub fn implementations(
 5955        &mut self,
 5956        buffer: &Entity<Buffer>,
 5957        position: PointUtf16,
 5958        cx: &mut Context<Self>,
 5959    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5960        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5961            let request = GetImplementations { position };
 5962            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5963                return Task::ready(Ok(None));
 5964            }
 5965
 5966            let request_timeout = ProjectSettings::get_global(cx)
 5967                .global_lsp_settings
 5968                .get_request_timeout();
 5969            let request_task = upstream_client.request_lsp(
 5970                project_id,
 5971                None,
 5972                request_timeout,
 5973                cx.background_executor().clone(),
 5974                request.to_proto(project_id, buffer.read(cx)),
 5975            );
 5976            let buffer = buffer.clone();
 5977            cx.spawn(async move |weak_lsp_store, cx| {
 5978                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5979                    return Ok(None);
 5980                };
 5981                let Some(responses) = request_task.await? else {
 5982                    return Ok(None);
 5983                };
 5984                let actions = join_all(responses.payload.into_iter().map(|response| {
 5985                    GetImplementations { position }.response_from_proto(
 5986                        response.response,
 5987                        lsp_store.clone(),
 5988                        buffer.clone(),
 5989                        cx.clone(),
 5990                    )
 5991                }))
 5992                .await;
 5993
 5994                Ok(Some(
 5995                    actions
 5996                        .into_iter()
 5997                        .collect::<Result<Vec<Vec<_>>>>()?
 5998                        .into_iter()
 5999                        .flatten()
 6000                        .dedup()
 6001                        .collect(),
 6002                ))
 6003            })
 6004        } else {
 6005            let implementations_task = self.request_multiple_lsp_locally(
 6006                buffer,
 6007                Some(position),
 6008                GetImplementations { position },
 6009                cx,
 6010            );
 6011            cx.background_spawn(async move {
 6012                Ok(Some(
 6013                    implementations_task
 6014                        .await
 6015                        .into_iter()
 6016                        .flat_map(|(_, implementations)| implementations)
 6017                        .dedup()
 6018                        .collect(),
 6019                ))
 6020            })
 6021        }
 6022    }
 6023
 6024    pub fn references(
 6025        &mut self,
 6026        buffer: &Entity<Buffer>,
 6027        position: PointUtf16,
 6028        cx: &mut Context<Self>,
 6029    ) -> Task<Result<Option<Vec<Location>>>> {
 6030        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6031            let request = GetReferences { position };
 6032            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6033                return Task::ready(Ok(None));
 6034            }
 6035
 6036            let request_timeout = ProjectSettings::get_global(cx)
 6037                .global_lsp_settings
 6038                .get_request_timeout();
 6039            let request_task = upstream_client.request_lsp(
 6040                project_id,
 6041                None,
 6042                request_timeout,
 6043                cx.background_executor().clone(),
 6044                request.to_proto(project_id, buffer.read(cx)),
 6045            );
 6046            let buffer = buffer.clone();
 6047            cx.spawn(async move |weak_lsp_store, cx| {
 6048                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6049                    return Ok(None);
 6050                };
 6051                let Some(responses) = request_task.await? else {
 6052                    return Ok(None);
 6053                };
 6054
 6055                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6056                    GetReferences { position }.response_from_proto(
 6057                        lsp_response.response,
 6058                        lsp_store.clone(),
 6059                        buffer.clone(),
 6060                        cx.clone(),
 6061                    )
 6062                }))
 6063                .await
 6064                .into_iter()
 6065                .collect::<Result<Vec<Vec<_>>>>()?
 6066                .into_iter()
 6067                .flatten()
 6068                .dedup()
 6069                .collect();
 6070                Ok(Some(locations))
 6071            })
 6072        } else {
 6073            let references_task = self.request_multiple_lsp_locally(
 6074                buffer,
 6075                Some(position),
 6076                GetReferences { position },
 6077                cx,
 6078            );
 6079            cx.background_spawn(async move {
 6080                Ok(Some(
 6081                    references_task
 6082                        .await
 6083                        .into_iter()
 6084                        .flat_map(|(_, references)| references)
 6085                        .dedup()
 6086                        .collect(),
 6087                ))
 6088            })
 6089        }
 6090    }
 6091
 6092    pub fn code_actions(
 6093        &mut self,
 6094        buffer: &Entity<Buffer>,
 6095        range: Range<Anchor>,
 6096        kinds: Option<Vec<CodeActionKind>>,
 6097        cx: &mut Context<Self>,
 6098    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6099        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6100            let request = GetCodeActions {
 6101                range: range.clone(),
 6102                kinds: kinds.clone(),
 6103            };
 6104            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6105                return Task::ready(Ok(None));
 6106            }
 6107            let request_timeout = ProjectSettings::get_global(cx)
 6108                .global_lsp_settings
 6109                .get_request_timeout();
 6110            let request_task = upstream_client.request_lsp(
 6111                project_id,
 6112                None,
 6113                request_timeout,
 6114                cx.background_executor().clone(),
 6115                request.to_proto(project_id, buffer.read(cx)),
 6116            );
 6117            let buffer = buffer.clone();
 6118            cx.spawn(async move |weak_lsp_store, cx| {
 6119                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6120                    return Ok(None);
 6121                };
 6122                let Some(responses) = request_task.await? else {
 6123                    return Ok(None);
 6124                };
 6125                let actions = join_all(responses.payload.into_iter().map(|response| {
 6126                    GetCodeActions {
 6127                        range: range.clone(),
 6128                        kinds: kinds.clone(),
 6129                    }
 6130                    .response_from_proto(
 6131                        response.response,
 6132                        lsp_store.clone(),
 6133                        buffer.clone(),
 6134                        cx.clone(),
 6135                    )
 6136                }))
 6137                .await;
 6138
 6139                Ok(Some(
 6140                    actions
 6141                        .into_iter()
 6142                        .collect::<Result<Vec<Vec<_>>>>()?
 6143                        .into_iter()
 6144                        .flatten()
 6145                        .collect(),
 6146                ))
 6147            })
 6148        } else {
 6149            let all_actions_task = self.request_multiple_lsp_locally(
 6150                buffer,
 6151                Some(range.start),
 6152                GetCodeActions { range, kinds },
 6153                cx,
 6154            );
 6155            cx.background_spawn(async move {
 6156                Ok(Some(
 6157                    all_actions_task
 6158                        .await
 6159                        .into_iter()
 6160                        .flat_map(|(_, actions)| actions)
 6161                        .collect(),
 6162                ))
 6163            })
 6164        }
 6165    }
 6166
 6167    #[inline(never)]
 6168    pub fn completions(
 6169        &self,
 6170        buffer: &Entity<Buffer>,
 6171        position: PointUtf16,
 6172        context: CompletionContext,
 6173        cx: &mut Context<Self>,
 6174    ) -> Task<Result<Vec<CompletionResponse>>> {
 6175        let language_registry = self.languages.clone();
 6176
 6177        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6178            let snapshot = buffer.read(cx).snapshot();
 6179            let offset = position.to_offset(&snapshot);
 6180            let scope = snapshot.language_scope_at(offset);
 6181            let capable_lsps = self.all_capable_for_proto_request(
 6182                buffer,
 6183                |server_name, capabilities| {
 6184                    capabilities.completion_provider.is_some()
 6185                        && scope
 6186                            .as_ref()
 6187                            .map(|scope| scope.language_allowed(server_name))
 6188                            .unwrap_or(true)
 6189                },
 6190                cx,
 6191            );
 6192            if capable_lsps.is_empty() {
 6193                return Task::ready(Ok(Vec::new()));
 6194            }
 6195
 6196            let language = buffer.read(cx).language().cloned();
 6197
 6198            let buffer = buffer.clone();
 6199
 6200            cx.spawn(async move |this, cx| {
 6201                let requests = join_all(
 6202                    capable_lsps
 6203                        .into_iter()
 6204                        .map(|(id, server_name)| {
 6205                            let request = GetCompletions {
 6206                                position,
 6207                                context: context.clone(),
 6208                                server_id: Some(id),
 6209                            };
 6210                            let buffer = buffer.clone();
 6211                            let language = language.clone();
 6212                            let lsp_adapter = language.as_ref().and_then(|language| {
 6213                                let adapters = language_registry.lsp_adapters(&language.name());
 6214                                adapters
 6215                                    .iter()
 6216                                    .find(|adapter| adapter.name() == server_name)
 6217                                    .or_else(|| adapters.first())
 6218                                    .cloned()
 6219                            });
 6220                            let upstream_client = upstream_client.clone();
 6221                            let response = this
 6222                                .update(cx, |this, cx| {
 6223                                    this.send_lsp_proto_request(
 6224                                        buffer,
 6225                                        upstream_client,
 6226                                        project_id,
 6227                                        request,
 6228                                        cx,
 6229                                    )
 6230                                })
 6231                                .log_err();
 6232                            async move {
 6233                                let response = response?.await.log_err()?;
 6234
 6235                                let completions = populate_labels_for_completions(
 6236                                    response.completions,
 6237                                    language,
 6238                                    lsp_adapter,
 6239                                )
 6240                                .await;
 6241
 6242                                Some(CompletionResponse {
 6243                                    completions,
 6244                                    display_options: CompletionDisplayOptions::default(),
 6245                                    is_incomplete: response.is_incomplete,
 6246                                })
 6247                            }
 6248                        })
 6249                        .collect::<Vec<_>>(),
 6250                );
 6251                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6252            })
 6253        } else if let Some(local) = self.as_local() {
 6254            let snapshot = buffer.read(cx).snapshot();
 6255            let offset = position.to_offset(&snapshot);
 6256            let scope = snapshot.language_scope_at(offset);
 6257            let language = snapshot.language().cloned();
 6258            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6259                .completions
 6260                .clone();
 6261            if !completion_settings.lsp {
 6262                return Task::ready(Ok(Vec::new()));
 6263            }
 6264
 6265            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6266                local
 6267                    .language_servers_for_buffer(buffer, cx)
 6268                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6269                    .filter(|(adapter, _)| {
 6270                        scope
 6271                            .as_ref()
 6272                            .map(|scope| scope.language_allowed(&adapter.name))
 6273                            .unwrap_or(true)
 6274                    })
 6275                    .map(|(_, server)| server.server_id())
 6276                    .collect()
 6277            });
 6278
 6279            let buffer = buffer.clone();
 6280            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6281            let lsp_timeout = if lsp_timeout > 0 {
 6282                Some(Duration::from_millis(lsp_timeout))
 6283            } else {
 6284                None
 6285            };
 6286            cx.spawn(async move |this,  cx| {
 6287                let mut tasks = Vec::with_capacity(server_ids.len());
 6288                this.update(cx, |lsp_store, cx| {
 6289                    for server_id in server_ids {
 6290                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6291                        let lsp_timeout = lsp_timeout
 6292                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6293                        let mut timeout = cx.background_spawn(async move {
 6294                            match lsp_timeout {
 6295                                Some(lsp_timeout) => {
 6296                                    lsp_timeout.await;
 6297                                    true
 6298                                },
 6299                                None => false,
 6300                            }
 6301                        }).fuse();
 6302                        let mut lsp_request = lsp_store.request_lsp(
 6303                            buffer.clone(),
 6304                            LanguageServerToQuery::Other(server_id),
 6305                            GetCompletions {
 6306                                position,
 6307                                context: context.clone(),
 6308                                server_id: Some(server_id),
 6309                            },
 6310                            cx,
 6311                        ).fuse();
 6312                        let new_task = cx.background_spawn(async move {
 6313                            select_biased! {
 6314                                response = lsp_request => anyhow::Ok(Some(response?)),
 6315                                timeout_happened = timeout => {
 6316                                    if timeout_happened {
 6317                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6318                                        Ok(None)
 6319                                    } else {
 6320                                        let completions = lsp_request.await?;
 6321                                        Ok(Some(completions))
 6322                                    }
 6323                                },
 6324                            }
 6325                        });
 6326                        tasks.push((lsp_adapter, new_task));
 6327                    }
 6328                })?;
 6329
 6330                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6331                    let completion_response = task.await.ok()??;
 6332                    let completions = populate_labels_for_completions(
 6333                            completion_response.completions,
 6334                            language.clone(),
 6335                            lsp_adapter,
 6336                        )
 6337                        .await;
 6338                    Some(CompletionResponse {
 6339                        completions,
 6340                        display_options: CompletionDisplayOptions::default(),
 6341                        is_incomplete: completion_response.is_incomplete,
 6342                    })
 6343                });
 6344
 6345                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6346
 6347                Ok(responses.into_iter().flatten().collect())
 6348            })
 6349        } else {
 6350            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6351        }
 6352    }
 6353
 6354    pub fn resolve_completions(
 6355        &self,
 6356        buffer: Entity<Buffer>,
 6357        completion_indices: Vec<usize>,
 6358        completions: Rc<RefCell<Box<[Completion]>>>,
 6359        cx: &mut Context<Self>,
 6360    ) -> Task<Result<bool>> {
 6361        let client = self.upstream_client();
 6362        let buffer_id = buffer.read(cx).remote_id();
 6363        let buffer_snapshot = buffer.read(cx).snapshot();
 6364
 6365        if !self.check_if_capable_for_proto_request(
 6366            &buffer,
 6367            GetCompletions::can_resolve_completions,
 6368            cx,
 6369        ) {
 6370            return Task::ready(Ok(false));
 6371        }
 6372        cx.spawn(async move |lsp_store, cx| {
 6373            let request_timeout = cx.update(|app| {
 6374                ProjectSettings::get_global(app)
 6375                    .global_lsp_settings
 6376                    .get_request_timeout()
 6377            });
 6378
 6379            let mut did_resolve = false;
 6380            if let Some((client, project_id)) = client {
 6381                for completion_index in completion_indices {
 6382                    let server_id = {
 6383                        let completion = &completions.borrow()[completion_index];
 6384                        completion.source.server_id()
 6385                    };
 6386                    if let Some(server_id) = server_id {
 6387                        if Self::resolve_completion_remote(
 6388                            project_id,
 6389                            server_id,
 6390                            buffer_id,
 6391                            completions.clone(),
 6392                            completion_index,
 6393                            client.clone(),
 6394                        )
 6395                        .await
 6396                        .log_err()
 6397                        .is_some()
 6398                        {
 6399                            did_resolve = true;
 6400                        }
 6401                    } else {
 6402                        resolve_word_completion(
 6403                            &buffer_snapshot,
 6404                            &mut completions.borrow_mut()[completion_index],
 6405                        );
 6406                    }
 6407                }
 6408            } else {
 6409                for completion_index in completion_indices {
 6410                    let server_id = {
 6411                        let completion = &completions.borrow()[completion_index];
 6412                        completion.source.server_id()
 6413                    };
 6414                    if let Some(server_id) = server_id {
 6415                        let server_and_adapter = lsp_store
 6416                            .read_with(cx, |lsp_store, _| {
 6417                                let server = lsp_store.language_server_for_id(server_id)?;
 6418                                let adapter =
 6419                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6420                                Some((server, adapter))
 6421                            })
 6422                            .ok()
 6423                            .flatten();
 6424                        let Some((server, adapter)) = server_and_adapter else {
 6425                            continue;
 6426                        };
 6427
 6428                        let resolved = Self::resolve_completion_local(
 6429                            server,
 6430                            completions.clone(),
 6431                            completion_index,
 6432                            request_timeout,
 6433                        )
 6434                        .await
 6435                        .log_err()
 6436                        .is_some();
 6437                        if resolved {
 6438                            Self::regenerate_completion_labels(
 6439                                adapter,
 6440                                &buffer_snapshot,
 6441                                completions.clone(),
 6442                                completion_index,
 6443                            )
 6444                            .await
 6445                            .log_err();
 6446                            did_resolve = true;
 6447                        }
 6448                    } else {
 6449                        resolve_word_completion(
 6450                            &buffer_snapshot,
 6451                            &mut completions.borrow_mut()[completion_index],
 6452                        );
 6453                    }
 6454                }
 6455            }
 6456
 6457            Ok(did_resolve)
 6458        })
 6459    }
 6460
 6461    async fn resolve_completion_local(
 6462        server: Arc<lsp::LanguageServer>,
 6463        completions: Rc<RefCell<Box<[Completion]>>>,
 6464        completion_index: usize,
 6465        request_timeout: Duration,
 6466    ) -> Result<()> {
 6467        let server_id = server.server_id();
 6468        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6469            return Ok(());
 6470        }
 6471
 6472        let request = {
 6473            let completion = &completions.borrow()[completion_index];
 6474            match &completion.source {
 6475                CompletionSource::Lsp {
 6476                    lsp_completion,
 6477                    resolved,
 6478                    server_id: completion_server_id,
 6479                    ..
 6480                } => {
 6481                    if *resolved {
 6482                        return Ok(());
 6483                    }
 6484                    anyhow::ensure!(
 6485                        server_id == *completion_server_id,
 6486                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6487                    );
 6488                    server.request::<lsp::request::ResolveCompletionItem>(
 6489                        *lsp_completion.clone(),
 6490                        request_timeout,
 6491                    )
 6492                }
 6493                CompletionSource::BufferWord { .. }
 6494                | CompletionSource::Dap { .. }
 6495                | CompletionSource::Custom => {
 6496                    return Ok(());
 6497                }
 6498            }
 6499        };
 6500        let resolved_completion = request
 6501            .await
 6502            .into_response()
 6503            .context("resolve completion")?;
 6504
 6505        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6506        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6507
 6508        let mut completions = completions.borrow_mut();
 6509        let completion = &mut completions[completion_index];
 6510        if let CompletionSource::Lsp {
 6511            lsp_completion,
 6512            resolved,
 6513            server_id: completion_server_id,
 6514            ..
 6515        } = &mut completion.source
 6516        {
 6517            if *resolved {
 6518                return Ok(());
 6519            }
 6520            anyhow::ensure!(
 6521                server_id == *completion_server_id,
 6522                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6523            );
 6524            **lsp_completion = resolved_completion;
 6525            *resolved = true;
 6526        }
 6527        Ok(())
 6528    }
 6529
 6530    async fn regenerate_completion_labels(
 6531        adapter: Arc<CachedLspAdapter>,
 6532        snapshot: &BufferSnapshot,
 6533        completions: Rc<RefCell<Box<[Completion]>>>,
 6534        completion_index: usize,
 6535    ) -> Result<()> {
 6536        let completion_item = completions.borrow()[completion_index]
 6537            .source
 6538            .lsp_completion(true)
 6539            .map(Cow::into_owned);
 6540        if let Some(lsp_documentation) = completion_item
 6541            .as_ref()
 6542            .and_then(|completion_item| completion_item.documentation.clone())
 6543        {
 6544            let mut completions = completions.borrow_mut();
 6545            let completion = &mut completions[completion_index];
 6546            completion.documentation = Some(lsp_documentation.into());
 6547        } else {
 6548            let mut completions = completions.borrow_mut();
 6549            let completion = &mut completions[completion_index];
 6550            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6551        }
 6552
 6553        let mut new_label = match completion_item {
 6554            Some(completion_item) => {
 6555                // Some language servers always return `detail` lazily via resolve, regardless of
 6556                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6557                // See: https://github.com/yioneko/vtsls/issues/213
 6558                let language = snapshot.language();
 6559                match language {
 6560                    Some(language) => {
 6561                        adapter
 6562                            .labels_for_completions(
 6563                                std::slice::from_ref(&completion_item),
 6564                                language,
 6565                            )
 6566                            .await?
 6567                    }
 6568                    None => Vec::new(),
 6569                }
 6570                .pop()
 6571                .flatten()
 6572                .unwrap_or_else(|| {
 6573                    CodeLabel::fallback_for_completion(
 6574                        &completion_item,
 6575                        language.map(|language| language.as_ref()),
 6576                    )
 6577                })
 6578            }
 6579            None => CodeLabel::plain(
 6580                completions.borrow()[completion_index].new_text.clone(),
 6581                None,
 6582            ),
 6583        };
 6584        ensure_uniform_list_compatible_label(&mut new_label);
 6585
 6586        let mut completions = completions.borrow_mut();
 6587        let completion = &mut completions[completion_index];
 6588        if completion.label.filter_text() == new_label.filter_text() {
 6589            completion.label = new_label;
 6590        } else {
 6591            log::error!(
 6592                "Resolved completion changed display label from {} to {}. \
 6593                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6594                completion.label.text(),
 6595                new_label.text(),
 6596                completion.label.filter_text(),
 6597                new_label.filter_text()
 6598            );
 6599        }
 6600
 6601        Ok(())
 6602    }
 6603
 6604    async fn resolve_completion_remote(
 6605        project_id: u64,
 6606        server_id: LanguageServerId,
 6607        buffer_id: BufferId,
 6608        completions: Rc<RefCell<Box<[Completion]>>>,
 6609        completion_index: usize,
 6610        client: AnyProtoClient,
 6611    ) -> Result<()> {
 6612        let lsp_completion = {
 6613            let completion = &completions.borrow()[completion_index];
 6614            match &completion.source {
 6615                CompletionSource::Lsp {
 6616                    lsp_completion,
 6617                    resolved,
 6618                    server_id: completion_server_id,
 6619                    ..
 6620                } => {
 6621                    anyhow::ensure!(
 6622                        server_id == *completion_server_id,
 6623                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6624                    );
 6625                    if *resolved {
 6626                        return Ok(());
 6627                    }
 6628                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6629                }
 6630                CompletionSource::Custom
 6631                | CompletionSource::Dap { .. }
 6632                | CompletionSource::BufferWord { .. } => {
 6633                    return Ok(());
 6634                }
 6635            }
 6636        };
 6637        let request = proto::ResolveCompletionDocumentation {
 6638            project_id,
 6639            language_server_id: server_id.0 as u64,
 6640            lsp_completion,
 6641            buffer_id: buffer_id.into(),
 6642        };
 6643
 6644        let response = client
 6645            .request(request)
 6646            .await
 6647            .context("completion documentation resolve proto request")?;
 6648        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6649
 6650        let documentation = if response.documentation.is_empty() {
 6651            CompletionDocumentation::Undocumented
 6652        } else if response.documentation_is_markdown {
 6653            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6654        } else if response.documentation.lines().count() <= 1 {
 6655            CompletionDocumentation::SingleLine(response.documentation.into())
 6656        } else {
 6657            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6658        };
 6659
 6660        let mut completions = completions.borrow_mut();
 6661        let completion = &mut completions[completion_index];
 6662        completion.documentation = Some(documentation);
 6663        if let CompletionSource::Lsp {
 6664            insert_range,
 6665            lsp_completion,
 6666            resolved,
 6667            server_id: completion_server_id,
 6668            lsp_defaults: _,
 6669        } = &mut completion.source
 6670        {
 6671            let completion_insert_range = response
 6672                .old_insert_start
 6673                .and_then(deserialize_anchor)
 6674                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6675            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6676
 6677            if *resolved {
 6678                return Ok(());
 6679            }
 6680            anyhow::ensure!(
 6681                server_id == *completion_server_id,
 6682                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6683            );
 6684            **lsp_completion = resolved_lsp_completion;
 6685            *resolved = true;
 6686        }
 6687
 6688        let replace_range = response
 6689            .old_replace_start
 6690            .and_then(deserialize_anchor)
 6691            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6692        if let Some((old_replace_start, old_replace_end)) = replace_range
 6693            && !response.new_text.is_empty()
 6694        {
 6695            completion.new_text = response.new_text;
 6696            completion.replace_range = old_replace_start..old_replace_end;
 6697        }
 6698
 6699        Ok(())
 6700    }
 6701
 6702    pub fn apply_additional_edits_for_completion(
 6703        &self,
 6704        buffer_handle: Entity<Buffer>,
 6705        completions: Rc<RefCell<Box<[Completion]>>>,
 6706        completion_index: usize,
 6707        push_to_history: bool,
 6708        cx: &mut Context<Self>,
 6709    ) -> Task<Result<Option<Transaction>>> {
 6710        if let Some((client, project_id)) = self.upstream_client() {
 6711            let buffer = buffer_handle.read(cx);
 6712            let buffer_id = buffer.remote_id();
 6713            cx.spawn(async move |_, cx| {
 6714                let request = {
 6715                    let completion = completions.borrow()[completion_index].clone();
 6716                    proto::ApplyCompletionAdditionalEdits {
 6717                        project_id,
 6718                        buffer_id: buffer_id.into(),
 6719                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6720                            replace_range: completion.replace_range,
 6721                            new_text: completion.new_text,
 6722                            source: completion.source,
 6723                        })),
 6724                    }
 6725                };
 6726
 6727                let Some(transaction) = client.request(request).await?.transaction else {
 6728                    return Ok(None);
 6729                };
 6730
 6731                let transaction = language::proto::deserialize_transaction(transaction)?;
 6732                buffer_handle
 6733                    .update(cx, |buffer, _| {
 6734                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6735                    })
 6736                    .await?;
 6737                if push_to_history {
 6738                    buffer_handle.update(cx, |buffer, _| {
 6739                        buffer.push_transaction(transaction.clone(), Instant::now());
 6740                        buffer.finalize_last_transaction();
 6741                    });
 6742                }
 6743                Ok(Some(transaction))
 6744            })
 6745        } else {
 6746            let request_timeout = ProjectSettings::get_global(cx)
 6747                .global_lsp_settings
 6748                .get_request_timeout();
 6749
 6750            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6751                let completion = &completions.borrow()[completion_index];
 6752                let server_id = completion.source.server_id()?;
 6753                Some(
 6754                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6755                        .1
 6756                        .clone(),
 6757                )
 6758            }) else {
 6759                return Task::ready(Ok(None));
 6760            };
 6761
 6762            cx.spawn(async move |this, cx| {
 6763                Self::resolve_completion_local(
 6764                    server.clone(),
 6765                    completions.clone(),
 6766                    completion_index,
 6767                    request_timeout,
 6768                )
 6769                .await
 6770                .context("resolving completion")?;
 6771                let completion = completions.borrow()[completion_index].clone();
 6772                let additional_text_edits = completion
 6773                    .source
 6774                    .lsp_completion(true)
 6775                    .as_ref()
 6776                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6777                if let Some(edits) = additional_text_edits {
 6778                    let edits = this
 6779                        .update(cx, |this, cx| {
 6780                            this.as_local_mut().unwrap().edits_from_lsp(
 6781                                &buffer_handle,
 6782                                edits,
 6783                                server.server_id(),
 6784                                None,
 6785                                cx,
 6786                            )
 6787                        })?
 6788                        .await?;
 6789
 6790                    buffer_handle.update(cx, |buffer, cx| {
 6791                        buffer.finalize_last_transaction();
 6792                        buffer.start_transaction();
 6793
 6794                        for (range, text) in edits {
 6795                            let primary = &completion.replace_range;
 6796
 6797                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6798                            // and the primary completion is just an insertion (empty range), then this is likely
 6799                            // an auto-import scenario and should not be considered overlapping
 6800                            // https://github.com/zed-industries/zed/issues/26136
 6801                            let is_file_start_auto_import = {
 6802                                let snapshot = buffer.snapshot();
 6803                                let primary_start_point = primary.start.to_point(&snapshot);
 6804                                let range_start_point = range.start.to_point(&snapshot);
 6805
 6806                                let result = primary_start_point.row == 0
 6807                                    && primary_start_point.column == 0
 6808                                    && range_start_point.row == 0
 6809                                    && range_start_point.column == 0;
 6810
 6811                                result
 6812                            };
 6813
 6814                            let has_overlap = if is_file_start_auto_import {
 6815                                false
 6816                            } else {
 6817                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6818                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6819                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6820                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6821                                let result = start_within || end_within;
 6822                                result
 6823                            };
 6824
 6825                            //Skip additional edits which overlap with the primary completion edit
 6826                            //https://github.com/zed-industries/zed/pull/1871
 6827                            if !has_overlap {
 6828                                buffer.edit([(range, text)], None, cx);
 6829                            }
 6830                        }
 6831
 6832                        let transaction = if buffer.end_transaction(cx).is_some() {
 6833                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6834                            if !push_to_history {
 6835                                buffer.forget_transaction(transaction.id);
 6836                            }
 6837                            Some(transaction)
 6838                        } else {
 6839                            None
 6840                        };
 6841                        Ok(transaction)
 6842                    })
 6843                } else {
 6844                    Ok(None)
 6845                }
 6846            })
 6847        }
 6848    }
 6849
 6850    pub fn pull_diagnostics(
 6851        &mut self,
 6852        buffer: Entity<Buffer>,
 6853        cx: &mut Context<Self>,
 6854    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6855        let buffer_id = buffer.read(cx).remote_id();
 6856
 6857        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6858            let mut suitable_capabilities = None;
 6859            // Are we capable for proto request?
 6860            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6861                &buffer,
 6862                |capabilities| {
 6863                    if let Some(caps) = &capabilities.diagnostic_provider {
 6864                        suitable_capabilities = Some(caps.clone());
 6865                        true
 6866                    } else {
 6867                        false
 6868                    }
 6869                },
 6870                cx,
 6871            );
 6872            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6873            let Some(dynamic_caps) = suitable_capabilities else {
 6874                return Task::ready(Ok(None));
 6875            };
 6876            assert!(any_server_has_diagnostics_provider);
 6877
 6878            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6879            let request = GetDocumentDiagnostics {
 6880                previous_result_id: None,
 6881                identifier,
 6882                registration_id: None,
 6883            };
 6884            let request_timeout = ProjectSettings::get_global(cx)
 6885                .global_lsp_settings
 6886                .get_request_timeout();
 6887            let request_task = client.request_lsp(
 6888                upstream_project_id,
 6889                None,
 6890                request_timeout,
 6891                cx.background_executor().clone(),
 6892                request.to_proto(upstream_project_id, buffer.read(cx)),
 6893            );
 6894            cx.background_spawn(async move {
 6895                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6896                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6897                // Do not attempt to further process the dummy responses here.
 6898                let _response = request_task.await?;
 6899                Ok(None)
 6900            })
 6901        } else {
 6902            let servers = buffer.update(cx, |buffer, cx| {
 6903                self.running_language_servers_for_local_buffer(buffer, cx)
 6904                    .map(|(_, server)| server.clone())
 6905                    .collect::<Vec<_>>()
 6906            });
 6907
 6908            let pull_diagnostics = servers
 6909                .into_iter()
 6910                .flat_map(|server| {
 6911                    let result = maybe!({
 6912                        let local = self.as_local()?;
 6913                        let server_id = server.server_id();
 6914                        let providers_with_identifiers = local
 6915                            .language_server_dynamic_registrations
 6916                            .get(&server_id)
 6917                            .into_iter()
 6918                            .flat_map(|registrations| registrations.diagnostics.clone())
 6919                            .collect::<Vec<_>>();
 6920                        Some(
 6921                            providers_with_identifiers
 6922                                .into_iter()
 6923                                .map(|(registration_id, dynamic_caps)| {
 6924                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6925                                    let registration_id = registration_id.map(SharedString::from);
 6926                                    let result_id = self.result_id_for_buffer_pull(
 6927                                        server_id,
 6928                                        buffer_id,
 6929                                        &registration_id,
 6930                                        cx,
 6931                                    );
 6932                                    self.request_lsp(
 6933                                        buffer.clone(),
 6934                                        LanguageServerToQuery::Other(server_id),
 6935                                        GetDocumentDiagnostics {
 6936                                            previous_result_id: result_id,
 6937                                            registration_id,
 6938                                            identifier,
 6939                                        },
 6940                                        cx,
 6941                                    )
 6942                                })
 6943                                .collect::<Vec<_>>(),
 6944                        )
 6945                    });
 6946
 6947                    result.unwrap_or_default()
 6948                })
 6949                .collect::<Vec<_>>();
 6950
 6951            cx.background_spawn(async move {
 6952                let mut responses = Vec::new();
 6953                for diagnostics in join_all(pull_diagnostics).await {
 6954                    responses.extend(diagnostics?);
 6955                }
 6956                Ok(Some(responses))
 6957            })
 6958        }
 6959    }
 6960
 6961    pub fn applicable_inlay_chunks(
 6962        &mut self,
 6963        buffer: &Entity<Buffer>,
 6964        ranges: &[Range<text::Anchor>],
 6965        cx: &mut Context<Self>,
 6966    ) -> Vec<Range<BufferRow>> {
 6967        let buffer_snapshot = buffer.read(cx).snapshot();
 6968        let ranges = ranges
 6969            .iter()
 6970            .map(|range| range.to_point(&buffer_snapshot))
 6971            .collect::<Vec<_>>();
 6972
 6973        self.latest_lsp_data(buffer, cx)
 6974            .inlay_hints
 6975            .applicable_chunks(ranges.as_slice())
 6976            .map(|chunk| chunk.row_range())
 6977            .collect()
 6978    }
 6979
 6980    pub fn invalidate_inlay_hints<'a>(
 6981        &'a mut self,
 6982        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6983    ) {
 6984        for buffer_id in for_buffers {
 6985            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6986                lsp_data.inlay_hints.clear();
 6987            }
 6988        }
 6989    }
 6990
 6991    pub fn inlay_hints(
 6992        &mut self,
 6993        invalidate: InvalidationStrategy,
 6994        buffer: Entity<Buffer>,
 6995        ranges: Vec<Range<text::Anchor>>,
 6996        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6997        cx: &mut Context<Self>,
 6998    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6999        let next_hint_id = self.next_hint_id.clone();
 7000        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7001        let query_version = lsp_data.buffer_version.clone();
 7002        let mut lsp_refresh_requested = false;
 7003        let for_server = if let InvalidationStrategy::RefreshRequested {
 7004            server_id,
 7005            request_id,
 7006        } = invalidate
 7007        {
 7008            let invalidated = lsp_data
 7009                .inlay_hints
 7010                .invalidate_for_server_refresh(server_id, request_id);
 7011            lsp_refresh_requested = invalidated;
 7012            Some(server_id)
 7013        } else {
 7014            None
 7015        };
 7016        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7017        let known_chunks = known_chunks
 7018            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7019            .map(|(_, known_chunks)| known_chunks)
 7020            .unwrap_or_default();
 7021
 7022        let buffer_snapshot = buffer.read(cx).snapshot();
 7023        let ranges = ranges
 7024            .iter()
 7025            .map(|range| range.to_point(&buffer_snapshot))
 7026            .collect::<Vec<_>>();
 7027
 7028        let mut hint_fetch_tasks = Vec::new();
 7029        let mut cached_inlay_hints = None;
 7030        let mut ranges_to_query = None;
 7031        let applicable_chunks = existing_inlay_hints
 7032            .applicable_chunks(ranges.as_slice())
 7033            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7034            .collect::<Vec<_>>();
 7035        if applicable_chunks.is_empty() {
 7036            return HashMap::default();
 7037        }
 7038
 7039        for row_chunk in applicable_chunks {
 7040            match (
 7041                existing_inlay_hints
 7042                    .cached_hints(&row_chunk)
 7043                    .filter(|_| !lsp_refresh_requested)
 7044                    .cloned(),
 7045                existing_inlay_hints
 7046                    .fetched_hints(&row_chunk)
 7047                    .as_ref()
 7048                    .filter(|_| !lsp_refresh_requested)
 7049                    .cloned(),
 7050            ) {
 7051                (None, None) => {
 7052                    let chunk_range = row_chunk.anchor_range();
 7053                    ranges_to_query
 7054                        .get_or_insert_with(Vec::new)
 7055                        .push((row_chunk, chunk_range));
 7056                }
 7057                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7058                (Some(cached_hints), None) => {
 7059                    for (server_id, cached_hints) in cached_hints {
 7060                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7061                            cached_inlay_hints
 7062                                .get_or_insert_with(HashMap::default)
 7063                                .entry(row_chunk.row_range())
 7064                                .or_insert_with(HashMap::default)
 7065                                .entry(server_id)
 7066                                .or_insert_with(Vec::new)
 7067                                .extend(cached_hints);
 7068                        }
 7069                    }
 7070                }
 7071                (Some(cached_hints), Some(fetched_hints)) => {
 7072                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7073                    for (server_id, cached_hints) in cached_hints {
 7074                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7075                            cached_inlay_hints
 7076                                .get_or_insert_with(HashMap::default)
 7077                                .entry(row_chunk.row_range())
 7078                                .or_insert_with(HashMap::default)
 7079                                .entry(server_id)
 7080                                .or_insert_with(Vec::new)
 7081                                .extend(cached_hints);
 7082                        }
 7083                    }
 7084                }
 7085            }
 7086        }
 7087
 7088        if hint_fetch_tasks.is_empty()
 7089            && ranges_to_query
 7090                .as_ref()
 7091                .is_none_or(|ranges| ranges.is_empty())
 7092            && let Some(cached_inlay_hints) = cached_inlay_hints
 7093        {
 7094            cached_inlay_hints
 7095                .into_iter()
 7096                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7097                .collect()
 7098        } else {
 7099            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7100                // When a server refresh was requested, other servers' cached hints
 7101                // are unaffected by the refresh and must be included in the result.
 7102                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7103                // removes all visible hints but only adds back the requesting
 7104                // server's new hints, permanently losing other servers' hints.
 7105                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7106                    lsp_data
 7107                        .inlay_hints
 7108                        .cached_hints(&chunk)
 7109                        .cloned()
 7110                        .unwrap_or_default()
 7111                } else {
 7112                    HashMap::default()
 7113                };
 7114
 7115                let next_hint_id = next_hint_id.clone();
 7116                let buffer = buffer.clone();
 7117                let query_version = query_version.clone();
 7118                let new_inlay_hints = cx
 7119                    .spawn(async move |lsp_store, cx| {
 7120                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7121                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7122                        })?;
 7123                        new_fetch_task
 7124                            .await
 7125                            .and_then(|new_hints_by_server| {
 7126                                lsp_store.update(cx, |lsp_store, cx| {
 7127                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7128                                    let update_cache = lsp_data.buffer_version == query_version;
 7129                                    if new_hints_by_server.is_empty() {
 7130                                        if update_cache {
 7131                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7132                                        }
 7133                                        other_servers_cached
 7134                                    } else {
 7135                                        let mut result = other_servers_cached;
 7136                                        for (server_id, new_hints) in new_hints_by_server {
 7137                                            let new_hints = new_hints
 7138                                                .into_iter()
 7139                                                .map(|new_hint| {
 7140                                                    (
 7141                                                        InlayId::Hint(next_hint_id.fetch_add(
 7142                                                            1,
 7143                                                            atomic::Ordering::AcqRel,
 7144                                                        )),
 7145                                                        new_hint,
 7146                                                    )
 7147                                                })
 7148                                                .collect::<Vec<_>>();
 7149                                            if update_cache {
 7150                                                lsp_data.inlay_hints.insert_new_hints(
 7151                                                    chunk,
 7152                                                    server_id,
 7153                                                    new_hints.clone(),
 7154                                                );
 7155                                            }
 7156                                            result.insert(server_id, new_hints);
 7157                                        }
 7158                                        result
 7159                                    }
 7160                                })
 7161                            })
 7162                            .map_err(Arc::new)
 7163                    })
 7164                    .shared();
 7165
 7166                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7167                *fetch_task = Some(new_inlay_hints.clone());
 7168                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7169            }
 7170
 7171            cached_inlay_hints
 7172                .unwrap_or_default()
 7173                .into_iter()
 7174                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7175                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7176                    (
 7177                        chunk.row_range(),
 7178                        cx.spawn(async move |_, _| {
 7179                            hints_fetch.await.map_err(|e| {
 7180                                if e.error_code() != ErrorCode::Internal {
 7181                                    anyhow!(e.error_code())
 7182                                } else {
 7183                                    anyhow!("{e:#}")
 7184                                }
 7185                            })
 7186                        }),
 7187                    )
 7188                }))
 7189                .collect()
 7190        }
 7191    }
 7192
 7193    fn fetch_inlay_hints(
 7194        &mut self,
 7195        for_server: Option<LanguageServerId>,
 7196        buffer: &Entity<Buffer>,
 7197        range: Range<Anchor>,
 7198        cx: &mut Context<Self>,
 7199    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7200        let request = InlayHints {
 7201            range: range.clone(),
 7202        };
 7203        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7204            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7205                return Task::ready(Ok(HashMap::default()));
 7206            }
 7207            let request_timeout = ProjectSettings::get_global(cx)
 7208                .global_lsp_settings
 7209                .get_request_timeout();
 7210            let request_task = upstream_client.request_lsp(
 7211                project_id,
 7212                for_server.map(|id| id.to_proto()),
 7213                request_timeout,
 7214                cx.background_executor().clone(),
 7215                request.to_proto(project_id, buffer.read(cx)),
 7216            );
 7217            let buffer = buffer.clone();
 7218            cx.spawn(async move |weak_lsp_store, cx| {
 7219                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7220                    return Ok(HashMap::default());
 7221                };
 7222                let Some(responses) = request_task.await? else {
 7223                    return Ok(HashMap::default());
 7224                };
 7225
 7226                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7227                    let lsp_store = lsp_store.clone();
 7228                    let buffer = buffer.clone();
 7229                    let cx = cx.clone();
 7230                    let request = request.clone();
 7231                    async move {
 7232                        (
 7233                            LanguageServerId::from_proto(response.server_id),
 7234                            request
 7235                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7236                                .await,
 7237                        )
 7238                    }
 7239                }))
 7240                .await;
 7241
 7242                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7243                let mut has_errors = false;
 7244                let inlay_hints = inlay_hints
 7245                    .into_iter()
 7246                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7247                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7248                        Err(e) => {
 7249                            has_errors = true;
 7250                            log::error!("{e:#}");
 7251                            None
 7252                        }
 7253                    })
 7254                    .map(|(server_id, mut new_hints)| {
 7255                        new_hints.retain(|hint| {
 7256                            hint.position.is_valid(&buffer_snapshot)
 7257                                && range.start.is_valid(&buffer_snapshot)
 7258                                && range.end.is_valid(&buffer_snapshot)
 7259                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7260                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7261                        });
 7262                        (server_id, new_hints)
 7263                    })
 7264                    .collect::<HashMap<_, _>>();
 7265                anyhow::ensure!(
 7266                    !has_errors || !inlay_hints.is_empty(),
 7267                    "Failed to fetch inlay hints"
 7268                );
 7269                Ok(inlay_hints)
 7270            })
 7271        } else {
 7272            let inlay_hints_task = match for_server {
 7273                Some(server_id) => {
 7274                    let server_task = self.request_lsp(
 7275                        buffer.clone(),
 7276                        LanguageServerToQuery::Other(server_id),
 7277                        request,
 7278                        cx,
 7279                    );
 7280                    cx.background_spawn(async move {
 7281                        let mut responses = Vec::new();
 7282                        match server_task.await {
 7283                            Ok(response) => responses.push((server_id, response)),
 7284                            // rust-analyzer likes to error with this when its still loading up
 7285                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7286                            Err(e) => log::error!(
 7287                                "Error handling response for inlay hints request: {e:#}"
 7288                            ),
 7289                        }
 7290                        responses
 7291                    })
 7292                }
 7293                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7294            };
 7295            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7296            cx.background_spawn(async move {
 7297                Ok(inlay_hints_task
 7298                    .await
 7299                    .into_iter()
 7300                    .map(|(server_id, mut new_hints)| {
 7301                        new_hints.retain(|hint| {
 7302                            hint.position.is_valid(&buffer_snapshot)
 7303                                && range.start.is_valid(&buffer_snapshot)
 7304                                && range.end.is_valid(&buffer_snapshot)
 7305                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7306                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7307                        });
 7308                        (server_id, new_hints)
 7309                    })
 7310                    .collect())
 7311            })
 7312        }
 7313    }
 7314
 7315    fn diagnostic_registration_exists(
 7316        &self,
 7317        server_id: LanguageServerId,
 7318        registration_id: &Option<SharedString>,
 7319    ) -> bool {
 7320        let Some(local) = self.as_local() else {
 7321            return false;
 7322        };
 7323        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7324        else {
 7325            return false;
 7326        };
 7327        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7328        registrations.diagnostics.contains_key(&registration_key)
 7329    }
 7330
 7331    pub fn pull_diagnostics_for_buffer(
 7332        &mut self,
 7333        buffer: Entity<Buffer>,
 7334        cx: &mut Context<Self>,
 7335    ) -> Task<anyhow::Result<()>> {
 7336        let diagnostics = self.pull_diagnostics(buffer, cx);
 7337        cx.spawn(async move |lsp_store, cx| {
 7338            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7339                return Ok(());
 7340            };
 7341            lsp_store.update(cx, |lsp_store, cx| {
 7342                if lsp_store.as_local().is_none() {
 7343                    return;
 7344                }
 7345
 7346                let mut unchanged_buffers = HashMap::default();
 7347                let server_diagnostics_updates = diagnostics
 7348                    .into_iter()
 7349                    .filter_map(|diagnostics_set| match diagnostics_set {
 7350                        LspPullDiagnostics::Response {
 7351                            server_id,
 7352                            uri,
 7353                            diagnostics,
 7354                            registration_id,
 7355                        } => Some((server_id, uri, diagnostics, registration_id)),
 7356                        LspPullDiagnostics::Default => None,
 7357                    })
 7358                    .filter(|(server_id, _, _, registration_id)| {
 7359                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7360                    })
 7361                    .fold(
 7362                        HashMap::default(),
 7363                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7364                            let (result_id, diagnostics) = match diagnostics {
 7365                                PulledDiagnostics::Unchanged { result_id } => {
 7366                                    unchanged_buffers
 7367                                        .entry(new_registration_id.clone())
 7368                                        .or_insert_with(HashSet::default)
 7369                                        .insert(uri.clone());
 7370                                    (Some(result_id), Vec::new())
 7371                                }
 7372                                PulledDiagnostics::Changed {
 7373                                    result_id,
 7374                                    diagnostics,
 7375                                } => (result_id, diagnostics),
 7376                            };
 7377                            let disk_based_sources = Cow::Owned(
 7378                                lsp_store
 7379                                    .language_server_adapter_for_id(server_id)
 7380                                    .as_ref()
 7381                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7382                                    .unwrap_or(&[])
 7383                                    .to_vec(),
 7384                            );
 7385                            acc.entry(server_id)
 7386                                .or_insert_with(HashMap::default)
 7387                                .entry(new_registration_id.clone())
 7388                                .or_insert_with(Vec::new)
 7389                                .push(DocumentDiagnosticsUpdate {
 7390                                    server_id,
 7391                                    diagnostics: lsp::PublishDiagnosticsParams {
 7392                                        uri,
 7393                                        diagnostics,
 7394                                        version: None,
 7395                                    },
 7396                                    result_id: result_id.map(SharedString::new),
 7397                                    disk_based_sources,
 7398                                    registration_id: new_registration_id,
 7399                                });
 7400                            acc
 7401                        },
 7402                    );
 7403
 7404                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7405                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7406                        lsp_store
 7407                            .merge_lsp_diagnostics(
 7408                                DiagnosticSourceKind::Pulled,
 7409                                diagnostic_updates,
 7410                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7411                                    DiagnosticSourceKind::Pulled => {
 7412                                        old_diagnostic.registration_id != registration_id
 7413                                            || unchanged_buffers
 7414                                                .get(&old_diagnostic.registration_id)
 7415                                                .is_some_and(|unchanged_buffers| {
 7416                                                    unchanged_buffers.contains(&document_uri)
 7417                                                })
 7418                                    }
 7419                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7420                                        true
 7421                                    }
 7422                                },
 7423                                cx,
 7424                            )
 7425                            .log_err();
 7426                    }
 7427                }
 7428            })
 7429        })
 7430    }
 7431
 7432    pub fn signature_help<T: ToPointUtf16>(
 7433        &mut self,
 7434        buffer: &Entity<Buffer>,
 7435        position: T,
 7436        cx: &mut Context<Self>,
 7437    ) -> Task<Option<Vec<SignatureHelp>>> {
 7438        let position = position.to_point_utf16(buffer.read(cx));
 7439
 7440        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7441            let request = GetSignatureHelp { position };
 7442            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7443                return Task::ready(None);
 7444            }
 7445            let request_timeout = ProjectSettings::get_global(cx)
 7446                .global_lsp_settings
 7447                .get_request_timeout();
 7448            let request_task = client.request_lsp(
 7449                upstream_project_id,
 7450                None,
 7451                request_timeout,
 7452                cx.background_executor().clone(),
 7453                request.to_proto(upstream_project_id, buffer.read(cx)),
 7454            );
 7455            let buffer = buffer.clone();
 7456            cx.spawn(async move |weak_lsp_store, cx| {
 7457                let lsp_store = weak_lsp_store.upgrade()?;
 7458                let signatures = join_all(
 7459                    request_task
 7460                        .await
 7461                        .log_err()
 7462                        .flatten()
 7463                        .map(|response| response.payload)
 7464                        .unwrap_or_default()
 7465                        .into_iter()
 7466                        .map(|response| {
 7467                            let response = GetSignatureHelp { position }.response_from_proto(
 7468                                response.response,
 7469                                lsp_store.clone(),
 7470                                buffer.clone(),
 7471                                cx.clone(),
 7472                            );
 7473                            async move { response.await.log_err().flatten() }
 7474                        }),
 7475                )
 7476                .await
 7477                .into_iter()
 7478                .flatten()
 7479                .collect();
 7480                Some(signatures)
 7481            })
 7482        } else {
 7483            let all_actions_task = self.request_multiple_lsp_locally(
 7484                buffer,
 7485                Some(position),
 7486                GetSignatureHelp { position },
 7487                cx,
 7488            );
 7489            cx.background_spawn(async move {
 7490                Some(
 7491                    all_actions_task
 7492                        .await
 7493                        .into_iter()
 7494                        .flat_map(|(_, actions)| actions)
 7495                        .collect::<Vec<_>>(),
 7496                )
 7497            })
 7498        }
 7499    }
 7500
 7501    pub fn hover(
 7502        &mut self,
 7503        buffer: &Entity<Buffer>,
 7504        position: PointUtf16,
 7505        cx: &mut Context<Self>,
 7506    ) -> Task<Option<Vec<Hover>>> {
 7507        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7508            let request = GetHover { position };
 7509            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7510                return Task::ready(None);
 7511            }
 7512            let request_timeout = ProjectSettings::get_global(cx)
 7513                .global_lsp_settings
 7514                .get_request_timeout();
 7515            let request_task = client.request_lsp(
 7516                upstream_project_id,
 7517                None,
 7518                request_timeout,
 7519                cx.background_executor().clone(),
 7520                request.to_proto(upstream_project_id, buffer.read(cx)),
 7521            );
 7522            let buffer = buffer.clone();
 7523            cx.spawn(async move |weak_lsp_store, cx| {
 7524                let lsp_store = weak_lsp_store.upgrade()?;
 7525                let hovers = join_all(
 7526                    request_task
 7527                        .await
 7528                        .log_err()
 7529                        .flatten()
 7530                        .map(|response| response.payload)
 7531                        .unwrap_or_default()
 7532                        .into_iter()
 7533                        .map(|response| {
 7534                            let response = GetHover { position }.response_from_proto(
 7535                                response.response,
 7536                                lsp_store.clone(),
 7537                                buffer.clone(),
 7538                                cx.clone(),
 7539                            );
 7540                            async move {
 7541                                response
 7542                                    .await
 7543                                    .log_err()
 7544                                    .flatten()
 7545                                    .and_then(remove_empty_hover_blocks)
 7546                            }
 7547                        }),
 7548                )
 7549                .await
 7550                .into_iter()
 7551                .flatten()
 7552                .collect();
 7553                Some(hovers)
 7554            })
 7555        } else {
 7556            let all_actions_task = self.request_multiple_lsp_locally(
 7557                buffer,
 7558                Some(position),
 7559                GetHover { position },
 7560                cx,
 7561            );
 7562            cx.background_spawn(async move {
 7563                Some(
 7564                    all_actions_task
 7565                        .await
 7566                        .into_iter()
 7567                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7568                        .collect::<Vec<Hover>>(),
 7569                )
 7570            })
 7571        }
 7572    }
 7573
 7574    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7575        let language_registry = self.languages.clone();
 7576
 7577        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7578            let request = upstream_client.request(proto::GetProjectSymbols {
 7579                project_id: *project_id,
 7580                query: query.to_string(),
 7581            });
 7582            cx.foreground_executor().spawn(async move {
 7583                let response = request.await?;
 7584                let mut symbols = Vec::new();
 7585                let core_symbols = response
 7586                    .symbols
 7587                    .into_iter()
 7588                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7589                    .collect::<Vec<_>>();
 7590                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7591                    .await;
 7592                Ok(symbols)
 7593            })
 7594        } else if let Some(local) = self.as_local() {
 7595            struct WorkspaceSymbolsResult {
 7596                server_id: LanguageServerId,
 7597                lsp_adapter: Arc<CachedLspAdapter>,
 7598                worktree: WeakEntity<Worktree>,
 7599                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7600            }
 7601
 7602            let mut requests = Vec::new();
 7603            let mut requested_servers = BTreeSet::new();
 7604            let request_timeout = ProjectSettings::get_global(cx)
 7605                .global_lsp_settings
 7606                .get_request_timeout();
 7607
 7608            for (seed, state) in local.language_server_ids.iter() {
 7609                let Some(worktree_handle) = self
 7610                    .worktree_store
 7611                    .read(cx)
 7612                    .worktree_for_id(seed.worktree_id, cx)
 7613                else {
 7614                    continue;
 7615                };
 7616
 7617                let worktree = worktree_handle.read(cx);
 7618                if !worktree.is_visible() {
 7619                    continue;
 7620                }
 7621
 7622                if !requested_servers.insert(state.id) {
 7623                    continue;
 7624                }
 7625
 7626                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7627                    Some(LanguageServerState::Running {
 7628                        adapter, server, ..
 7629                    }) => (adapter.clone(), server),
 7630
 7631                    _ => continue,
 7632                };
 7633
 7634                let supports_workspace_symbol_request =
 7635                    match server.capabilities().workspace_symbol_provider {
 7636                        Some(OneOf::Left(supported)) => supported,
 7637                        Some(OneOf::Right(_)) => true,
 7638                        None => false,
 7639                    };
 7640
 7641                if !supports_workspace_symbol_request {
 7642                    continue;
 7643                }
 7644
 7645                let worktree_handle = worktree_handle.clone();
 7646                let server_id = server.server_id();
 7647                requests.push(
 7648                    server
 7649                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7650                            lsp::WorkspaceSymbolParams {
 7651                                query: query.to_string(),
 7652                                ..Default::default()
 7653                            },
 7654                            request_timeout,
 7655                        )
 7656                        .map(move |response| {
 7657                            let lsp_symbols = response
 7658                                .into_response()
 7659                                .context("workspace symbols request")
 7660                                .log_err()
 7661                                .flatten()
 7662                                .map(|symbol_response| match symbol_response {
 7663                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7664                                        flat_responses
 7665                                            .into_iter()
 7666                                            .map(|lsp_symbol| {
 7667                                                (
 7668                                                    lsp_symbol.name,
 7669                                                    lsp_symbol.kind,
 7670                                                    lsp_symbol.location,
 7671                                                    lsp_symbol.container_name,
 7672                                                )
 7673                                            })
 7674                                            .collect::<Vec<_>>()
 7675                                    }
 7676                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7677                                        nested_responses
 7678                                            .into_iter()
 7679                                            .filter_map(|lsp_symbol| {
 7680                                                let location = match lsp_symbol.location {
 7681                                                    OneOf::Left(location) => location,
 7682                                                    OneOf::Right(_) => {
 7683                                                        log::error!(
 7684                                                            "Unexpected: client capabilities \
 7685                                                            forbid symbol resolutions in \
 7686                                                            workspace.symbol.resolveSupport"
 7687                                                        );
 7688                                                        return None;
 7689                                                    }
 7690                                                };
 7691                                                Some((
 7692                                                    lsp_symbol.name,
 7693                                                    lsp_symbol.kind,
 7694                                                    location,
 7695                                                    lsp_symbol.container_name,
 7696                                                ))
 7697                                            })
 7698                                            .collect::<Vec<_>>()
 7699                                    }
 7700                                })
 7701                                .unwrap_or_default();
 7702
 7703                            WorkspaceSymbolsResult {
 7704                                server_id,
 7705                                lsp_adapter,
 7706                                worktree: worktree_handle.downgrade(),
 7707                                lsp_symbols,
 7708                            }
 7709                        }),
 7710                );
 7711            }
 7712
 7713            cx.spawn(async move |this, cx| {
 7714                let responses = futures::future::join_all(requests).await;
 7715                let this = match this.upgrade() {
 7716                    Some(this) => this,
 7717                    None => return Ok(Vec::new()),
 7718                };
 7719
 7720                let mut symbols = Vec::new();
 7721                for result in responses {
 7722                    let core_symbols = this.update(cx, |this, cx| {
 7723                        result
 7724                            .lsp_symbols
 7725                            .into_iter()
 7726                            .filter_map(
 7727                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7728                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7729                                    let source_worktree = result.worktree.upgrade()?;
 7730                                    let source_worktree_id = source_worktree.read(cx).id();
 7731
 7732                                    let path = if let Some((tree, rel_path)) =
 7733                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7734                                    {
 7735                                        let worktree_id = tree.read(cx).id();
 7736                                        SymbolLocation::InProject(ProjectPath {
 7737                                            worktree_id,
 7738                                            path: rel_path,
 7739                                        })
 7740                                    } else {
 7741                                        SymbolLocation::OutsideProject {
 7742                                            signature: this.symbol_signature(&abs_path),
 7743                                            abs_path: abs_path.into(),
 7744                                        }
 7745                                    };
 7746
 7747                                    Some(CoreSymbol {
 7748                                        source_language_server_id: result.server_id,
 7749                                        language_server_name: result.lsp_adapter.name.clone(),
 7750                                        source_worktree_id,
 7751                                        path,
 7752                                        kind: symbol_kind,
 7753                                        name: collapse_newlines(&symbol_name, ""),
 7754                                        range: range_from_lsp(symbol_location.range),
 7755                                        container_name: container_name
 7756                                            .map(|c| collapse_newlines(&c, "")),
 7757                                    })
 7758                                },
 7759                            )
 7760                            .collect::<Vec<_>>()
 7761                    });
 7762
 7763                    populate_labels_for_symbols(
 7764                        core_symbols,
 7765                        &language_registry,
 7766                        Some(result.lsp_adapter),
 7767                        &mut symbols,
 7768                    )
 7769                    .await;
 7770                }
 7771
 7772                Ok(symbols)
 7773            })
 7774        } else {
 7775            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7776        }
 7777    }
 7778
 7779    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7780        let mut summary = DiagnosticSummary::default();
 7781        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7782            summary.error_count += path_summary.error_count;
 7783            summary.warning_count += path_summary.warning_count;
 7784        }
 7785        summary
 7786    }
 7787
 7788    /// Returns the diagnostic summary for a specific project path.
 7789    pub fn diagnostic_summary_for_path(
 7790        &self,
 7791        project_path: &ProjectPath,
 7792        _: &App,
 7793    ) -> DiagnosticSummary {
 7794        if let Some(summaries) = self
 7795            .diagnostic_summaries
 7796            .get(&project_path.worktree_id)
 7797            .and_then(|map| map.get(&project_path.path))
 7798        {
 7799            let (error_count, warning_count) = summaries.iter().fold(
 7800                (0, 0),
 7801                |(error_count, warning_count), (_language_server_id, summary)| {
 7802                    (
 7803                        error_count + summary.error_count,
 7804                        warning_count + summary.warning_count,
 7805                    )
 7806                },
 7807            );
 7808
 7809            DiagnosticSummary {
 7810                error_count,
 7811                warning_count,
 7812            }
 7813        } else {
 7814            DiagnosticSummary::default()
 7815        }
 7816    }
 7817
 7818    pub fn diagnostic_summaries<'a>(
 7819        &'a self,
 7820        include_ignored: bool,
 7821        cx: &'a App,
 7822    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7823        self.worktree_store
 7824            .read(cx)
 7825            .visible_worktrees(cx)
 7826            .filter_map(|worktree| {
 7827                let worktree = worktree.read(cx);
 7828                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7829            })
 7830            .flat_map(move |(worktree, summaries)| {
 7831                let worktree_id = worktree.id();
 7832                summaries
 7833                    .iter()
 7834                    .filter(move |(path, _)| {
 7835                        include_ignored
 7836                            || worktree
 7837                                .entry_for_path(path.as_ref())
 7838                                .is_some_and(|entry| !entry.is_ignored)
 7839                    })
 7840                    .flat_map(move |(path, summaries)| {
 7841                        summaries.iter().map(move |(server_id, summary)| {
 7842                            (
 7843                                ProjectPath {
 7844                                    worktree_id,
 7845                                    path: path.clone(),
 7846                                },
 7847                                *server_id,
 7848                                *summary,
 7849                            )
 7850                        })
 7851                    })
 7852            })
 7853    }
 7854
 7855    pub fn on_buffer_edited(
 7856        &mut self,
 7857        buffer: Entity<Buffer>,
 7858        cx: &mut Context<Self>,
 7859    ) -> Option<()> {
 7860        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7861            Some(
 7862                self.as_local()?
 7863                    .language_servers_for_buffer(buffer, cx)
 7864                    .map(|i| i.1.clone())
 7865                    .collect(),
 7866            )
 7867        })?;
 7868
 7869        let buffer = buffer.read(cx);
 7870        let file = File::from_dyn(buffer.file())?;
 7871        let abs_path = file.as_local()?.abs_path(cx);
 7872        let uri = lsp::Uri::from_file_path(&abs_path)
 7873            .ok()
 7874            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7875            .log_err()?;
 7876        let next_snapshot = buffer.text_snapshot();
 7877        for language_server in language_servers {
 7878            let language_server = language_server.clone();
 7879
 7880            let buffer_snapshots = self
 7881                .as_local_mut()?
 7882                .buffer_snapshots
 7883                .get_mut(&buffer.remote_id())
 7884                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7885            let previous_snapshot = buffer_snapshots.last()?;
 7886
 7887            let build_incremental_change = || {
 7888                buffer
 7889                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7890                        previous_snapshot.snapshot.version(),
 7891                    )
 7892                    .map(|edit| {
 7893                        let edit_start = edit.new.start.0;
 7894                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7895                        let new_text = next_snapshot
 7896                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7897                            .collect();
 7898                        lsp::TextDocumentContentChangeEvent {
 7899                            range: Some(lsp::Range::new(
 7900                                point_to_lsp(edit_start),
 7901                                point_to_lsp(edit_end),
 7902                            )),
 7903                            range_length: None,
 7904                            text: new_text,
 7905                        }
 7906                    })
 7907                    .collect()
 7908            };
 7909
 7910            let document_sync_kind = language_server
 7911                .capabilities()
 7912                .text_document_sync
 7913                .as_ref()
 7914                .and_then(|sync| match sync {
 7915                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7916                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7917                });
 7918
 7919            let content_changes: Vec<_> = match document_sync_kind {
 7920                Some(lsp::TextDocumentSyncKind::FULL) => {
 7921                    vec![lsp::TextDocumentContentChangeEvent {
 7922                        range: None,
 7923                        range_length: None,
 7924                        text: next_snapshot.text(),
 7925                    }]
 7926                }
 7927                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7928                _ => {
 7929                    #[cfg(any(test, feature = "test-support"))]
 7930                    {
 7931                        build_incremental_change()
 7932                    }
 7933
 7934                    #[cfg(not(any(test, feature = "test-support")))]
 7935                    {
 7936                        continue;
 7937                    }
 7938                }
 7939            };
 7940
 7941            let next_version = previous_snapshot.version + 1;
 7942            buffer_snapshots.push(LspBufferSnapshot {
 7943                version: next_version,
 7944                snapshot: next_snapshot.clone(),
 7945            });
 7946
 7947            language_server
 7948                .notify::<lsp::notification::DidChangeTextDocument>(
 7949                    lsp::DidChangeTextDocumentParams {
 7950                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7951                            uri.clone(),
 7952                            next_version,
 7953                        ),
 7954                        content_changes,
 7955                    },
 7956                )
 7957                .ok();
 7958            self.pull_workspace_diagnostics(language_server.server_id());
 7959        }
 7960
 7961        None
 7962    }
 7963
 7964    pub fn on_buffer_saved(
 7965        &mut self,
 7966        buffer: Entity<Buffer>,
 7967        cx: &mut Context<Self>,
 7968    ) -> Option<()> {
 7969        let file = File::from_dyn(buffer.read(cx).file())?;
 7970        let worktree_id = file.worktree_id(cx);
 7971        let abs_path = file.as_local()?.abs_path(cx);
 7972        let text_document = lsp::TextDocumentIdentifier {
 7973            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7974        };
 7975        let local = self.as_local()?;
 7976
 7977        for server in local.language_servers_for_worktree(worktree_id) {
 7978            if let Some(include_text) = include_text(server.as_ref()) {
 7979                let text = if include_text {
 7980                    Some(buffer.read(cx).text())
 7981                } else {
 7982                    None
 7983                };
 7984                server
 7985                    .notify::<lsp::notification::DidSaveTextDocument>(
 7986                        lsp::DidSaveTextDocumentParams {
 7987                            text_document: text_document.clone(),
 7988                            text,
 7989                        },
 7990                    )
 7991                    .ok();
 7992            }
 7993        }
 7994
 7995        let language_servers = buffer.update(cx, |buffer, cx| {
 7996            local.language_server_ids_for_buffer(buffer, cx)
 7997        });
 7998        for language_server_id in language_servers {
 7999            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8000        }
 8001
 8002        None
 8003    }
 8004
 8005    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8006        maybe!(async move {
 8007            let mut refreshed_servers = HashSet::default();
 8008            let servers = lsp_store
 8009                .update(cx, |lsp_store, cx| {
 8010                    let local = lsp_store.as_local()?;
 8011
 8012                    let servers = local
 8013                        .language_server_ids
 8014                        .iter()
 8015                        .filter_map(|(seed, state)| {
 8016                            let worktree = lsp_store
 8017                                .worktree_store
 8018                                .read(cx)
 8019                                .worktree_for_id(seed.worktree_id, cx);
 8020                            let delegate: Arc<dyn LspAdapterDelegate> =
 8021                                worktree.map(|worktree| {
 8022                                    LocalLspAdapterDelegate::new(
 8023                                        local.languages.clone(),
 8024                                        &local.environment,
 8025                                        cx.weak_entity(),
 8026                                        &worktree,
 8027                                        local.http_client.clone(),
 8028                                        local.fs.clone(),
 8029                                        cx,
 8030                                    )
 8031                                })?;
 8032                            let server_id = state.id;
 8033
 8034                            let states = local.language_servers.get(&server_id)?;
 8035
 8036                            match states {
 8037                                LanguageServerState::Starting { .. } => None,
 8038                                LanguageServerState::Running {
 8039                                    adapter, server, ..
 8040                                } => {
 8041                                    let adapter = adapter.clone();
 8042                                    let server = server.clone();
 8043                                    refreshed_servers.insert(server.name());
 8044                                    let toolchain = seed.toolchain.clone();
 8045                                    Some(cx.spawn(async move |_, cx| {
 8046                                        let settings =
 8047                                            LocalLspStore::workspace_configuration_for_adapter(
 8048                                                adapter.adapter.clone(),
 8049                                                &delegate,
 8050                                                toolchain,
 8051                                                None,
 8052                                                cx,
 8053                                            )
 8054                                            .await
 8055                                            .ok()?;
 8056                                        server
 8057                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8058                                                lsp::DidChangeConfigurationParams { settings },
 8059                                            )
 8060                                            .ok()?;
 8061                                        Some(())
 8062                                    }))
 8063                                }
 8064                            }
 8065                        })
 8066                        .collect::<Vec<_>>();
 8067
 8068                    Some(servers)
 8069                })
 8070                .ok()
 8071                .flatten()?;
 8072
 8073            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8074            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8075            // to stop and unregister its language server wrapper.
 8076            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8077            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8078            let _: Vec<Option<()>> = join_all(servers).await;
 8079
 8080            Some(())
 8081        })
 8082        .await;
 8083    }
 8084
 8085    fn maintain_workspace_config(
 8086        external_refresh_requests: watch::Receiver<()>,
 8087        cx: &mut Context<Self>,
 8088    ) -> Task<Result<()>> {
 8089        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8090        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8091
 8092        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8093            *settings_changed_tx.borrow_mut() = ();
 8094        });
 8095
 8096        let mut joint_future =
 8097            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8098        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8099        // - 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).
 8100        // - 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.
 8101        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8102        // - 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,
 8103        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8104        cx.spawn(async move |this, cx| {
 8105            while let Some(()) = joint_future.next().await {
 8106                this.update(cx, |this, cx| {
 8107                    this.refresh_server_tree(cx);
 8108                })
 8109                .ok();
 8110
 8111                Self::refresh_workspace_configurations(&this, cx).await;
 8112            }
 8113
 8114            drop(settings_observation);
 8115            anyhow::Ok(())
 8116        })
 8117    }
 8118
 8119    pub fn running_language_servers_for_local_buffer<'a>(
 8120        &'a self,
 8121        buffer: &Buffer,
 8122        cx: &mut App,
 8123    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8124        let local = self.as_local();
 8125        let language_server_ids = local
 8126            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8127            .unwrap_or_default();
 8128
 8129        language_server_ids
 8130            .into_iter()
 8131            .filter_map(
 8132                move |server_id| match local?.language_servers.get(&server_id)? {
 8133                    LanguageServerState::Running {
 8134                        adapter, server, ..
 8135                    } => Some((adapter, server)),
 8136                    _ => None,
 8137                },
 8138            )
 8139    }
 8140
 8141    pub fn language_servers_for_local_buffer(
 8142        &self,
 8143        buffer: &Buffer,
 8144        cx: &mut App,
 8145    ) -> Vec<LanguageServerId> {
 8146        let local = self.as_local();
 8147        local
 8148            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8149            .unwrap_or_default()
 8150    }
 8151
 8152    pub fn language_server_for_local_buffer<'a>(
 8153        &'a self,
 8154        buffer: &'a Buffer,
 8155        server_id: LanguageServerId,
 8156        cx: &'a mut App,
 8157    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8158        self.as_local()?
 8159            .language_servers_for_buffer(buffer, cx)
 8160            .find(|(_, s)| s.server_id() == server_id)
 8161    }
 8162
 8163    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8164        self.diagnostic_summaries.remove(&id_to_remove);
 8165        if let Some(local) = self.as_local_mut() {
 8166            let to_remove = local.remove_worktree(id_to_remove, cx);
 8167            for server in to_remove {
 8168                self.language_server_statuses.remove(&server);
 8169            }
 8170        }
 8171    }
 8172
 8173    pub fn shared(
 8174        &mut self,
 8175        project_id: u64,
 8176        downstream_client: AnyProtoClient,
 8177        _: &mut Context<Self>,
 8178    ) {
 8179        self.downstream_client = Some((downstream_client.clone(), project_id));
 8180
 8181        for (server_id, status) in &self.language_server_statuses {
 8182            if let Some(server) = self.language_server_for_id(*server_id) {
 8183                downstream_client
 8184                    .send(proto::StartLanguageServer {
 8185                        project_id,
 8186                        server: Some(proto::LanguageServer {
 8187                            id: server_id.to_proto(),
 8188                            name: status.name.to_string(),
 8189                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8190                        }),
 8191                        capabilities: serde_json::to_string(&server.capabilities())
 8192                            .expect("serializing server LSP capabilities"),
 8193                    })
 8194                    .log_err();
 8195            }
 8196        }
 8197    }
 8198
 8199    pub fn disconnected_from_host(&mut self) {
 8200        self.downstream_client.take();
 8201    }
 8202
 8203    pub fn disconnected_from_ssh_remote(&mut self) {
 8204        if let LspStoreMode::Remote(RemoteLspStore {
 8205            upstream_client, ..
 8206        }) = &mut self.mode
 8207        {
 8208            upstream_client.take();
 8209        }
 8210    }
 8211
 8212    pub(crate) fn set_language_server_statuses_from_proto(
 8213        &mut self,
 8214        project: WeakEntity<Project>,
 8215        language_servers: Vec<proto::LanguageServer>,
 8216        server_capabilities: Vec<String>,
 8217        cx: &mut Context<Self>,
 8218    ) {
 8219        let lsp_logs = cx
 8220            .try_global::<GlobalLogStore>()
 8221            .map(|lsp_store| lsp_store.0.clone());
 8222
 8223        self.language_server_statuses = language_servers
 8224            .into_iter()
 8225            .zip(server_capabilities)
 8226            .map(|(server, server_capabilities)| {
 8227                let server_id = LanguageServerId(server.id as usize);
 8228                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8229                    self.lsp_server_capabilities
 8230                        .insert(server_id, server_capabilities);
 8231                }
 8232
 8233                let name = LanguageServerName::from_proto(server.name);
 8234                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8235
 8236                if let Some(lsp_logs) = &lsp_logs {
 8237                    lsp_logs.update(cx, |lsp_logs, cx| {
 8238                        lsp_logs.add_language_server(
 8239                            // Only remote clients get their language servers set from proto
 8240                            LanguageServerKind::Remote {
 8241                                project: project.clone(),
 8242                            },
 8243                            server_id,
 8244                            Some(name.clone()),
 8245                            worktree,
 8246                            None,
 8247                            cx,
 8248                        );
 8249                    });
 8250                }
 8251
 8252                (
 8253                    server_id,
 8254                    LanguageServerStatus {
 8255                        name,
 8256                        server_version: None,
 8257                        pending_work: Default::default(),
 8258                        has_pending_diagnostic_updates: false,
 8259                        progress_tokens: Default::default(),
 8260                        worktree,
 8261                        binary: None,
 8262                        configuration: None,
 8263                        workspace_folders: BTreeSet::new(),
 8264                        process_id: None,
 8265                    },
 8266                )
 8267            })
 8268            .collect();
 8269    }
 8270
 8271    #[cfg(feature = "test-support")]
 8272    pub fn update_diagnostic_entries(
 8273        &mut self,
 8274        server_id: LanguageServerId,
 8275        abs_path: PathBuf,
 8276        result_id: Option<SharedString>,
 8277        version: Option<i32>,
 8278        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8279        cx: &mut Context<Self>,
 8280    ) -> anyhow::Result<()> {
 8281        self.merge_diagnostic_entries(
 8282            vec![DocumentDiagnosticsUpdate {
 8283                diagnostics: DocumentDiagnostics {
 8284                    diagnostics,
 8285                    document_abs_path: abs_path,
 8286                    version,
 8287                },
 8288                result_id,
 8289                server_id,
 8290                disk_based_sources: Cow::Borrowed(&[]),
 8291                registration_id: None,
 8292            }],
 8293            |_, _, _| false,
 8294            cx,
 8295        )?;
 8296        Ok(())
 8297    }
 8298
 8299    pub fn merge_diagnostic_entries<'a>(
 8300        &mut self,
 8301        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8302        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8303        cx: &mut Context<Self>,
 8304    ) -> anyhow::Result<()> {
 8305        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8306        let mut updated_diagnostics_paths = HashMap::default();
 8307        for mut update in diagnostic_updates {
 8308            let abs_path = &update.diagnostics.document_abs_path;
 8309            let server_id = update.server_id;
 8310            let Some((worktree, relative_path)) =
 8311                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8312            else {
 8313                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8314                return Ok(());
 8315            };
 8316
 8317            let worktree_id = worktree.read(cx).id();
 8318            let project_path = ProjectPath {
 8319                worktree_id,
 8320                path: relative_path,
 8321            };
 8322
 8323            let document_uri = lsp::Uri::from_file_path(abs_path)
 8324                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8325            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8326                let snapshot = buffer_handle.read(cx).snapshot();
 8327                let buffer = buffer_handle.read(cx);
 8328                let reused_diagnostics = buffer
 8329                    .buffer_diagnostics(Some(server_id))
 8330                    .iter()
 8331                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8332                    .map(|v| {
 8333                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8334                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8335                        DiagnosticEntry {
 8336                            range: start..end,
 8337                            diagnostic: v.diagnostic.clone(),
 8338                        }
 8339                    })
 8340                    .collect::<Vec<_>>();
 8341
 8342                self.as_local_mut()
 8343                    .context("cannot merge diagnostics on a remote LspStore")?
 8344                    .update_buffer_diagnostics(
 8345                        &buffer_handle,
 8346                        server_id,
 8347                        Some(update.registration_id),
 8348                        update.result_id,
 8349                        update.diagnostics.version,
 8350                        update.diagnostics.diagnostics.clone(),
 8351                        reused_diagnostics.clone(),
 8352                        cx,
 8353                    )?;
 8354
 8355                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8356            } else if let Some(local) = self.as_local() {
 8357                let reused_diagnostics = local
 8358                    .diagnostics
 8359                    .get(&worktree_id)
 8360                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8361                    .and_then(|diagnostics_by_server_id| {
 8362                        diagnostics_by_server_id
 8363                            .binary_search_by_key(&server_id, |e| e.0)
 8364                            .ok()
 8365                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8366                    })
 8367                    .into_iter()
 8368                    .flatten()
 8369                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8370
 8371                update
 8372                    .diagnostics
 8373                    .diagnostics
 8374                    .extend(reused_diagnostics.cloned());
 8375            }
 8376
 8377            let updated = worktree.update(cx, |worktree, cx| {
 8378                self.update_worktree_diagnostics(
 8379                    worktree.id(),
 8380                    server_id,
 8381                    project_path.path.clone(),
 8382                    update.diagnostics.diagnostics,
 8383                    cx,
 8384                )
 8385            })?;
 8386            match updated {
 8387                ControlFlow::Continue(new_summary) => {
 8388                    if let Some((project_id, new_summary)) = new_summary {
 8389                        match &mut diagnostics_summary {
 8390                            Some(diagnostics_summary) => {
 8391                                diagnostics_summary
 8392                                    .more_summaries
 8393                                    .push(proto::DiagnosticSummary {
 8394                                        path: project_path.path.as_ref().to_proto(),
 8395                                        language_server_id: server_id.0 as u64,
 8396                                        error_count: new_summary.error_count,
 8397                                        warning_count: new_summary.warning_count,
 8398                                    })
 8399                            }
 8400                            None => {
 8401                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8402                                    project_id,
 8403                                    worktree_id: worktree_id.to_proto(),
 8404                                    summary: Some(proto::DiagnosticSummary {
 8405                                        path: project_path.path.as_ref().to_proto(),
 8406                                        language_server_id: server_id.0 as u64,
 8407                                        error_count: new_summary.error_count,
 8408                                        warning_count: new_summary.warning_count,
 8409                                    }),
 8410                                    more_summaries: Vec::new(),
 8411                                })
 8412                            }
 8413                        }
 8414                    }
 8415                    updated_diagnostics_paths
 8416                        .entry(server_id)
 8417                        .or_insert_with(Vec::new)
 8418                        .push(project_path);
 8419                }
 8420                ControlFlow::Break(()) => {}
 8421            }
 8422        }
 8423
 8424        if let Some((diagnostics_summary, (downstream_client, _))) =
 8425            diagnostics_summary.zip(self.downstream_client.as_ref())
 8426        {
 8427            downstream_client.send(diagnostics_summary).log_err();
 8428        }
 8429        for (server_id, paths) in updated_diagnostics_paths {
 8430            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8431        }
 8432        Ok(())
 8433    }
 8434
 8435    fn update_worktree_diagnostics(
 8436        &mut self,
 8437        worktree_id: WorktreeId,
 8438        server_id: LanguageServerId,
 8439        path_in_worktree: Arc<RelPath>,
 8440        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8441        _: &mut Context<Worktree>,
 8442    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8443        let local = match &mut self.mode {
 8444            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8445            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8446        };
 8447
 8448        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8449        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8450        let summaries_by_server_id = summaries_for_tree
 8451            .entry(path_in_worktree.clone())
 8452            .or_default();
 8453
 8454        let old_summary = summaries_by_server_id
 8455            .remove(&server_id)
 8456            .unwrap_or_default();
 8457
 8458        let new_summary = DiagnosticSummary::new(&diagnostics);
 8459        if diagnostics.is_empty() {
 8460            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8461            {
 8462                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8463                    diagnostics_by_server_id.remove(ix);
 8464                }
 8465                if diagnostics_by_server_id.is_empty() {
 8466                    diagnostics_for_tree.remove(&path_in_worktree);
 8467                }
 8468            }
 8469        } else {
 8470            summaries_by_server_id.insert(server_id, new_summary);
 8471            let diagnostics_by_server_id = diagnostics_for_tree
 8472                .entry(path_in_worktree.clone())
 8473                .or_default();
 8474            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8475                Ok(ix) => {
 8476                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8477                }
 8478                Err(ix) => {
 8479                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8480                }
 8481            }
 8482        }
 8483
 8484        if !old_summary.is_empty() || !new_summary.is_empty() {
 8485            if let Some((_, project_id)) = &self.downstream_client {
 8486                Ok(ControlFlow::Continue(Some((
 8487                    *project_id,
 8488                    proto::DiagnosticSummary {
 8489                        path: path_in_worktree.to_proto(),
 8490                        language_server_id: server_id.0 as u64,
 8491                        error_count: new_summary.error_count as u32,
 8492                        warning_count: new_summary.warning_count as u32,
 8493                    },
 8494                ))))
 8495            } else {
 8496                Ok(ControlFlow::Continue(None))
 8497            }
 8498        } else {
 8499            Ok(ControlFlow::Break(()))
 8500        }
 8501    }
 8502
 8503    pub fn open_buffer_for_symbol(
 8504        &mut self,
 8505        symbol: &Symbol,
 8506        cx: &mut Context<Self>,
 8507    ) -> Task<Result<Entity<Buffer>>> {
 8508        if let Some((client, project_id)) = self.upstream_client() {
 8509            let request = client.request(proto::OpenBufferForSymbol {
 8510                project_id,
 8511                symbol: Some(Self::serialize_symbol(symbol)),
 8512            });
 8513            cx.spawn(async move |this, cx| {
 8514                let response = request.await?;
 8515                let buffer_id = BufferId::new(response.buffer_id)?;
 8516                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8517                    .await
 8518            })
 8519        } else if let Some(local) = self.as_local() {
 8520            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8521                seed.worktree_id == symbol.source_worktree_id
 8522                    && state.id == symbol.source_language_server_id
 8523                    && symbol.language_server_name == seed.name
 8524            });
 8525            if !is_valid {
 8526                return Task::ready(Err(anyhow!(
 8527                    "language server for worktree and language not found"
 8528                )));
 8529            };
 8530
 8531            let symbol_abs_path = match &symbol.path {
 8532                SymbolLocation::InProject(project_path) => self
 8533                    .worktree_store
 8534                    .read(cx)
 8535                    .absolutize(&project_path, cx)
 8536                    .context("no such worktree"),
 8537                SymbolLocation::OutsideProject {
 8538                    abs_path,
 8539                    signature: _,
 8540                } => Ok(abs_path.to_path_buf()),
 8541            };
 8542            let symbol_abs_path = match symbol_abs_path {
 8543                Ok(abs_path) => abs_path,
 8544                Err(err) => return Task::ready(Err(err)),
 8545            };
 8546            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8547                uri
 8548            } else {
 8549                return Task::ready(Err(anyhow!("invalid symbol path")));
 8550            };
 8551
 8552            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8553        } else {
 8554            Task::ready(Err(anyhow!("no upstream client or local store")))
 8555        }
 8556    }
 8557
 8558    pub(crate) fn open_local_buffer_via_lsp(
 8559        &mut self,
 8560        abs_path: lsp::Uri,
 8561        language_server_id: LanguageServerId,
 8562        cx: &mut Context<Self>,
 8563    ) -> Task<Result<Entity<Buffer>>> {
 8564        let path_style = self.worktree_store.read(cx).path_style();
 8565        cx.spawn(async move |lsp_store, cx| {
 8566            // Escape percent-encoded string.
 8567            let current_scheme = abs_path.scheme().to_owned();
 8568            // Uri is immutable, so we can't modify the scheme
 8569
 8570            let abs_path = abs_path
 8571                .to_file_path_ext(path_style)
 8572                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8573            let p = abs_path.clone();
 8574            let yarn_worktree = lsp_store
 8575                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8576                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8577                        cx.spawn(async move |this, cx| {
 8578                            let t = this
 8579                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8580                                .ok()?;
 8581                            t.await
 8582                        })
 8583                    }),
 8584                    None => Task::ready(None),
 8585                })?
 8586                .await;
 8587            let (worktree_root_target, known_relative_path) =
 8588                if let Some((zip_root, relative_path)) = yarn_worktree {
 8589                    (zip_root, Some(relative_path))
 8590                } else {
 8591                    (Arc::<Path>::from(abs_path.as_path()), None)
 8592                };
 8593            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8594                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8595                    worktree_store.find_worktree(&worktree_root_target, cx)
 8596                })
 8597            })?;
 8598            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8599                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8600                (result.0, relative_path, None)
 8601            } else {
 8602                let worktree = lsp_store
 8603                    .update(cx, |lsp_store, cx| {
 8604                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8605                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8606                        })
 8607                    })?
 8608                    .await?;
 8609                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8610                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8611                    lsp_store
 8612                        .update(cx, |lsp_store, cx| {
 8613                            if let Some(local) = lsp_store.as_local_mut() {
 8614                                local.register_language_server_for_invisible_worktree(
 8615                                    &worktree,
 8616                                    language_server_id,
 8617                                    cx,
 8618                                )
 8619                            }
 8620                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8621                                Some(status) => status.worktree,
 8622                                None => None,
 8623                            }
 8624                        })
 8625                        .ok()
 8626                        .flatten()
 8627                        .zip(Some(worktree_root.clone()))
 8628                } else {
 8629                    None
 8630                };
 8631                let relative_path = if let Some(known_path) = known_relative_path {
 8632                    known_path
 8633                } else {
 8634                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8635                        .into_arc()
 8636                };
 8637                (worktree, relative_path, source_ws)
 8638            };
 8639            let project_path = ProjectPath {
 8640                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8641                path: relative_path,
 8642            };
 8643            let buffer = lsp_store
 8644                .update(cx, |lsp_store, cx| {
 8645                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8646                        buffer_store.open_buffer(project_path, cx)
 8647                    })
 8648                })?
 8649                .await?;
 8650            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8651            if let Some((source_ws, worktree_root)) = source_ws {
 8652                buffer.update(cx, |buffer, cx| {
 8653                    let settings = WorktreeSettings::get(
 8654                        Some(
 8655                            (&ProjectPath {
 8656                                worktree_id: source_ws,
 8657                                path: Arc::from(RelPath::empty()),
 8658                            })
 8659                                .into(),
 8660                        ),
 8661                        cx,
 8662                    );
 8663                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8664                    if is_read_only {
 8665                        buffer.set_capability(Capability::ReadOnly, cx);
 8666                    }
 8667                });
 8668            }
 8669            Ok(buffer)
 8670        })
 8671    }
 8672
 8673    fn local_lsp_servers_for_buffer(
 8674        &self,
 8675        buffer: &Entity<Buffer>,
 8676        cx: &mut Context<Self>,
 8677    ) -> Vec<LanguageServerId> {
 8678        let Some(local) = self.as_local() else {
 8679            return Vec::new();
 8680        };
 8681
 8682        let snapshot = buffer.read(cx).snapshot();
 8683
 8684        buffer.update(cx, |buffer, cx| {
 8685            local
 8686                .language_servers_for_buffer(buffer, cx)
 8687                .map(|(_, server)| server.server_id())
 8688                .filter(|server_id| {
 8689                    self.as_local().is_none_or(|local| {
 8690                        local
 8691                            .buffers_opened_in_servers
 8692                            .get(&snapshot.remote_id())
 8693                            .is_some_and(|servers| servers.contains(server_id))
 8694                    })
 8695                })
 8696                .collect()
 8697        })
 8698    }
 8699
 8700    fn request_multiple_lsp_locally<P, R>(
 8701        &mut self,
 8702        buffer: &Entity<Buffer>,
 8703        position: Option<P>,
 8704        request: R,
 8705        cx: &mut Context<Self>,
 8706    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8707    where
 8708        P: ToOffset,
 8709        R: LspCommand + Clone,
 8710        <R::LspRequest as lsp::request::Request>::Result: Send,
 8711        <R::LspRequest as lsp::request::Request>::Params: Send,
 8712    {
 8713        let Some(local) = self.as_local() else {
 8714            return Task::ready(Vec::new());
 8715        };
 8716
 8717        let snapshot = buffer.read(cx).snapshot();
 8718        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8719
 8720        let server_ids = buffer.update(cx, |buffer, cx| {
 8721            local
 8722                .language_servers_for_buffer(buffer, cx)
 8723                .filter(|(adapter, _)| {
 8724                    scope
 8725                        .as_ref()
 8726                        .map(|scope| scope.language_allowed(&adapter.name))
 8727                        .unwrap_or(true)
 8728                })
 8729                .map(|(_, server)| server.server_id())
 8730                .filter(|server_id| {
 8731                    self.as_local().is_none_or(|local| {
 8732                        local
 8733                            .buffers_opened_in_servers
 8734                            .get(&snapshot.remote_id())
 8735                            .is_some_and(|servers| servers.contains(server_id))
 8736                    })
 8737                })
 8738                .collect::<Vec<_>>()
 8739        });
 8740
 8741        let mut response_results = server_ids
 8742            .into_iter()
 8743            .map(|server_id| {
 8744                let task = self.request_lsp(
 8745                    buffer.clone(),
 8746                    LanguageServerToQuery::Other(server_id),
 8747                    request.clone(),
 8748                    cx,
 8749                );
 8750                async move { (server_id, task.await) }
 8751            })
 8752            .collect::<FuturesUnordered<_>>();
 8753
 8754        cx.background_spawn(async move {
 8755            let mut responses = Vec::with_capacity(response_results.len());
 8756            while let Some((server_id, response_result)) = response_results.next().await {
 8757                match response_result {
 8758                    Ok(response) => responses.push((server_id, response)),
 8759                    // rust-analyzer likes to error with this when its still loading up
 8760                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8761                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8762                }
 8763            }
 8764            responses
 8765        })
 8766    }
 8767
 8768    async fn handle_lsp_get_completions(
 8769        this: Entity<Self>,
 8770        envelope: TypedEnvelope<proto::GetCompletions>,
 8771        mut cx: AsyncApp,
 8772    ) -> Result<proto::GetCompletionsResponse> {
 8773        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8774
 8775        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8776        let buffer_handle = this.update(&mut cx, |this, cx| {
 8777            this.buffer_store.read(cx).get_existing(buffer_id)
 8778        })?;
 8779        let request = GetCompletions::from_proto(
 8780            envelope.payload,
 8781            this.clone(),
 8782            buffer_handle.clone(),
 8783            cx.clone(),
 8784        )
 8785        .await?;
 8786
 8787        let server_to_query = match request.server_id {
 8788            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8789            None => LanguageServerToQuery::FirstCapable,
 8790        };
 8791
 8792        let response = this
 8793            .update(&mut cx, |this, cx| {
 8794                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8795            })
 8796            .await?;
 8797        this.update(&mut cx, |this, cx| {
 8798            Ok(GetCompletions::response_to_proto(
 8799                response,
 8800                this,
 8801                sender_id,
 8802                &buffer_handle.read(cx).version(),
 8803                cx,
 8804            ))
 8805        })
 8806    }
 8807
 8808    async fn handle_lsp_command<T: LspCommand>(
 8809        this: Entity<Self>,
 8810        envelope: TypedEnvelope<T::ProtoRequest>,
 8811        mut cx: AsyncApp,
 8812    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8813    where
 8814        <T::LspRequest as lsp::request::Request>::Params: Send,
 8815        <T::LspRequest as lsp::request::Request>::Result: Send,
 8816    {
 8817        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8818        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8819        let buffer_handle = this.update(&mut cx, |this, cx| {
 8820            this.buffer_store.read(cx).get_existing(buffer_id)
 8821        })?;
 8822        let request = T::from_proto(
 8823            envelope.payload,
 8824            this.clone(),
 8825            buffer_handle.clone(),
 8826            cx.clone(),
 8827        )
 8828        .await?;
 8829        let response = this
 8830            .update(&mut cx, |this, cx| {
 8831                this.request_lsp(
 8832                    buffer_handle.clone(),
 8833                    LanguageServerToQuery::FirstCapable,
 8834                    request,
 8835                    cx,
 8836                )
 8837            })
 8838            .await?;
 8839        this.update(&mut cx, |this, cx| {
 8840            Ok(T::response_to_proto(
 8841                response,
 8842                this,
 8843                sender_id,
 8844                &buffer_handle.read(cx).version(),
 8845                cx,
 8846            ))
 8847        })
 8848    }
 8849
 8850    async fn handle_lsp_query(
 8851        lsp_store: Entity<Self>,
 8852        envelope: TypedEnvelope<proto::LspQuery>,
 8853        mut cx: AsyncApp,
 8854    ) -> Result<proto::Ack> {
 8855        use proto::lsp_query::Request;
 8856        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8857        let lsp_query = envelope.payload;
 8858        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8859        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8860        match lsp_query.request.context("invalid LSP query request")? {
 8861            Request::GetReferences(get_references) => {
 8862                let position = get_references.position.clone().and_then(deserialize_anchor);
 8863                Self::query_lsp_locally::<GetReferences>(
 8864                    lsp_store,
 8865                    server_id,
 8866                    sender_id,
 8867                    lsp_request_id,
 8868                    get_references,
 8869                    position,
 8870                    &mut cx,
 8871                )
 8872                .await?;
 8873            }
 8874            Request::GetDocumentColor(get_document_color) => {
 8875                Self::query_lsp_locally::<GetDocumentColor>(
 8876                    lsp_store,
 8877                    server_id,
 8878                    sender_id,
 8879                    lsp_request_id,
 8880                    get_document_color,
 8881                    None,
 8882                    &mut cx,
 8883                )
 8884                .await?;
 8885            }
 8886            Request::GetFoldingRanges(get_folding_ranges) => {
 8887                Self::query_lsp_locally::<GetFoldingRanges>(
 8888                    lsp_store,
 8889                    server_id,
 8890                    sender_id,
 8891                    lsp_request_id,
 8892                    get_folding_ranges,
 8893                    None,
 8894                    &mut cx,
 8895                )
 8896                .await?;
 8897            }
 8898            Request::GetDocumentSymbols(get_document_symbols) => {
 8899                Self::query_lsp_locally::<GetDocumentSymbols>(
 8900                    lsp_store,
 8901                    server_id,
 8902                    sender_id,
 8903                    lsp_request_id,
 8904                    get_document_symbols,
 8905                    None,
 8906                    &mut cx,
 8907                )
 8908                .await?;
 8909            }
 8910            Request::GetHover(get_hover) => {
 8911                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8912                Self::query_lsp_locally::<GetHover>(
 8913                    lsp_store,
 8914                    server_id,
 8915                    sender_id,
 8916                    lsp_request_id,
 8917                    get_hover,
 8918                    position,
 8919                    &mut cx,
 8920                )
 8921                .await?;
 8922            }
 8923            Request::GetCodeActions(get_code_actions) => {
 8924                Self::query_lsp_locally::<GetCodeActions>(
 8925                    lsp_store,
 8926                    server_id,
 8927                    sender_id,
 8928                    lsp_request_id,
 8929                    get_code_actions,
 8930                    None,
 8931                    &mut cx,
 8932                )
 8933                .await?;
 8934            }
 8935            Request::GetSignatureHelp(get_signature_help) => {
 8936                let position = get_signature_help
 8937                    .position
 8938                    .clone()
 8939                    .and_then(deserialize_anchor);
 8940                Self::query_lsp_locally::<GetSignatureHelp>(
 8941                    lsp_store,
 8942                    server_id,
 8943                    sender_id,
 8944                    lsp_request_id,
 8945                    get_signature_help,
 8946                    position,
 8947                    &mut cx,
 8948                )
 8949                .await?;
 8950            }
 8951            Request::GetCodeLens(get_code_lens) => {
 8952                Self::query_lsp_locally::<GetCodeLens>(
 8953                    lsp_store,
 8954                    server_id,
 8955                    sender_id,
 8956                    lsp_request_id,
 8957                    get_code_lens,
 8958                    None,
 8959                    &mut cx,
 8960                )
 8961                .await?;
 8962            }
 8963            Request::GetDefinition(get_definition) => {
 8964                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8965                Self::query_lsp_locally::<GetDefinitions>(
 8966                    lsp_store,
 8967                    server_id,
 8968                    sender_id,
 8969                    lsp_request_id,
 8970                    get_definition,
 8971                    position,
 8972                    &mut cx,
 8973                )
 8974                .await?;
 8975            }
 8976            Request::GetDeclaration(get_declaration) => {
 8977                let position = get_declaration
 8978                    .position
 8979                    .clone()
 8980                    .and_then(deserialize_anchor);
 8981                Self::query_lsp_locally::<GetDeclarations>(
 8982                    lsp_store,
 8983                    server_id,
 8984                    sender_id,
 8985                    lsp_request_id,
 8986                    get_declaration,
 8987                    position,
 8988                    &mut cx,
 8989                )
 8990                .await?;
 8991            }
 8992            Request::GetTypeDefinition(get_type_definition) => {
 8993                let position = get_type_definition
 8994                    .position
 8995                    .clone()
 8996                    .and_then(deserialize_anchor);
 8997                Self::query_lsp_locally::<GetTypeDefinitions>(
 8998                    lsp_store,
 8999                    server_id,
 9000                    sender_id,
 9001                    lsp_request_id,
 9002                    get_type_definition,
 9003                    position,
 9004                    &mut cx,
 9005                )
 9006                .await?;
 9007            }
 9008            Request::GetImplementation(get_implementation) => {
 9009                let position = get_implementation
 9010                    .position
 9011                    .clone()
 9012                    .and_then(deserialize_anchor);
 9013                Self::query_lsp_locally::<GetImplementations>(
 9014                    lsp_store,
 9015                    server_id,
 9016                    sender_id,
 9017                    lsp_request_id,
 9018                    get_implementation,
 9019                    position,
 9020                    &mut cx,
 9021                )
 9022                .await?;
 9023            }
 9024            Request::InlayHints(inlay_hints) => {
 9025                let query_start = inlay_hints
 9026                    .start
 9027                    .clone()
 9028                    .and_then(deserialize_anchor)
 9029                    .context("invalid inlay hints range start")?;
 9030                let query_end = inlay_hints
 9031                    .end
 9032                    .clone()
 9033                    .and_then(deserialize_anchor)
 9034                    .context("invalid inlay hints range end")?;
 9035                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9036                    &lsp_store,
 9037                    server_id,
 9038                    lsp_request_id,
 9039                    &inlay_hints,
 9040                    query_start..query_end,
 9041                    &mut cx,
 9042                )
 9043                .await
 9044                .context("preparing inlay hints request")?;
 9045                Self::query_lsp_locally::<InlayHints>(
 9046                    lsp_store,
 9047                    server_id,
 9048                    sender_id,
 9049                    lsp_request_id,
 9050                    inlay_hints,
 9051                    None,
 9052                    &mut cx,
 9053                )
 9054                .await
 9055                .context("querying for inlay hints")?
 9056            }
 9057            //////////////////////////////
 9058            // Below are LSP queries that need to fetch more data,
 9059            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9060            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9061                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9062                    &lsp_store,
 9063                    &get_document_diagnostics,
 9064                    &mut cx,
 9065                )
 9066                .await?;
 9067                lsp_store.update(&mut cx, |lsp_store, cx| {
 9068                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9069                    let key = LspKey {
 9070                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9071                        server_queried: server_id,
 9072                    };
 9073                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9074                    ) {
 9075                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9076                            lsp_requests.clear();
 9077                        };
 9078                    }
 9079
 9080                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9081                        lsp_request_id,
 9082                        cx.spawn(async move |lsp_store, cx| {
 9083                            let diagnostics_pull = lsp_store
 9084                                .update(cx, |lsp_store, cx| {
 9085                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9086                                })
 9087                                .ok();
 9088                            if let Some(diagnostics_pull) = diagnostics_pull {
 9089                                match diagnostics_pull.await {
 9090                                    Ok(()) => {}
 9091                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9092                                };
 9093                            }
 9094                        }),
 9095                    );
 9096                });
 9097            }
 9098            Request::SemanticTokens(semantic_tokens) => {
 9099                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9100                    &lsp_store,
 9101                    &semantic_tokens,
 9102                    &mut cx,
 9103                )
 9104                .await?;
 9105                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9106                lsp_store.update(&mut cx, |lsp_store, cx| {
 9107                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9108                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9109                        let key = LspKey {
 9110                            request_type: TypeId::of::<SemanticTokensFull>(),
 9111                            server_queried: server_id,
 9112                        };
 9113                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9114                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9115                                lsp_requests.clear();
 9116                            };
 9117                        }
 9118
 9119                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9120                            lsp_request_id,
 9121                            cx.spawn(async move |lsp_store, cx| {
 9122                                let tokens_fetch = lsp_store
 9123                                    .update(cx, |lsp_store, cx| {
 9124                                        lsp_store
 9125                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9126                                    })
 9127                                    .ok();
 9128                                if let Some(tokens_fetch) = tokens_fetch {
 9129                                    let new_tokens = tokens_fetch.await;
 9130                                    if let Some(new_tokens) = new_tokens {
 9131                                        lsp_store
 9132                                            .update(cx, |lsp_store, cx| {
 9133                                                let response = new_tokens
 9134                                                    .into_iter()
 9135                                                    .map(|(server_id, response)| {
 9136                                                        (
 9137                                                            server_id.to_proto(),
 9138                                                            SemanticTokensFull::response_to_proto(
 9139                                                                response,
 9140                                                                lsp_store,
 9141                                                                sender_id,
 9142                                                                &buffer_version,
 9143                                                                cx,
 9144                                                            ),
 9145                                                        )
 9146                                                    })
 9147                                                    .collect::<HashMap<_, _>>();
 9148                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9149                                                    project_id,
 9150                                                    lsp_request_id,
 9151                                                    response,
 9152                                                ) {
 9153                                                    Ok(()) => {}
 9154                                                    Err(e) => {
 9155                                                        log::error!(
 9156                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9157                                                        )
 9158                                                    }
 9159                                                }
 9160                                            })
 9161                                            .ok();
 9162                                    }
 9163                                }
 9164                            }),
 9165                        );
 9166                    }
 9167                });
 9168            }
 9169        }
 9170        Ok(proto::Ack {})
 9171    }
 9172
 9173    async fn handle_lsp_query_response(
 9174        lsp_store: Entity<Self>,
 9175        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9176        cx: AsyncApp,
 9177    ) -> Result<()> {
 9178        lsp_store.read_with(&cx, |lsp_store, _| {
 9179            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9180                upstream_client.handle_lsp_response(envelope.clone());
 9181            }
 9182        });
 9183        Ok(())
 9184    }
 9185
 9186    async fn handle_apply_code_action(
 9187        this: Entity<Self>,
 9188        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9189        mut cx: AsyncApp,
 9190    ) -> Result<proto::ApplyCodeActionResponse> {
 9191        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9192        let action =
 9193            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9194        let apply_code_action = this.update(&mut cx, |this, cx| {
 9195            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9196            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9197            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9198        })?;
 9199
 9200        let project_transaction = apply_code_action.await?;
 9201        let project_transaction = this.update(&mut cx, |this, cx| {
 9202            this.buffer_store.update(cx, |buffer_store, cx| {
 9203                buffer_store.serialize_project_transaction_for_peer(
 9204                    project_transaction,
 9205                    sender_id,
 9206                    cx,
 9207                )
 9208            })
 9209        });
 9210        Ok(proto::ApplyCodeActionResponse {
 9211            transaction: Some(project_transaction),
 9212        })
 9213    }
 9214
 9215    async fn handle_register_buffer_with_language_servers(
 9216        this: Entity<Self>,
 9217        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9218        mut cx: AsyncApp,
 9219    ) -> Result<proto::Ack> {
 9220        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9221        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9222        this.update(&mut cx, |this, cx| {
 9223            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9224                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9225                    project_id: upstream_project_id,
 9226                    buffer_id: buffer_id.to_proto(),
 9227                    only_servers: envelope.payload.only_servers,
 9228                });
 9229            }
 9230
 9231            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9232                anyhow::bail!("buffer is not open");
 9233            };
 9234
 9235            let handle = this.register_buffer_with_language_servers(
 9236                &buffer,
 9237                envelope
 9238                    .payload
 9239                    .only_servers
 9240                    .into_iter()
 9241                    .filter_map(|selector| {
 9242                        Some(match selector.selector? {
 9243                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9244                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9245                            }
 9246                            proto::language_server_selector::Selector::Name(name) => {
 9247                                LanguageServerSelector::Name(LanguageServerName(
 9248                                    SharedString::from(name),
 9249                                ))
 9250                            }
 9251                        })
 9252                    })
 9253                    .collect(),
 9254                false,
 9255                cx,
 9256            );
 9257            // Pull diagnostics for the buffer even if it was already registered.
 9258            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9259            // but it's unclear if we need it.
 9260            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9261                .detach();
 9262            this.buffer_store().update(cx, |buffer_store, _| {
 9263                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9264            });
 9265
 9266            Ok(())
 9267        })?;
 9268        Ok(proto::Ack {})
 9269    }
 9270
 9271    async fn handle_rename_project_entry(
 9272        this: Entity<Self>,
 9273        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9274        mut cx: AsyncApp,
 9275    ) -> Result<proto::ProjectEntryResponse> {
 9276        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9277        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9278        let new_path =
 9279            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9280
 9281        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9282            .update(&mut cx, |this, cx| {
 9283                let (worktree, entry) = this
 9284                    .worktree_store
 9285                    .read(cx)
 9286                    .worktree_and_entry_for_id(entry_id, cx)?;
 9287                let new_worktree = this
 9288                    .worktree_store
 9289                    .read(cx)
 9290                    .worktree_for_id(new_worktree_id, cx)?;
 9291                Some((
 9292                    this.worktree_store.clone(),
 9293                    worktree,
 9294                    new_worktree,
 9295                    entry.clone(),
 9296                ))
 9297            })
 9298            .context("worktree not found")?;
 9299        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9300            (worktree.absolutize(&old_entry.path), worktree.id())
 9301        });
 9302        let new_abs_path =
 9303            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9304
 9305        let _transaction = Self::will_rename_entry(
 9306            this.downgrade(),
 9307            old_worktree_id,
 9308            &old_abs_path,
 9309            &new_abs_path,
 9310            old_entry.is_dir(),
 9311            cx.clone(),
 9312        )
 9313        .await;
 9314        let response = WorktreeStore::handle_rename_project_entry(
 9315            worktree_store,
 9316            envelope.payload,
 9317            cx.clone(),
 9318        )
 9319        .await;
 9320        this.read_with(&cx, |this, _| {
 9321            this.did_rename_entry(
 9322                old_worktree_id,
 9323                &old_abs_path,
 9324                &new_abs_path,
 9325                old_entry.is_dir(),
 9326            );
 9327        });
 9328        response
 9329    }
 9330
 9331    async fn handle_update_diagnostic_summary(
 9332        this: Entity<Self>,
 9333        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9334        mut cx: AsyncApp,
 9335    ) -> Result<()> {
 9336        this.update(&mut cx, |lsp_store, cx| {
 9337            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9338            let mut updated_diagnostics_paths = HashMap::default();
 9339            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9340            for message_summary in envelope
 9341                .payload
 9342                .summary
 9343                .into_iter()
 9344                .chain(envelope.payload.more_summaries)
 9345            {
 9346                let project_path = ProjectPath {
 9347                    worktree_id,
 9348                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9349                };
 9350                let path = project_path.path.clone();
 9351                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9352                let summary = DiagnosticSummary {
 9353                    error_count: message_summary.error_count as usize,
 9354                    warning_count: message_summary.warning_count as usize,
 9355                };
 9356
 9357                if summary.is_empty() {
 9358                    if let Some(worktree_summaries) =
 9359                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9360                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9361                    {
 9362                        summaries.remove(&server_id);
 9363                        if summaries.is_empty() {
 9364                            worktree_summaries.remove(&path);
 9365                        }
 9366                    }
 9367                } else {
 9368                    lsp_store
 9369                        .diagnostic_summaries
 9370                        .entry(worktree_id)
 9371                        .or_default()
 9372                        .entry(path)
 9373                        .or_default()
 9374                        .insert(server_id, summary);
 9375                }
 9376
 9377                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9378                    match &mut diagnostics_summary {
 9379                        Some(diagnostics_summary) => {
 9380                            diagnostics_summary
 9381                                .more_summaries
 9382                                .push(proto::DiagnosticSummary {
 9383                                    path: project_path.path.as_ref().to_proto(),
 9384                                    language_server_id: server_id.0 as u64,
 9385                                    error_count: summary.error_count as u32,
 9386                                    warning_count: summary.warning_count as u32,
 9387                                })
 9388                        }
 9389                        None => {
 9390                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9391                                project_id: *project_id,
 9392                                worktree_id: worktree_id.to_proto(),
 9393                                summary: Some(proto::DiagnosticSummary {
 9394                                    path: project_path.path.as_ref().to_proto(),
 9395                                    language_server_id: server_id.0 as u64,
 9396                                    error_count: summary.error_count as u32,
 9397                                    warning_count: summary.warning_count as u32,
 9398                                }),
 9399                                more_summaries: Vec::new(),
 9400                            })
 9401                        }
 9402                    }
 9403                }
 9404                updated_diagnostics_paths
 9405                    .entry(server_id)
 9406                    .or_insert_with(Vec::new)
 9407                    .push(project_path);
 9408            }
 9409
 9410            if let Some((diagnostics_summary, (downstream_client, _))) =
 9411                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9412            {
 9413                downstream_client.send(diagnostics_summary).log_err();
 9414            }
 9415            for (server_id, paths) in updated_diagnostics_paths {
 9416                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9417            }
 9418            Ok(())
 9419        })
 9420    }
 9421
 9422    async fn handle_start_language_server(
 9423        lsp_store: Entity<Self>,
 9424        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9425        mut cx: AsyncApp,
 9426    ) -> Result<()> {
 9427        let server = envelope.payload.server.context("invalid server")?;
 9428        let server_capabilities =
 9429            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9430                .with_context(|| {
 9431                    format!(
 9432                        "incorrect server capabilities {}",
 9433                        envelope.payload.capabilities
 9434                    )
 9435                })?;
 9436        lsp_store.update(&mut cx, |lsp_store, cx| {
 9437            let server_id = LanguageServerId(server.id as usize);
 9438            let server_name = LanguageServerName::from_proto(server.name.clone());
 9439            lsp_store
 9440                .lsp_server_capabilities
 9441                .insert(server_id, server_capabilities);
 9442            lsp_store.language_server_statuses.insert(
 9443                server_id,
 9444                LanguageServerStatus {
 9445                    name: server_name.clone(),
 9446                    server_version: None,
 9447                    pending_work: Default::default(),
 9448                    has_pending_diagnostic_updates: false,
 9449                    progress_tokens: Default::default(),
 9450                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9451                    binary: None,
 9452                    configuration: None,
 9453                    workspace_folders: BTreeSet::new(),
 9454                    process_id: None,
 9455                },
 9456            );
 9457            cx.emit(LspStoreEvent::LanguageServerAdded(
 9458                server_id,
 9459                server_name,
 9460                server.worktree_id.map(WorktreeId::from_proto),
 9461            ));
 9462            cx.notify();
 9463        });
 9464        Ok(())
 9465    }
 9466
 9467    async fn handle_update_language_server(
 9468        lsp_store: Entity<Self>,
 9469        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9470        mut cx: AsyncApp,
 9471    ) -> Result<()> {
 9472        lsp_store.update(&mut cx, |lsp_store, cx| {
 9473            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9474
 9475            match envelope.payload.variant.context("invalid variant")? {
 9476                proto::update_language_server::Variant::WorkStart(payload) => {
 9477                    lsp_store.on_lsp_work_start(
 9478                        language_server_id,
 9479                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9480                            .context("invalid progress token value")?,
 9481                        LanguageServerProgress {
 9482                            title: payload.title,
 9483                            is_disk_based_diagnostics_progress: false,
 9484                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9485                            message: payload.message,
 9486                            percentage: payload.percentage.map(|p| p as usize),
 9487                            last_update_at: cx.background_executor().now(),
 9488                        },
 9489                        cx,
 9490                    );
 9491                }
 9492                proto::update_language_server::Variant::WorkProgress(payload) => {
 9493                    lsp_store.on_lsp_work_progress(
 9494                        language_server_id,
 9495                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9496                            .context("invalid progress token value")?,
 9497                        LanguageServerProgress {
 9498                            title: None,
 9499                            is_disk_based_diagnostics_progress: false,
 9500                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9501                            message: payload.message,
 9502                            percentage: payload.percentage.map(|p| p as usize),
 9503                            last_update_at: cx.background_executor().now(),
 9504                        },
 9505                        cx,
 9506                    );
 9507                }
 9508
 9509                proto::update_language_server::Variant::WorkEnd(payload) => {
 9510                    lsp_store.on_lsp_work_end(
 9511                        language_server_id,
 9512                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9513                            .context("invalid progress token value")?,
 9514                        cx,
 9515                    );
 9516                }
 9517
 9518                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9519                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9520                }
 9521
 9522                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9523                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9524                }
 9525
 9526                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9527                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9528                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9529                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9530                        language_server_id,
 9531                        name: envelope
 9532                            .payload
 9533                            .server_name
 9534                            .map(SharedString::new)
 9535                            .map(LanguageServerName),
 9536                        message: non_lsp,
 9537                    });
 9538                }
 9539            }
 9540
 9541            Ok(())
 9542        })
 9543    }
 9544
 9545    async fn handle_language_server_log(
 9546        this: Entity<Self>,
 9547        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9548        mut cx: AsyncApp,
 9549    ) -> Result<()> {
 9550        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9551        let log_type = envelope
 9552            .payload
 9553            .log_type
 9554            .map(LanguageServerLogType::from_proto)
 9555            .context("invalid language server log type")?;
 9556
 9557        let message = envelope.payload.message;
 9558
 9559        this.update(&mut cx, |_, cx| {
 9560            cx.emit(LspStoreEvent::LanguageServerLog(
 9561                language_server_id,
 9562                log_type,
 9563                message,
 9564            ));
 9565        });
 9566        Ok(())
 9567    }
 9568
 9569    async fn handle_lsp_ext_cancel_flycheck(
 9570        lsp_store: Entity<Self>,
 9571        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9572        cx: AsyncApp,
 9573    ) -> Result<proto::Ack> {
 9574        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9575        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9576            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9577                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9578            } else {
 9579                None
 9580            }
 9581        });
 9582        if let Some(task) = task {
 9583            task.context("handling lsp ext cancel flycheck")?;
 9584        }
 9585
 9586        Ok(proto::Ack {})
 9587    }
 9588
 9589    async fn handle_lsp_ext_run_flycheck(
 9590        lsp_store: Entity<Self>,
 9591        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9592        mut cx: AsyncApp,
 9593    ) -> Result<proto::Ack> {
 9594        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9595        lsp_store.update(&mut cx, |lsp_store, cx| {
 9596            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9597                let text_document = if envelope.payload.current_file_only {
 9598                    let buffer_id = envelope
 9599                        .payload
 9600                        .buffer_id
 9601                        .map(|id| BufferId::new(id))
 9602                        .transpose()?;
 9603                    buffer_id
 9604                        .and_then(|buffer_id| {
 9605                            lsp_store
 9606                                .buffer_store()
 9607                                .read(cx)
 9608                                .get(buffer_id)
 9609                                .and_then(|buffer| {
 9610                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9611                                })
 9612                                .map(|path| make_text_document_identifier(&path))
 9613                        })
 9614                        .transpose()?
 9615                } else {
 9616                    None
 9617                };
 9618                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9619                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9620                )?;
 9621            }
 9622            anyhow::Ok(())
 9623        })?;
 9624
 9625        Ok(proto::Ack {})
 9626    }
 9627
 9628    async fn handle_lsp_ext_clear_flycheck(
 9629        lsp_store: Entity<Self>,
 9630        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9631        cx: AsyncApp,
 9632    ) -> Result<proto::Ack> {
 9633        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9634        lsp_store.read_with(&cx, |lsp_store, _| {
 9635            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9636                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9637            } else {
 9638                None
 9639            }
 9640        });
 9641
 9642        Ok(proto::Ack {})
 9643    }
 9644
 9645    pub fn disk_based_diagnostics_started(
 9646        &mut self,
 9647        language_server_id: LanguageServerId,
 9648        cx: &mut Context<Self>,
 9649    ) {
 9650        if let Some(language_server_status) =
 9651            self.language_server_statuses.get_mut(&language_server_id)
 9652        {
 9653            language_server_status.has_pending_diagnostic_updates = true;
 9654        }
 9655
 9656        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9657        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9658            language_server_id,
 9659            name: self
 9660                .language_server_adapter_for_id(language_server_id)
 9661                .map(|adapter| adapter.name()),
 9662            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9663                Default::default(),
 9664            ),
 9665        })
 9666    }
 9667
 9668    pub fn disk_based_diagnostics_finished(
 9669        &mut self,
 9670        language_server_id: LanguageServerId,
 9671        cx: &mut Context<Self>,
 9672    ) {
 9673        if let Some(language_server_status) =
 9674            self.language_server_statuses.get_mut(&language_server_id)
 9675        {
 9676            language_server_status.has_pending_diagnostic_updates = false;
 9677        }
 9678
 9679        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9680        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9681            language_server_id,
 9682            name: self
 9683                .language_server_adapter_for_id(language_server_id)
 9684                .map(|adapter| adapter.name()),
 9685            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9686                Default::default(),
 9687            ),
 9688        })
 9689    }
 9690
 9691    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9692    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9693    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9694    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9695    // the language server might take some time to publish diagnostics.
 9696    fn simulate_disk_based_diagnostics_events_if_needed(
 9697        &mut self,
 9698        language_server_id: LanguageServerId,
 9699        cx: &mut Context<Self>,
 9700    ) {
 9701        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9702
 9703        let Some(LanguageServerState::Running {
 9704            simulate_disk_based_diagnostics_completion,
 9705            adapter,
 9706            ..
 9707        }) = self
 9708            .as_local_mut()
 9709            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9710        else {
 9711            return;
 9712        };
 9713
 9714        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9715            return;
 9716        }
 9717
 9718        let prev_task =
 9719            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9720                cx.background_executor()
 9721                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9722                    .await;
 9723
 9724                this.update(cx, |this, cx| {
 9725                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9726
 9727                    if let Some(LanguageServerState::Running {
 9728                        simulate_disk_based_diagnostics_completion,
 9729                        ..
 9730                    }) = this.as_local_mut().and_then(|local_store| {
 9731                        local_store.language_servers.get_mut(&language_server_id)
 9732                    }) {
 9733                        *simulate_disk_based_diagnostics_completion = None;
 9734                    }
 9735                })
 9736                .ok();
 9737            }));
 9738
 9739        if prev_task.is_none() {
 9740            self.disk_based_diagnostics_started(language_server_id, cx);
 9741        }
 9742    }
 9743
 9744    pub fn language_server_statuses(
 9745        &self,
 9746    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9747        self.language_server_statuses
 9748            .iter()
 9749            .map(|(key, value)| (*key, value))
 9750    }
 9751
 9752    pub(super) fn did_rename_entry(
 9753        &self,
 9754        worktree_id: WorktreeId,
 9755        old_path: &Path,
 9756        new_path: &Path,
 9757        is_dir: bool,
 9758    ) {
 9759        maybe!({
 9760            let local_store = self.as_local()?;
 9761
 9762            let old_uri = lsp::Uri::from_file_path(old_path)
 9763                .ok()
 9764                .map(|uri| uri.to_string())?;
 9765            let new_uri = lsp::Uri::from_file_path(new_path)
 9766                .ok()
 9767                .map(|uri| uri.to_string())?;
 9768
 9769            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9770                let Some(filter) = local_store
 9771                    .language_server_paths_watched_for_rename
 9772                    .get(&language_server.server_id())
 9773                else {
 9774                    continue;
 9775                };
 9776
 9777                if filter.should_send_did_rename(&old_uri, is_dir) {
 9778                    language_server
 9779                        .notify::<DidRenameFiles>(RenameFilesParams {
 9780                            files: vec![FileRename {
 9781                                old_uri: old_uri.clone(),
 9782                                new_uri: new_uri.clone(),
 9783                            }],
 9784                        })
 9785                        .ok();
 9786                }
 9787            }
 9788            Some(())
 9789        });
 9790    }
 9791
 9792    pub(super) fn will_rename_entry(
 9793        this: WeakEntity<Self>,
 9794        worktree_id: WorktreeId,
 9795        old_path: &Path,
 9796        new_path: &Path,
 9797        is_dir: bool,
 9798        cx: AsyncApp,
 9799    ) -> Task<ProjectTransaction> {
 9800        let old_uri = lsp::Uri::from_file_path(old_path)
 9801            .ok()
 9802            .map(|uri| uri.to_string());
 9803        let new_uri = lsp::Uri::from_file_path(new_path)
 9804            .ok()
 9805            .map(|uri| uri.to_string());
 9806        cx.spawn(async move |cx| {
 9807            let mut tasks = vec![];
 9808            this.update(cx, |this, cx| {
 9809                let local_store = this.as_local()?;
 9810                let old_uri = old_uri?;
 9811                let new_uri = new_uri?;
 9812                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9813                    let Some(filter) = local_store
 9814                        .language_server_paths_watched_for_rename
 9815                        .get(&language_server.server_id())
 9816                    else {
 9817                        continue;
 9818                    };
 9819
 9820                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9821                        continue;
 9822                    }
 9823                    let request_timeout = ProjectSettings::get_global(cx)
 9824                        .global_lsp_settings
 9825                        .get_request_timeout();
 9826
 9827                    let apply_edit = cx.spawn({
 9828                        let old_uri = old_uri.clone();
 9829                        let new_uri = new_uri.clone();
 9830                        let language_server = language_server.clone();
 9831                        async move |this, cx| {
 9832                            let edit = language_server
 9833                                .request::<WillRenameFiles>(
 9834                                    RenameFilesParams {
 9835                                        files: vec![FileRename { old_uri, new_uri }],
 9836                                    },
 9837                                    request_timeout,
 9838                                )
 9839                                .await
 9840                                .into_response()
 9841                                .context("will rename files")
 9842                                .log_err()
 9843                                .flatten()?;
 9844
 9845                            LocalLspStore::deserialize_workspace_edit(
 9846                                this.upgrade()?,
 9847                                edit,
 9848                                false,
 9849                                language_server.clone(),
 9850                                cx,
 9851                            )
 9852                            .await
 9853                            .ok()
 9854                        }
 9855                    });
 9856                    tasks.push(apply_edit);
 9857                }
 9858                Some(())
 9859            })
 9860            .ok()
 9861            .flatten();
 9862            let mut merged_transaction = ProjectTransaction::default();
 9863            for task in tasks {
 9864                // Await on tasks sequentially so that the order of application of edits is deterministic
 9865                // (at least with regards to the order of registration of language servers)
 9866                if let Some(transaction) = task.await {
 9867                    for (buffer, buffer_transaction) in transaction.0 {
 9868                        merged_transaction.0.insert(buffer, buffer_transaction);
 9869                    }
 9870                }
 9871            }
 9872            merged_transaction
 9873        })
 9874    }
 9875
 9876    fn lsp_notify_abs_paths_changed(
 9877        &mut self,
 9878        server_id: LanguageServerId,
 9879        changes: Vec<PathEvent>,
 9880    ) {
 9881        maybe!({
 9882            let server = self.language_server_for_id(server_id)?;
 9883            let changes = changes
 9884                .into_iter()
 9885                .filter_map(|event| {
 9886                    let typ = match event.kind? {
 9887                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9888                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9889                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9890                    };
 9891                    Some(lsp::FileEvent {
 9892                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9893                        typ,
 9894                    })
 9895                })
 9896                .collect::<Vec<_>>();
 9897            if !changes.is_empty() {
 9898                server
 9899                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9900                        lsp::DidChangeWatchedFilesParams { changes },
 9901                    )
 9902                    .ok();
 9903            }
 9904            Some(())
 9905        });
 9906    }
 9907
 9908    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9909        self.as_local()?.language_server_for_id(id)
 9910    }
 9911
 9912    fn on_lsp_progress(
 9913        &mut self,
 9914        progress_params: lsp::ProgressParams,
 9915        language_server_id: LanguageServerId,
 9916        disk_based_diagnostics_progress_token: Option<String>,
 9917        cx: &mut Context<Self>,
 9918    ) {
 9919        match progress_params.value {
 9920            lsp::ProgressParamsValue::WorkDone(progress) => {
 9921                self.handle_work_done_progress(
 9922                    progress,
 9923                    language_server_id,
 9924                    disk_based_diagnostics_progress_token,
 9925                    ProgressToken::from_lsp(progress_params.token),
 9926                    cx,
 9927                );
 9928            }
 9929            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9930                let registration_id = match progress_params.token {
 9931                    lsp::NumberOrString::Number(_) => None,
 9932                    lsp::NumberOrString::String(token) => token
 9933                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9934                        .map(|(_, id)| id.to_owned()),
 9935                };
 9936                if let Some(LanguageServerState::Running {
 9937                    workspace_diagnostics_refresh_tasks,
 9938                    ..
 9939                }) = self
 9940                    .as_local_mut()
 9941                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9942                    && let Some(workspace_diagnostics) =
 9943                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9944                {
 9945                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9946                    self.apply_workspace_diagnostic_report(
 9947                        language_server_id,
 9948                        report,
 9949                        registration_id.map(SharedString::from),
 9950                        cx,
 9951                    )
 9952                }
 9953            }
 9954        }
 9955    }
 9956
 9957    fn handle_work_done_progress(
 9958        &mut self,
 9959        progress: lsp::WorkDoneProgress,
 9960        language_server_id: LanguageServerId,
 9961        disk_based_diagnostics_progress_token: Option<String>,
 9962        token: ProgressToken,
 9963        cx: &mut Context<Self>,
 9964    ) {
 9965        let language_server_status =
 9966            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9967                status
 9968            } else {
 9969                return;
 9970            };
 9971
 9972        if !language_server_status.progress_tokens.contains(&token) {
 9973            return;
 9974        }
 9975
 9976        let is_disk_based_diagnostics_progress =
 9977            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9978                (&disk_based_diagnostics_progress_token, &token)
 9979            {
 9980                token.starts_with(disk_based_token)
 9981            } else {
 9982                false
 9983            };
 9984
 9985        match progress {
 9986            lsp::WorkDoneProgress::Begin(report) => {
 9987                if is_disk_based_diagnostics_progress {
 9988                    self.disk_based_diagnostics_started(language_server_id, cx);
 9989                }
 9990                self.on_lsp_work_start(
 9991                    language_server_id,
 9992                    token.clone(),
 9993                    LanguageServerProgress {
 9994                        title: Some(report.title),
 9995                        is_disk_based_diagnostics_progress,
 9996                        is_cancellable: report.cancellable.unwrap_or(false),
 9997                        message: report.message.clone(),
 9998                        percentage: report.percentage.map(|p| p as usize),
 9999                        last_update_at: cx.background_executor().now(),
10000                    },
10001                    cx,
10002                );
10003            }
10004            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10005                language_server_id,
10006                token,
10007                LanguageServerProgress {
10008                    title: None,
10009                    is_disk_based_diagnostics_progress,
10010                    is_cancellable: report.cancellable.unwrap_or(false),
10011                    message: report.message,
10012                    percentage: report.percentage.map(|p| p as usize),
10013                    last_update_at: cx.background_executor().now(),
10014                },
10015                cx,
10016            ),
10017            lsp::WorkDoneProgress::End(_) => {
10018                language_server_status.progress_tokens.remove(&token);
10019                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10020                if is_disk_based_diagnostics_progress {
10021                    self.disk_based_diagnostics_finished(language_server_id, cx);
10022                }
10023            }
10024        }
10025    }
10026
10027    fn on_lsp_work_start(
10028        &mut self,
10029        language_server_id: LanguageServerId,
10030        token: ProgressToken,
10031        progress: LanguageServerProgress,
10032        cx: &mut Context<Self>,
10033    ) {
10034        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10035            status.pending_work.insert(token.clone(), progress.clone());
10036            cx.notify();
10037        }
10038        cx.emit(LspStoreEvent::LanguageServerUpdate {
10039            language_server_id,
10040            name: self
10041                .language_server_adapter_for_id(language_server_id)
10042                .map(|adapter| adapter.name()),
10043            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10044                token: Some(token.to_proto()),
10045                title: progress.title,
10046                message: progress.message,
10047                percentage: progress.percentage.map(|p| p as u32),
10048                is_cancellable: Some(progress.is_cancellable),
10049            }),
10050        })
10051    }
10052
10053    fn on_lsp_work_progress(
10054        &mut self,
10055        language_server_id: LanguageServerId,
10056        token: ProgressToken,
10057        progress: LanguageServerProgress,
10058        cx: &mut Context<Self>,
10059    ) {
10060        let mut did_update = false;
10061        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10062            match status.pending_work.entry(token.clone()) {
10063                btree_map::Entry::Vacant(entry) => {
10064                    entry.insert(progress.clone());
10065                    did_update = true;
10066                }
10067                btree_map::Entry::Occupied(mut entry) => {
10068                    let entry = entry.get_mut();
10069                    if (progress.last_update_at - entry.last_update_at)
10070                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10071                    {
10072                        entry.last_update_at = progress.last_update_at;
10073                        if progress.message.is_some() {
10074                            entry.message = progress.message.clone();
10075                        }
10076                        if progress.percentage.is_some() {
10077                            entry.percentage = progress.percentage;
10078                        }
10079                        if progress.is_cancellable != entry.is_cancellable {
10080                            entry.is_cancellable = progress.is_cancellable;
10081                        }
10082                        did_update = true;
10083                    }
10084                }
10085            }
10086        }
10087
10088        if did_update {
10089            cx.emit(LspStoreEvent::LanguageServerUpdate {
10090                language_server_id,
10091                name: self
10092                    .language_server_adapter_for_id(language_server_id)
10093                    .map(|adapter| adapter.name()),
10094                message: proto::update_language_server::Variant::WorkProgress(
10095                    proto::LspWorkProgress {
10096                        token: Some(token.to_proto()),
10097                        message: progress.message,
10098                        percentage: progress.percentage.map(|p| p as u32),
10099                        is_cancellable: Some(progress.is_cancellable),
10100                    },
10101                ),
10102            })
10103        }
10104    }
10105
10106    fn on_lsp_work_end(
10107        &mut self,
10108        language_server_id: LanguageServerId,
10109        token: ProgressToken,
10110        cx: &mut Context<Self>,
10111    ) {
10112        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10113            if let Some(work) = status.pending_work.remove(&token)
10114                && !work.is_disk_based_diagnostics_progress
10115            {
10116                cx.emit(LspStoreEvent::RefreshInlayHints {
10117                    server_id: language_server_id,
10118                    request_id: None,
10119                });
10120            }
10121            cx.notify();
10122        }
10123
10124        cx.emit(LspStoreEvent::LanguageServerUpdate {
10125            language_server_id,
10126            name: self
10127                .language_server_adapter_for_id(language_server_id)
10128                .map(|adapter| adapter.name()),
10129            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10130                token: Some(token.to_proto()),
10131            }),
10132        })
10133    }
10134
10135    pub async fn handle_resolve_completion_documentation(
10136        this: Entity<Self>,
10137        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10138        mut cx: AsyncApp,
10139    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10140        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10141
10142        let completion = this
10143            .read_with(&cx, |this, cx| {
10144                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10145                let server = this
10146                    .language_server_for_id(id)
10147                    .with_context(|| format!("No language server {id}"))?;
10148
10149                let request_timeout = ProjectSettings::get_global(cx)
10150                    .global_lsp_settings
10151                    .get_request_timeout();
10152
10153                anyhow::Ok(cx.background_spawn(async move {
10154                    let can_resolve = server
10155                        .capabilities()
10156                        .completion_provider
10157                        .as_ref()
10158                        .and_then(|options| options.resolve_provider)
10159                        .unwrap_or(false);
10160                    if can_resolve {
10161                        server
10162                            .request::<lsp::request::ResolveCompletionItem>(
10163                                lsp_completion,
10164                                request_timeout,
10165                            )
10166                            .await
10167                            .into_response()
10168                            .context("resolve completion item")
10169                    } else {
10170                        anyhow::Ok(lsp_completion)
10171                    }
10172                }))
10173            })?
10174            .await?;
10175
10176        let mut documentation_is_markdown = false;
10177        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10178        let documentation = match completion.documentation {
10179            Some(lsp::Documentation::String(text)) => text,
10180
10181            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10182                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10183                value
10184            }
10185
10186            _ => String::new(),
10187        };
10188
10189        // If we have a new buffer_id, that means we're talking to a new client
10190        // and want to check for new text_edits in the completion too.
10191        let mut old_replace_start = None;
10192        let mut old_replace_end = None;
10193        let mut old_insert_start = None;
10194        let mut old_insert_end = None;
10195        let mut new_text = String::default();
10196        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10197            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10198                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10199                anyhow::Ok(buffer.read(cx).snapshot())
10200            })?;
10201
10202            if let Some(text_edit) = completion.text_edit.as_ref() {
10203                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10204
10205                if let Some(mut edit) = edit {
10206                    LineEnding::normalize(&mut edit.new_text);
10207
10208                    new_text = edit.new_text;
10209                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10210                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10211                    if let Some(insert_range) = edit.insert_range {
10212                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10213                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10214                    }
10215                }
10216            }
10217        }
10218
10219        Ok(proto::ResolveCompletionDocumentationResponse {
10220            documentation,
10221            documentation_is_markdown,
10222            old_replace_start,
10223            old_replace_end,
10224            new_text,
10225            lsp_completion,
10226            old_insert_start,
10227            old_insert_end,
10228        })
10229    }
10230
10231    async fn handle_on_type_formatting(
10232        this: Entity<Self>,
10233        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10234        mut cx: AsyncApp,
10235    ) -> Result<proto::OnTypeFormattingResponse> {
10236        let on_type_formatting = this.update(&mut cx, |this, cx| {
10237            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10238            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10239            let position = envelope
10240                .payload
10241                .position
10242                .and_then(deserialize_anchor)
10243                .context("invalid position")?;
10244            anyhow::Ok(this.apply_on_type_formatting(
10245                buffer,
10246                position,
10247                envelope.payload.trigger.clone(),
10248                cx,
10249            ))
10250        })?;
10251
10252        let transaction = on_type_formatting
10253            .await?
10254            .as_ref()
10255            .map(language::proto::serialize_transaction);
10256        Ok(proto::OnTypeFormattingResponse { transaction })
10257    }
10258
10259    async fn handle_pull_workspace_diagnostics(
10260        lsp_store: Entity<Self>,
10261        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10262        mut cx: AsyncApp,
10263    ) -> Result<proto::Ack> {
10264        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10265        lsp_store.update(&mut cx, |lsp_store, _| {
10266            lsp_store.pull_workspace_diagnostics(server_id);
10267        });
10268        Ok(proto::Ack {})
10269    }
10270
10271    async fn handle_open_buffer_for_symbol(
10272        this: Entity<Self>,
10273        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10274        mut cx: AsyncApp,
10275    ) -> Result<proto::OpenBufferForSymbolResponse> {
10276        let peer_id = envelope.original_sender_id().unwrap_or_default();
10277        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10278        let symbol = Self::deserialize_symbol(symbol)?;
10279        this.read_with(&cx, |this, _| {
10280            if let SymbolLocation::OutsideProject {
10281                abs_path,
10282                signature,
10283            } = &symbol.path
10284            {
10285                let new_signature = this.symbol_signature(&abs_path);
10286                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10287            }
10288            Ok(())
10289        })?;
10290        let buffer = this
10291            .update(&mut cx, |this, cx| {
10292                this.open_buffer_for_symbol(
10293                    &Symbol {
10294                        language_server_name: symbol.language_server_name,
10295                        source_worktree_id: symbol.source_worktree_id,
10296                        source_language_server_id: symbol.source_language_server_id,
10297                        path: symbol.path,
10298                        name: symbol.name,
10299                        kind: symbol.kind,
10300                        range: symbol.range,
10301                        label: CodeLabel::default(),
10302                        container_name: symbol.container_name,
10303                    },
10304                    cx,
10305                )
10306            })
10307            .await?;
10308
10309        this.update(&mut cx, |this, cx| {
10310            let is_private = buffer
10311                .read(cx)
10312                .file()
10313                .map(|f| f.is_private())
10314                .unwrap_or_default();
10315            if is_private {
10316                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10317            } else {
10318                this.buffer_store
10319                    .update(cx, |buffer_store, cx| {
10320                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10321                    })
10322                    .detach_and_log_err(cx);
10323                let buffer_id = buffer.read(cx).remote_id().to_proto();
10324                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10325            }
10326        })
10327    }
10328
10329    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10330        let mut hasher = Sha256::new();
10331        hasher.update(abs_path.to_string_lossy().as_bytes());
10332        hasher.update(self.nonce.to_be_bytes());
10333        hasher.finalize().as_slice().try_into().unwrap()
10334    }
10335
10336    pub async fn handle_get_project_symbols(
10337        this: Entity<Self>,
10338        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10339        mut cx: AsyncApp,
10340    ) -> Result<proto::GetProjectSymbolsResponse> {
10341        let symbols = this
10342            .update(&mut cx, |this, cx| {
10343                this.symbols(&envelope.payload.query, cx)
10344            })
10345            .await?;
10346
10347        Ok(proto::GetProjectSymbolsResponse {
10348            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10349        })
10350    }
10351
10352    pub async fn handle_restart_language_servers(
10353        this: Entity<Self>,
10354        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10355        mut cx: AsyncApp,
10356    ) -> Result<proto::Ack> {
10357        this.update(&mut cx, |lsp_store, cx| {
10358            let buffers =
10359                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10360            lsp_store.restart_language_servers_for_buffers(
10361                buffers,
10362                envelope
10363                    .payload
10364                    .only_servers
10365                    .into_iter()
10366                    .filter_map(|selector| {
10367                        Some(match selector.selector? {
10368                            proto::language_server_selector::Selector::ServerId(server_id) => {
10369                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10370                            }
10371                            proto::language_server_selector::Selector::Name(name) => {
10372                                LanguageServerSelector::Name(LanguageServerName(
10373                                    SharedString::from(name),
10374                                ))
10375                            }
10376                        })
10377                    })
10378                    .collect(),
10379                cx,
10380            );
10381        });
10382
10383        Ok(proto::Ack {})
10384    }
10385
10386    pub async fn handle_stop_language_servers(
10387        lsp_store: Entity<Self>,
10388        envelope: TypedEnvelope<proto::StopLanguageServers>,
10389        mut cx: AsyncApp,
10390    ) -> Result<proto::Ack> {
10391        lsp_store.update(&mut cx, |lsp_store, cx| {
10392            if envelope.payload.all
10393                && envelope.payload.also_servers.is_empty()
10394                && envelope.payload.buffer_ids.is_empty()
10395            {
10396                lsp_store.stop_all_language_servers(cx);
10397            } else {
10398                let buffers =
10399                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10400                lsp_store
10401                    .stop_language_servers_for_buffers(
10402                        buffers,
10403                        envelope
10404                            .payload
10405                            .also_servers
10406                            .into_iter()
10407                            .filter_map(|selector| {
10408                                Some(match selector.selector? {
10409                                    proto::language_server_selector::Selector::ServerId(
10410                                        server_id,
10411                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10412                                        server_id,
10413                                    )),
10414                                    proto::language_server_selector::Selector::Name(name) => {
10415                                        LanguageServerSelector::Name(LanguageServerName(
10416                                            SharedString::from(name),
10417                                        ))
10418                                    }
10419                                })
10420                            })
10421                            .collect(),
10422                        cx,
10423                    )
10424                    .detach_and_log_err(cx);
10425            }
10426        });
10427
10428        Ok(proto::Ack {})
10429    }
10430
10431    pub async fn handle_cancel_language_server_work(
10432        lsp_store: Entity<Self>,
10433        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10434        mut cx: AsyncApp,
10435    ) -> Result<proto::Ack> {
10436        lsp_store.update(&mut cx, |lsp_store, cx| {
10437            if let Some(work) = envelope.payload.work {
10438                match work {
10439                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10440                        let buffers =
10441                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10442                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10443                    }
10444                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10445                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10446                        let token = work
10447                            .token
10448                            .map(|token| {
10449                                ProgressToken::from_proto(token)
10450                                    .context("invalid work progress token")
10451                            })
10452                            .transpose()?;
10453                        lsp_store.cancel_language_server_work(server_id, token, cx);
10454                    }
10455                }
10456            }
10457            anyhow::Ok(())
10458        })?;
10459
10460        Ok(proto::Ack {})
10461    }
10462
10463    fn buffer_ids_to_buffers(
10464        &mut self,
10465        buffer_ids: impl Iterator<Item = u64>,
10466        cx: &mut Context<Self>,
10467    ) -> Vec<Entity<Buffer>> {
10468        buffer_ids
10469            .into_iter()
10470            .flat_map(|buffer_id| {
10471                self.buffer_store
10472                    .read(cx)
10473                    .get(BufferId::new(buffer_id).log_err()?)
10474            })
10475            .collect::<Vec<_>>()
10476    }
10477
10478    async fn handle_apply_additional_edits_for_completion(
10479        this: Entity<Self>,
10480        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10481        mut cx: AsyncApp,
10482    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10483        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10484            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10485            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10486            let completion = Self::deserialize_completion(
10487                envelope.payload.completion.context("invalid completion")?,
10488            )?;
10489            anyhow::Ok((buffer, completion))
10490        })?;
10491
10492        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10493            this.apply_additional_edits_for_completion(
10494                buffer,
10495                Rc::new(RefCell::new(Box::new([Completion {
10496                    replace_range: completion.replace_range,
10497                    new_text: completion.new_text,
10498                    source: completion.source,
10499                    documentation: None,
10500                    label: CodeLabel::default(),
10501                    match_start: None,
10502                    snippet_deduplication_key: None,
10503                    insert_text_mode: None,
10504                    icon_path: None,
10505                    confirm: None,
10506                }]))),
10507                0,
10508                false,
10509                cx,
10510            )
10511        });
10512
10513        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10514            transaction: apply_additional_edits
10515                .await?
10516                .as_ref()
10517                .map(language::proto::serialize_transaction),
10518        })
10519    }
10520
10521    pub fn last_formatting_failure(&self) -> Option<&str> {
10522        self.last_formatting_failure.as_deref()
10523    }
10524
10525    pub fn reset_last_formatting_failure(&mut self) {
10526        self.last_formatting_failure = None;
10527    }
10528
10529    pub fn environment_for_buffer(
10530        &self,
10531        buffer: &Entity<Buffer>,
10532        cx: &mut Context<Self>,
10533    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10534        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10535            environment.update(cx, |env, cx| {
10536                env.buffer_environment(buffer, &self.worktree_store, cx)
10537            })
10538        } else {
10539            Task::ready(None).shared()
10540        }
10541    }
10542
10543    pub fn format(
10544        &mut self,
10545        buffers: HashSet<Entity<Buffer>>,
10546        target: LspFormatTarget,
10547        push_to_history: bool,
10548        trigger: FormatTrigger,
10549        cx: &mut Context<Self>,
10550    ) -> Task<anyhow::Result<ProjectTransaction>> {
10551        let logger = zlog::scoped!("format");
10552        if self.as_local().is_some() {
10553            zlog::trace!(logger => "Formatting locally");
10554            let logger = zlog::scoped!(logger => "local");
10555            let buffers = buffers
10556                .into_iter()
10557                .map(|buffer_handle| {
10558                    let buffer = buffer_handle.read(cx);
10559                    let buffer_abs_path = File::from_dyn(buffer.file())
10560                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10561
10562                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10563                })
10564                .collect::<Vec<_>>();
10565
10566            cx.spawn(async move |lsp_store, cx| {
10567                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10568
10569                for (handle, abs_path, id) in buffers {
10570                    let env = lsp_store
10571                        .update(cx, |lsp_store, cx| {
10572                            lsp_store.environment_for_buffer(&handle, cx)
10573                        })?
10574                        .await;
10575
10576                    let ranges = match &target {
10577                        LspFormatTarget::Buffers => None,
10578                        LspFormatTarget::Ranges(ranges) => {
10579                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10580                        }
10581                    };
10582
10583                    formattable_buffers.push(FormattableBuffer {
10584                        handle,
10585                        abs_path,
10586                        env,
10587                        ranges,
10588                    });
10589                }
10590                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10591
10592                let format_timer = zlog::time!(logger => "Formatting buffers");
10593                let result = LocalLspStore::format_locally(
10594                    lsp_store.clone(),
10595                    formattable_buffers,
10596                    push_to_history,
10597                    trigger,
10598                    logger,
10599                    cx,
10600                )
10601                .await;
10602                format_timer.end();
10603
10604                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10605
10606                lsp_store.update(cx, |lsp_store, _| {
10607                    lsp_store.update_last_formatting_failure(&result);
10608                })?;
10609
10610                result
10611            })
10612        } else if let Some((client, project_id)) = self.upstream_client() {
10613            zlog::trace!(logger => "Formatting remotely");
10614            let logger = zlog::scoped!(logger => "remote");
10615
10616            let buffer_ranges = match &target {
10617                LspFormatTarget::Buffers => Vec::new(),
10618                LspFormatTarget::Ranges(ranges) => ranges
10619                    .iter()
10620                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10621                        buffer_id: buffer_id.to_proto(),
10622                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10623                    })
10624                    .collect(),
10625            };
10626
10627            let buffer_store = self.buffer_store();
10628            cx.spawn(async move |lsp_store, cx| {
10629                zlog::trace!(logger => "Sending remote format request");
10630                let request_timer = zlog::time!(logger => "remote format request");
10631                let result = client
10632                    .request(proto::FormatBuffers {
10633                        project_id,
10634                        trigger: trigger as i32,
10635                        buffer_ids: buffers
10636                            .iter()
10637                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10638                            .collect(),
10639                        buffer_ranges,
10640                    })
10641                    .await
10642                    .and_then(|result| result.transaction.context("missing transaction"));
10643                request_timer.end();
10644
10645                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10646
10647                lsp_store.update(cx, |lsp_store, _| {
10648                    lsp_store.update_last_formatting_failure(&result);
10649                })?;
10650
10651                let transaction_response = result?;
10652                let _timer = zlog::time!(logger => "deserializing project transaction");
10653                buffer_store
10654                    .update(cx, |buffer_store, cx| {
10655                        buffer_store.deserialize_project_transaction(
10656                            transaction_response,
10657                            push_to_history,
10658                            cx,
10659                        )
10660                    })
10661                    .await
10662            })
10663        } else {
10664            zlog::trace!(logger => "Not formatting");
10665            Task::ready(Ok(ProjectTransaction::default()))
10666        }
10667    }
10668
10669    async fn handle_format_buffers(
10670        this: Entity<Self>,
10671        envelope: TypedEnvelope<proto::FormatBuffers>,
10672        mut cx: AsyncApp,
10673    ) -> Result<proto::FormatBuffersResponse> {
10674        let sender_id = envelope.original_sender_id().unwrap_or_default();
10675        let format = this.update(&mut cx, |this, cx| {
10676            let mut buffers = HashSet::default();
10677            for buffer_id in &envelope.payload.buffer_ids {
10678                let buffer_id = BufferId::new(*buffer_id)?;
10679                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10680            }
10681
10682            let target = if envelope.payload.buffer_ranges.is_empty() {
10683                LspFormatTarget::Buffers
10684            } else {
10685                let mut ranges_map = BTreeMap::new();
10686                for buffer_range in &envelope.payload.buffer_ranges {
10687                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10688                    let ranges: Result<Vec<_>> = buffer_range
10689                        .ranges
10690                        .iter()
10691                        .map(|range| {
10692                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10693                        })
10694                        .collect();
10695                    ranges_map.insert(buffer_id, ranges?);
10696                }
10697                LspFormatTarget::Ranges(ranges_map)
10698            };
10699
10700            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10701            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10702        })?;
10703
10704        let project_transaction = format.await?;
10705        let project_transaction = this.update(&mut cx, |this, cx| {
10706            this.buffer_store.update(cx, |buffer_store, cx| {
10707                buffer_store.serialize_project_transaction_for_peer(
10708                    project_transaction,
10709                    sender_id,
10710                    cx,
10711                )
10712            })
10713        });
10714        Ok(proto::FormatBuffersResponse {
10715            transaction: Some(project_transaction),
10716        })
10717    }
10718
10719    async fn handle_apply_code_action_kind(
10720        this: Entity<Self>,
10721        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10722        mut cx: AsyncApp,
10723    ) -> Result<proto::ApplyCodeActionKindResponse> {
10724        let sender_id = envelope.original_sender_id().unwrap_or_default();
10725        let format = this.update(&mut cx, |this, cx| {
10726            let mut buffers = HashSet::default();
10727            for buffer_id in &envelope.payload.buffer_ids {
10728                let buffer_id = BufferId::new(*buffer_id)?;
10729                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10730            }
10731            let kind = match envelope.payload.kind.as_str() {
10732                "" => CodeActionKind::EMPTY,
10733                "quickfix" => CodeActionKind::QUICKFIX,
10734                "refactor" => CodeActionKind::REFACTOR,
10735                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10736                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10737                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10738                "source" => CodeActionKind::SOURCE,
10739                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10740                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10741                _ => anyhow::bail!(
10742                    "Invalid code action kind {}",
10743                    envelope.payload.kind.as_str()
10744                ),
10745            };
10746            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10747        })?;
10748
10749        let project_transaction = format.await?;
10750        let project_transaction = this.update(&mut cx, |this, cx| {
10751            this.buffer_store.update(cx, |buffer_store, cx| {
10752                buffer_store.serialize_project_transaction_for_peer(
10753                    project_transaction,
10754                    sender_id,
10755                    cx,
10756                )
10757            })
10758        });
10759        Ok(proto::ApplyCodeActionKindResponse {
10760            transaction: Some(project_transaction),
10761        })
10762    }
10763
10764    async fn shutdown_language_server(
10765        server_state: Option<LanguageServerState>,
10766        name: LanguageServerName,
10767        cx: &mut AsyncApp,
10768    ) {
10769        let server = match server_state {
10770            Some(LanguageServerState::Starting { startup, .. }) => {
10771                let mut timer = cx
10772                    .background_executor()
10773                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10774                    .fuse();
10775
10776                select! {
10777                    server = startup.fuse() => server,
10778                    () = timer => {
10779                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10780                        None
10781                    },
10782                }
10783            }
10784
10785            Some(LanguageServerState::Running { server, .. }) => Some(server),
10786
10787            None => None,
10788        };
10789
10790        let Some(server) = server else { return };
10791        if let Some(shutdown) = server.shutdown() {
10792            shutdown.await;
10793        }
10794    }
10795
10796    // Returns a list of all of the worktrees which no longer have a language server and the root path
10797    // for the stopped server
10798    fn stop_local_language_server(
10799        &mut self,
10800        server_id: LanguageServerId,
10801        cx: &mut Context<Self>,
10802    ) -> Task<()> {
10803        let local = match &mut self.mode {
10804            LspStoreMode::Local(local) => local,
10805            _ => {
10806                return Task::ready(());
10807            }
10808        };
10809
10810        // Remove this server ID from all entries in the given worktree.
10811        local
10812            .language_server_ids
10813            .retain(|_, state| state.id != server_id);
10814        self.buffer_store.update(cx, |buffer_store, cx| {
10815            for buffer in buffer_store.buffers() {
10816                buffer.update(cx, |buffer, cx| {
10817                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10818                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10819                });
10820            }
10821        });
10822
10823        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10824            summaries.retain(|path, summaries_by_server_id| {
10825                if summaries_by_server_id.remove(&server_id).is_some() {
10826                    if let Some((client, project_id)) = self.downstream_client.clone() {
10827                        client
10828                            .send(proto::UpdateDiagnosticSummary {
10829                                project_id,
10830                                worktree_id: worktree_id.to_proto(),
10831                                summary: Some(proto::DiagnosticSummary {
10832                                    path: path.as_ref().to_proto(),
10833                                    language_server_id: server_id.0 as u64,
10834                                    error_count: 0,
10835                                    warning_count: 0,
10836                                }),
10837                                more_summaries: Vec::new(),
10838                            })
10839                            .log_err();
10840                    }
10841                    !summaries_by_server_id.is_empty()
10842                } else {
10843                    true
10844                }
10845            });
10846        }
10847
10848        let local = self.as_local_mut().unwrap();
10849        for diagnostics in local.diagnostics.values_mut() {
10850            diagnostics.retain(|_, diagnostics_by_server_id| {
10851                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10852                    diagnostics_by_server_id.remove(ix);
10853                    !diagnostics_by_server_id.is_empty()
10854                } else {
10855                    true
10856                }
10857            });
10858        }
10859        local.language_server_watched_paths.remove(&server_id);
10860
10861        let server_state = local.language_servers.remove(&server_id);
10862        self.cleanup_lsp_data(server_id);
10863        let name = self
10864            .language_server_statuses
10865            .remove(&server_id)
10866            .map(|status| status.name)
10867            .or_else(|| {
10868                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10869                    Some(adapter.name())
10870                } else {
10871                    None
10872                }
10873            });
10874
10875        if let Some(name) = name {
10876            log::info!("stopping language server {name}");
10877            self.languages
10878                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10879            cx.notify();
10880
10881            return cx.spawn(async move |lsp_store, cx| {
10882                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10883                lsp_store
10884                    .update(cx, |lsp_store, cx| {
10885                        lsp_store
10886                            .languages
10887                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10888                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10889                        cx.notify();
10890                    })
10891                    .ok();
10892            });
10893        }
10894
10895        if server_state.is_some() {
10896            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10897        }
10898        Task::ready(())
10899    }
10900
10901    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10902        self.shutdown_all_language_servers(cx).detach();
10903    }
10904
10905    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10906        if let Some((client, project_id)) = self.upstream_client() {
10907            let request = client.request(proto::StopLanguageServers {
10908                project_id,
10909                buffer_ids: Vec::new(),
10910                also_servers: Vec::new(),
10911                all: true,
10912            });
10913            cx.background_spawn(async move {
10914                request.await.ok();
10915            })
10916        } else {
10917            let Some(local) = self.as_local_mut() else {
10918                return Task::ready(());
10919            };
10920            let language_servers_to_stop = local
10921                .language_server_ids
10922                .values()
10923                .map(|state| state.id)
10924                .collect();
10925            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10926            let tasks = language_servers_to_stop
10927                .into_iter()
10928                .map(|server| self.stop_local_language_server(server, cx))
10929                .collect::<Vec<_>>();
10930            cx.background_spawn(async move {
10931                futures::future::join_all(tasks).await;
10932            })
10933        }
10934    }
10935
10936    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10937        let buffers = self.buffer_store.read(cx).buffers().collect();
10938        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10939    }
10940
10941    pub fn restart_language_servers_for_buffers(
10942        &mut self,
10943        buffers: Vec<Entity<Buffer>>,
10944        only_restart_servers: HashSet<LanguageServerSelector>,
10945        cx: &mut Context<Self>,
10946    ) {
10947        if let Some((client, project_id)) = self.upstream_client() {
10948            let request = client.request(proto::RestartLanguageServers {
10949                project_id,
10950                buffer_ids: buffers
10951                    .into_iter()
10952                    .map(|b| b.read(cx).remote_id().to_proto())
10953                    .collect(),
10954                only_servers: only_restart_servers
10955                    .into_iter()
10956                    .map(|selector| {
10957                        let selector = match selector {
10958                            LanguageServerSelector::Id(language_server_id) => {
10959                                proto::language_server_selector::Selector::ServerId(
10960                                    language_server_id.to_proto(),
10961                                )
10962                            }
10963                            LanguageServerSelector::Name(language_server_name) => {
10964                                proto::language_server_selector::Selector::Name(
10965                                    language_server_name.to_string(),
10966                                )
10967                            }
10968                        };
10969                        proto::LanguageServerSelector {
10970                            selector: Some(selector),
10971                        }
10972                    })
10973                    .collect(),
10974                all: false,
10975            });
10976            cx.background_spawn(request).detach_and_log_err(cx);
10977        } else {
10978            let stop_task = if only_restart_servers.is_empty() {
10979                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10980            } else {
10981                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10982            };
10983            cx.spawn(async move |lsp_store, cx| {
10984                stop_task.await;
10985                lsp_store.update(cx, |lsp_store, cx| {
10986                    for buffer in buffers {
10987                        lsp_store.register_buffer_with_language_servers(
10988                            &buffer,
10989                            only_restart_servers.clone(),
10990                            true,
10991                            cx,
10992                        );
10993                    }
10994                })
10995            })
10996            .detach();
10997        }
10998    }
10999
11000    pub fn stop_language_servers_for_buffers(
11001        &mut self,
11002        buffers: Vec<Entity<Buffer>>,
11003        also_stop_servers: HashSet<LanguageServerSelector>,
11004        cx: &mut Context<Self>,
11005    ) -> Task<Result<()>> {
11006        if let Some((client, project_id)) = self.upstream_client() {
11007            let request = client.request(proto::StopLanguageServers {
11008                project_id,
11009                buffer_ids: buffers
11010                    .into_iter()
11011                    .map(|b| b.read(cx).remote_id().to_proto())
11012                    .collect(),
11013                also_servers: also_stop_servers
11014                    .into_iter()
11015                    .map(|selector| {
11016                        let selector = match selector {
11017                            LanguageServerSelector::Id(language_server_id) => {
11018                                proto::language_server_selector::Selector::ServerId(
11019                                    language_server_id.to_proto(),
11020                                )
11021                            }
11022                            LanguageServerSelector::Name(language_server_name) => {
11023                                proto::language_server_selector::Selector::Name(
11024                                    language_server_name.to_string(),
11025                                )
11026                            }
11027                        };
11028                        proto::LanguageServerSelector {
11029                            selector: Some(selector),
11030                        }
11031                    })
11032                    .collect(),
11033                all: false,
11034            });
11035            cx.background_spawn(async move {
11036                let _ = request.await?;
11037                Ok(())
11038            })
11039        } else {
11040            let task =
11041                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11042            cx.background_spawn(async move {
11043                task.await;
11044                Ok(())
11045            })
11046        }
11047    }
11048
11049    fn stop_local_language_servers_for_buffers(
11050        &mut self,
11051        buffers: &[Entity<Buffer>],
11052        also_stop_servers: HashSet<LanguageServerSelector>,
11053        cx: &mut Context<Self>,
11054    ) -> Task<()> {
11055        let Some(local) = self.as_local_mut() else {
11056            return Task::ready(());
11057        };
11058        let mut language_server_names_to_stop = BTreeSet::default();
11059        let mut language_servers_to_stop = also_stop_servers
11060            .into_iter()
11061            .flat_map(|selector| match selector {
11062                LanguageServerSelector::Id(id) => Some(id),
11063                LanguageServerSelector::Name(name) => {
11064                    language_server_names_to_stop.insert(name);
11065                    None
11066                }
11067            })
11068            .collect::<BTreeSet<_>>();
11069
11070        let mut covered_worktrees = HashSet::default();
11071        for buffer in buffers {
11072            buffer.update(cx, |buffer, cx| {
11073                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11074                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11075                    && covered_worktrees.insert(worktree_id)
11076                {
11077                    language_server_names_to_stop.retain(|name| {
11078                        let old_ids_count = language_servers_to_stop.len();
11079                        let all_language_servers_with_this_name = local
11080                            .language_server_ids
11081                            .iter()
11082                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11083                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11084                        old_ids_count == language_servers_to_stop.len()
11085                    });
11086                }
11087            });
11088        }
11089        for name in language_server_names_to_stop {
11090            language_servers_to_stop.extend(
11091                local
11092                    .language_server_ids
11093                    .iter()
11094                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11095            );
11096        }
11097
11098        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11099        let tasks = language_servers_to_stop
11100            .into_iter()
11101            .map(|server| self.stop_local_language_server(server, cx))
11102            .collect::<Vec<_>>();
11103
11104        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11105    }
11106
11107    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11108        let (worktree, relative_path) =
11109            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11110
11111        let project_path = ProjectPath {
11112            worktree_id: worktree.read(cx).id(),
11113            path: relative_path,
11114        };
11115
11116        Some(
11117            self.buffer_store()
11118                .read(cx)
11119                .get_by_path(&project_path)?
11120                .read(cx),
11121        )
11122    }
11123
11124    #[cfg(any(test, feature = "test-support"))]
11125    pub fn update_diagnostics(
11126        &mut self,
11127        server_id: LanguageServerId,
11128        diagnostics: lsp::PublishDiagnosticsParams,
11129        result_id: Option<SharedString>,
11130        source_kind: DiagnosticSourceKind,
11131        disk_based_sources: &[String],
11132        cx: &mut Context<Self>,
11133    ) -> Result<()> {
11134        self.merge_lsp_diagnostics(
11135            source_kind,
11136            vec![DocumentDiagnosticsUpdate {
11137                diagnostics,
11138                result_id,
11139                server_id,
11140                disk_based_sources: Cow::Borrowed(disk_based_sources),
11141                registration_id: None,
11142            }],
11143            |_, _, _| false,
11144            cx,
11145        )
11146    }
11147
11148    pub fn merge_lsp_diagnostics(
11149        &mut self,
11150        source_kind: DiagnosticSourceKind,
11151        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11152        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11153        cx: &mut Context<Self>,
11154    ) -> Result<()> {
11155        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11156        let updates = lsp_diagnostics
11157            .into_iter()
11158            .filter_map(|update| {
11159                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11160                Some(DocumentDiagnosticsUpdate {
11161                    diagnostics: self.lsp_to_document_diagnostics(
11162                        abs_path,
11163                        source_kind,
11164                        update.server_id,
11165                        update.diagnostics,
11166                        &update.disk_based_sources,
11167                        update.registration_id.clone(),
11168                    ),
11169                    result_id: update.result_id,
11170                    server_id: update.server_id,
11171                    disk_based_sources: update.disk_based_sources,
11172                    registration_id: update.registration_id,
11173                })
11174            })
11175            .collect();
11176        self.merge_diagnostic_entries(updates, merge, cx)?;
11177        Ok(())
11178    }
11179
11180    fn lsp_to_document_diagnostics(
11181        &mut self,
11182        document_abs_path: PathBuf,
11183        source_kind: DiagnosticSourceKind,
11184        server_id: LanguageServerId,
11185        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11186        disk_based_sources: &[String],
11187        registration_id: Option<SharedString>,
11188    ) -> DocumentDiagnostics {
11189        let mut diagnostics = Vec::default();
11190        let mut primary_diagnostic_group_ids = HashMap::default();
11191        let mut sources_by_group_id = HashMap::default();
11192        let mut supporting_diagnostics = HashMap::default();
11193
11194        let adapter = self.language_server_adapter_for_id(server_id);
11195
11196        // Ensure that primary diagnostics are always the most severe
11197        lsp_diagnostics
11198            .diagnostics
11199            .sort_by_key(|item| item.severity);
11200
11201        for diagnostic in &lsp_diagnostics.diagnostics {
11202            let source = diagnostic.source.as_ref();
11203            let range = range_from_lsp(diagnostic.range);
11204            let is_supporting = diagnostic
11205                .related_information
11206                .as_ref()
11207                .is_some_and(|infos| {
11208                    infos.iter().any(|info| {
11209                        primary_diagnostic_group_ids.contains_key(&(
11210                            source,
11211                            diagnostic.code.clone(),
11212                            range_from_lsp(info.location.range),
11213                        ))
11214                    })
11215                });
11216
11217            let is_unnecessary = diagnostic
11218                .tags
11219                .as_ref()
11220                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11221
11222            let underline = self
11223                .language_server_adapter_for_id(server_id)
11224                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11225
11226            if is_supporting {
11227                supporting_diagnostics.insert(
11228                    (source, diagnostic.code.clone(), range),
11229                    (diagnostic.severity, is_unnecessary),
11230                );
11231            } else {
11232                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11233                let is_disk_based =
11234                    source.is_some_and(|source| disk_based_sources.contains(source));
11235
11236                sources_by_group_id.insert(group_id, source);
11237                primary_diagnostic_group_ids
11238                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11239
11240                diagnostics.push(DiagnosticEntry {
11241                    range,
11242                    diagnostic: Diagnostic {
11243                        source: diagnostic.source.clone(),
11244                        source_kind,
11245                        code: diagnostic.code.clone(),
11246                        code_description: diagnostic
11247                            .code_description
11248                            .as_ref()
11249                            .and_then(|d| d.href.clone()),
11250                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11251                        markdown: adapter.as_ref().and_then(|adapter| {
11252                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11253                        }),
11254                        message: diagnostic.message.trim().to_string(),
11255                        group_id,
11256                        is_primary: true,
11257                        is_disk_based,
11258                        is_unnecessary,
11259                        underline,
11260                        data: diagnostic.data.clone(),
11261                        registration_id: registration_id.clone(),
11262                    },
11263                });
11264                if let Some(infos) = &diagnostic.related_information {
11265                    for info in infos {
11266                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11267                            let range = range_from_lsp(info.location.range);
11268                            diagnostics.push(DiagnosticEntry {
11269                                range,
11270                                diagnostic: Diagnostic {
11271                                    source: diagnostic.source.clone(),
11272                                    source_kind,
11273                                    code: diagnostic.code.clone(),
11274                                    code_description: diagnostic
11275                                        .code_description
11276                                        .as_ref()
11277                                        .and_then(|d| d.href.clone()),
11278                                    severity: DiagnosticSeverity::INFORMATION,
11279                                    markdown: adapter.as_ref().and_then(|adapter| {
11280                                        adapter.diagnostic_message_to_markdown(&info.message)
11281                                    }),
11282                                    message: info.message.trim().to_string(),
11283                                    group_id,
11284                                    is_primary: false,
11285                                    is_disk_based,
11286                                    is_unnecessary: false,
11287                                    underline,
11288                                    data: diagnostic.data.clone(),
11289                                    registration_id: registration_id.clone(),
11290                                },
11291                            });
11292                        }
11293                    }
11294                }
11295            }
11296        }
11297
11298        for entry in &mut diagnostics {
11299            let diagnostic = &mut entry.diagnostic;
11300            if !diagnostic.is_primary {
11301                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11302                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11303                    source,
11304                    diagnostic.code.clone(),
11305                    entry.range.clone(),
11306                )) {
11307                    if let Some(severity) = severity {
11308                        diagnostic.severity = severity;
11309                    }
11310                    diagnostic.is_unnecessary = is_unnecessary;
11311                }
11312            }
11313        }
11314
11315        DocumentDiagnostics {
11316            diagnostics,
11317            document_abs_path,
11318            version: lsp_diagnostics.version,
11319        }
11320    }
11321
11322    fn insert_newly_running_language_server(
11323        &mut self,
11324        adapter: Arc<CachedLspAdapter>,
11325        language_server: Arc<LanguageServer>,
11326        server_id: LanguageServerId,
11327        key: LanguageServerSeed,
11328        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11329        cx: &mut Context<Self>,
11330    ) {
11331        let Some(local) = self.as_local_mut() else {
11332            return;
11333        };
11334        // If the language server for this key doesn't match the server id, don't store the
11335        // server. Which will cause it to be dropped, killing the process
11336        if local
11337            .language_server_ids
11338            .get(&key)
11339            .map(|state| state.id != server_id)
11340            .unwrap_or(false)
11341        {
11342            return;
11343        }
11344
11345        // Update language_servers collection with Running variant of LanguageServerState
11346        // indicating that the server is up and running and ready
11347        let workspace_folders = workspace_folders.lock().clone();
11348        language_server.set_workspace_folders(workspace_folders);
11349
11350        let workspace_diagnostics_refresh_tasks = language_server
11351            .capabilities()
11352            .diagnostic_provider
11353            .and_then(|provider| {
11354                local
11355                    .language_server_dynamic_registrations
11356                    .entry(server_id)
11357                    .or_default()
11358                    .diagnostics
11359                    .entry(None)
11360                    .or_insert(provider.clone());
11361                let workspace_refresher =
11362                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11363
11364                Some((None, workspace_refresher))
11365            })
11366            .into_iter()
11367            .collect();
11368        local.language_servers.insert(
11369            server_id,
11370            LanguageServerState::Running {
11371                workspace_diagnostics_refresh_tasks,
11372                adapter: adapter.clone(),
11373                server: language_server.clone(),
11374                simulate_disk_based_diagnostics_completion: None,
11375            },
11376        );
11377        local
11378            .languages
11379            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11380        if let Some(file_ops_caps) = language_server
11381            .capabilities()
11382            .workspace
11383            .as_ref()
11384            .and_then(|ws| ws.file_operations.as_ref())
11385        {
11386            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11387            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11388            if did_rename_caps.or(will_rename_caps).is_some() {
11389                let watcher = RenamePathsWatchedForServer::default()
11390                    .with_did_rename_patterns(did_rename_caps)
11391                    .with_will_rename_patterns(will_rename_caps);
11392                local
11393                    .language_server_paths_watched_for_rename
11394                    .insert(server_id, watcher);
11395            }
11396        }
11397
11398        self.language_server_statuses.insert(
11399            server_id,
11400            LanguageServerStatus {
11401                name: language_server.name(),
11402                server_version: language_server.version(),
11403                pending_work: Default::default(),
11404                has_pending_diagnostic_updates: false,
11405                progress_tokens: Default::default(),
11406                worktree: Some(key.worktree_id),
11407                binary: Some(language_server.binary().clone()),
11408                configuration: Some(language_server.configuration().clone()),
11409                workspace_folders: language_server.workspace_folders(),
11410                process_id: language_server.process_id(),
11411            },
11412        );
11413
11414        cx.emit(LspStoreEvent::LanguageServerAdded(
11415            server_id,
11416            language_server.name(),
11417            Some(key.worktree_id),
11418        ));
11419
11420        let server_capabilities = language_server.capabilities();
11421        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11422            downstream_client
11423                .send(proto::StartLanguageServer {
11424                    project_id: *project_id,
11425                    server: Some(proto::LanguageServer {
11426                        id: server_id.to_proto(),
11427                        name: language_server.name().to_string(),
11428                        worktree_id: Some(key.worktree_id.to_proto()),
11429                    }),
11430                    capabilities: serde_json::to_string(&server_capabilities)
11431                        .expect("serializing server LSP capabilities"),
11432                })
11433                .log_err();
11434        }
11435        self.lsp_server_capabilities
11436            .insert(server_id, server_capabilities);
11437
11438        // Tell the language server about every open buffer in the worktree that matches the language.
11439        // Also check for buffers in worktrees that reused this server
11440        let mut worktrees_using_server = vec![key.worktree_id];
11441        if let Some(local) = self.as_local() {
11442            // Find all worktrees that have this server in their language server tree
11443            for (worktree_id, servers) in &local.lsp_tree.instances {
11444                if *worktree_id != key.worktree_id {
11445                    for server_map in servers.roots.values() {
11446                        if server_map
11447                            .values()
11448                            .any(|(node, _)| node.id() == Some(server_id))
11449                        {
11450                            worktrees_using_server.push(*worktree_id);
11451                        }
11452                    }
11453                }
11454            }
11455        }
11456
11457        let mut buffer_paths_registered = Vec::new();
11458        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11459            let mut lsp_adapters = HashMap::default();
11460            for buffer_handle in buffer_store.buffers() {
11461                let buffer = buffer_handle.read(cx);
11462                let file = match File::from_dyn(buffer.file()) {
11463                    Some(file) => file,
11464                    None => continue,
11465                };
11466                let language = match buffer.language() {
11467                    Some(language) => language,
11468                    None => continue,
11469                };
11470
11471                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11472                    || !lsp_adapters
11473                        .entry(language.name())
11474                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11475                        .iter()
11476                        .any(|a| a.name == key.name)
11477                {
11478                    continue;
11479                }
11480                // didOpen
11481                let file = match file.as_local() {
11482                    Some(file) => file,
11483                    None => continue,
11484                };
11485
11486                let local = self.as_local_mut().unwrap();
11487
11488                let buffer_id = buffer.remote_id();
11489                if local.registered_buffers.contains_key(&buffer_id) {
11490                    let abs_path = file.abs_path(cx);
11491                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11492                        Ok(uri) => uri,
11493                        Err(()) => {
11494                            log::error!("failed to convert path to URI: {:?}", abs_path);
11495                            continue;
11496                        }
11497                    };
11498
11499                    let versions = local
11500                        .buffer_snapshots
11501                        .entry(buffer_id)
11502                        .or_default()
11503                        .entry(server_id)
11504                        .and_modify(|_| {
11505                            assert!(
11506                            false,
11507                            "There should not be an existing snapshot for a newly inserted buffer"
11508                        )
11509                        })
11510                        .or_insert_with(|| {
11511                            vec![LspBufferSnapshot {
11512                                version: 0,
11513                                snapshot: buffer.text_snapshot(),
11514                            }]
11515                        });
11516
11517                    let snapshot = versions.last().unwrap();
11518                    let version = snapshot.version;
11519                    let initial_snapshot = &snapshot.snapshot;
11520                    language_server.register_buffer(
11521                        uri,
11522                        adapter.language_id(&language.name()),
11523                        version,
11524                        initial_snapshot.text(),
11525                    );
11526                    buffer_paths_registered.push((buffer_id, abs_path));
11527                    local
11528                        .buffers_opened_in_servers
11529                        .entry(buffer_id)
11530                        .or_default()
11531                        .insert(server_id);
11532                }
11533                buffer_handle.update(cx, |buffer, cx| {
11534                    buffer.set_completion_triggers(
11535                        server_id,
11536                        language_server
11537                            .capabilities()
11538                            .completion_provider
11539                            .as_ref()
11540                            .and_then(|provider| {
11541                                provider
11542                                    .trigger_characters
11543                                    .as_ref()
11544                                    .map(|characters| characters.iter().cloned().collect())
11545                            })
11546                            .unwrap_or_default(),
11547                        cx,
11548                    )
11549                });
11550            }
11551        });
11552
11553        for (buffer_id, abs_path) in buffer_paths_registered {
11554            cx.emit(LspStoreEvent::LanguageServerUpdate {
11555                language_server_id: server_id,
11556                name: Some(adapter.name()),
11557                message: proto::update_language_server::Variant::RegisteredForBuffer(
11558                    proto::RegisteredForBuffer {
11559                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11560                        buffer_id: buffer_id.to_proto(),
11561                    },
11562                ),
11563            });
11564        }
11565
11566        cx.notify();
11567    }
11568
11569    pub fn language_servers_running_disk_based_diagnostics(
11570        &self,
11571    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11572        self.language_server_statuses
11573            .iter()
11574            .filter_map(|(id, status)| {
11575                if status.has_pending_diagnostic_updates {
11576                    Some(*id)
11577                } else {
11578                    None
11579                }
11580            })
11581    }
11582
11583    pub(crate) fn cancel_language_server_work_for_buffers(
11584        &mut self,
11585        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11586        cx: &mut Context<Self>,
11587    ) {
11588        if let Some((client, project_id)) = self.upstream_client() {
11589            let request = client.request(proto::CancelLanguageServerWork {
11590                project_id,
11591                work: Some(proto::cancel_language_server_work::Work::Buffers(
11592                    proto::cancel_language_server_work::Buffers {
11593                        buffer_ids: buffers
11594                            .into_iter()
11595                            .map(|b| b.read(cx).remote_id().to_proto())
11596                            .collect(),
11597                    },
11598                )),
11599            });
11600            cx.background_spawn(request).detach_and_log_err(cx);
11601        } else if let Some(local) = self.as_local() {
11602            let servers = buffers
11603                .into_iter()
11604                .flat_map(|buffer| {
11605                    buffer.update(cx, |buffer, cx| {
11606                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11607                    })
11608                })
11609                .collect::<HashSet<_>>();
11610            for server_id in servers {
11611                self.cancel_language_server_work(server_id, None, cx);
11612            }
11613        }
11614    }
11615
11616    pub(crate) fn cancel_language_server_work(
11617        &mut self,
11618        server_id: LanguageServerId,
11619        token_to_cancel: Option<ProgressToken>,
11620        cx: &mut Context<Self>,
11621    ) {
11622        if let Some(local) = self.as_local() {
11623            let status = self.language_server_statuses.get(&server_id);
11624            let server = local.language_servers.get(&server_id);
11625            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11626            {
11627                for (token, progress) in &status.pending_work {
11628                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11629                        && token != token_to_cancel
11630                    {
11631                        continue;
11632                    }
11633                    if progress.is_cancellable {
11634                        server
11635                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11636                                WorkDoneProgressCancelParams {
11637                                    token: token.to_lsp(),
11638                                },
11639                            )
11640                            .ok();
11641                    }
11642                }
11643            }
11644        } else if let Some((client, project_id)) = self.upstream_client() {
11645            let request = client.request(proto::CancelLanguageServerWork {
11646                project_id,
11647                work: Some(
11648                    proto::cancel_language_server_work::Work::LanguageServerWork(
11649                        proto::cancel_language_server_work::LanguageServerWork {
11650                            language_server_id: server_id.to_proto(),
11651                            token: token_to_cancel.map(|token| token.to_proto()),
11652                        },
11653                    ),
11654                ),
11655            });
11656            cx.background_spawn(request).detach_and_log_err(cx);
11657        }
11658    }
11659
11660    fn register_supplementary_language_server(
11661        &mut self,
11662        id: LanguageServerId,
11663        name: LanguageServerName,
11664        server: Arc<LanguageServer>,
11665        cx: &mut Context<Self>,
11666    ) {
11667        if let Some(local) = self.as_local_mut() {
11668            local
11669                .supplementary_language_servers
11670                .insert(id, (name.clone(), server));
11671            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11672        }
11673    }
11674
11675    fn unregister_supplementary_language_server(
11676        &mut self,
11677        id: LanguageServerId,
11678        cx: &mut Context<Self>,
11679    ) {
11680        if let Some(local) = self.as_local_mut() {
11681            local.supplementary_language_servers.remove(&id);
11682            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11683        }
11684    }
11685
11686    pub(crate) fn supplementary_language_servers(
11687        &self,
11688    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11689        self.as_local().into_iter().flat_map(|local| {
11690            local
11691                .supplementary_language_servers
11692                .iter()
11693                .map(|(id, (name, _))| (*id, name.clone()))
11694        })
11695    }
11696
11697    pub fn language_server_adapter_for_id(
11698        &self,
11699        id: LanguageServerId,
11700    ) -> Option<Arc<CachedLspAdapter>> {
11701        self.as_local()
11702            .and_then(|local| local.language_servers.get(&id))
11703            .and_then(|language_server_state| match language_server_state {
11704                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11705                _ => None,
11706            })
11707    }
11708
11709    pub(super) fn update_local_worktree_language_servers(
11710        &mut self,
11711        worktree_handle: &Entity<Worktree>,
11712        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11713        cx: &mut Context<Self>,
11714    ) {
11715        if changes.is_empty() {
11716            return;
11717        }
11718
11719        let Some(local) = self.as_local() else { return };
11720
11721        local.prettier_store.update(cx, |prettier_store, cx| {
11722            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11723        });
11724
11725        let worktree_id = worktree_handle.read(cx).id();
11726        let mut language_server_ids = local
11727            .language_server_ids
11728            .iter()
11729            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11730            .collect::<Vec<_>>();
11731        language_server_ids.sort();
11732        language_server_ids.dedup();
11733
11734        // let abs_path = worktree_handle.read(cx).abs_path();
11735        for server_id in &language_server_ids {
11736            if let Some(LanguageServerState::Running { server, .. }) =
11737                local.language_servers.get(server_id)
11738                && let Some(watched_paths) = local
11739                    .language_server_watched_paths
11740                    .get(server_id)
11741                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11742            {
11743                let params = lsp::DidChangeWatchedFilesParams {
11744                    changes: changes
11745                        .iter()
11746                        .filter_map(|(path, _, change)| {
11747                            if !watched_paths.is_match(path.as_std_path()) {
11748                                return None;
11749                            }
11750                            let typ = match change {
11751                                PathChange::Loaded => return None,
11752                                PathChange::Added => lsp::FileChangeType::CREATED,
11753                                PathChange::Removed => lsp::FileChangeType::DELETED,
11754                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11755                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11756                            };
11757                            let uri = lsp::Uri::from_file_path(
11758                                worktree_handle.read(cx).absolutize(&path),
11759                            )
11760                            .ok()?;
11761                            Some(lsp::FileEvent { uri, typ })
11762                        })
11763                        .collect(),
11764                };
11765                if !params.changes.is_empty() {
11766                    server
11767                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11768                        .ok();
11769                }
11770            }
11771        }
11772        for (path, _, _) in changes {
11773            if let Some(file_name) = path.file_name()
11774                && local.watched_manifest_filenames.contains(file_name)
11775            {
11776                self.request_workspace_config_refresh();
11777                break;
11778            }
11779        }
11780    }
11781
11782    pub fn wait_for_remote_buffer(
11783        &mut self,
11784        id: BufferId,
11785        cx: &mut Context<Self>,
11786    ) -> Task<Result<Entity<Buffer>>> {
11787        self.buffer_store.update(cx, |buffer_store, cx| {
11788            buffer_store.wait_for_remote_buffer(id, cx)
11789        })
11790    }
11791
11792    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11793        let mut result = proto::Symbol {
11794            language_server_name: symbol.language_server_name.0.to_string(),
11795            source_worktree_id: symbol.source_worktree_id.to_proto(),
11796            language_server_id: symbol.source_language_server_id.to_proto(),
11797            name: symbol.name.clone(),
11798            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11799            start: Some(proto::PointUtf16 {
11800                row: symbol.range.start.0.row,
11801                column: symbol.range.start.0.column,
11802            }),
11803            end: Some(proto::PointUtf16 {
11804                row: symbol.range.end.0.row,
11805                column: symbol.range.end.0.column,
11806            }),
11807            worktree_id: Default::default(),
11808            path: Default::default(),
11809            signature: Default::default(),
11810            container_name: symbol.container_name.clone(),
11811        };
11812        match &symbol.path {
11813            SymbolLocation::InProject(path) => {
11814                result.worktree_id = path.worktree_id.to_proto();
11815                result.path = path.path.to_proto();
11816            }
11817            SymbolLocation::OutsideProject {
11818                abs_path,
11819                signature,
11820            } => {
11821                result.path = abs_path.to_string_lossy().into_owned();
11822                result.signature = signature.to_vec();
11823            }
11824        }
11825        result
11826    }
11827
11828    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11829        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11830        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11831        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11832
11833        let path = if serialized_symbol.signature.is_empty() {
11834            SymbolLocation::InProject(ProjectPath {
11835                worktree_id,
11836                path: RelPath::from_proto(&serialized_symbol.path)
11837                    .context("invalid symbol path")?,
11838            })
11839        } else {
11840            SymbolLocation::OutsideProject {
11841                abs_path: Path::new(&serialized_symbol.path).into(),
11842                signature: serialized_symbol
11843                    .signature
11844                    .try_into()
11845                    .map_err(|_| anyhow!("invalid signature"))?,
11846            }
11847        };
11848
11849        let start = serialized_symbol.start.context("invalid start")?;
11850        let end = serialized_symbol.end.context("invalid end")?;
11851        Ok(CoreSymbol {
11852            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11853            source_worktree_id,
11854            source_language_server_id: LanguageServerId::from_proto(
11855                serialized_symbol.language_server_id,
11856            ),
11857            path,
11858            name: serialized_symbol.name,
11859            range: Unclipped(PointUtf16::new(start.row, start.column))
11860                ..Unclipped(PointUtf16::new(end.row, end.column)),
11861            kind,
11862            container_name: serialized_symbol.container_name,
11863        })
11864    }
11865
11866    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11867        let mut serialized_completion = proto::Completion {
11868            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11869            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11870            new_text: completion.new_text.clone(),
11871            ..proto::Completion::default()
11872        };
11873        match &completion.source {
11874            CompletionSource::Lsp {
11875                insert_range,
11876                server_id,
11877                lsp_completion,
11878                lsp_defaults,
11879                resolved,
11880            } => {
11881                let (old_insert_start, old_insert_end) = insert_range
11882                    .as_ref()
11883                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11884                    .unzip();
11885
11886                serialized_completion.old_insert_start = old_insert_start;
11887                serialized_completion.old_insert_end = old_insert_end;
11888                serialized_completion.source = proto::completion::Source::Lsp as i32;
11889                serialized_completion.server_id = server_id.0 as u64;
11890                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11891                serialized_completion.lsp_defaults = lsp_defaults
11892                    .as_deref()
11893                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11894                serialized_completion.resolved = *resolved;
11895            }
11896            CompletionSource::BufferWord {
11897                word_range,
11898                resolved,
11899            } => {
11900                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11901                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11902                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11903                serialized_completion.resolved = *resolved;
11904            }
11905            CompletionSource::Custom => {
11906                serialized_completion.source = proto::completion::Source::Custom as i32;
11907                serialized_completion.resolved = true;
11908            }
11909            CompletionSource::Dap { sort_text } => {
11910                serialized_completion.source = proto::completion::Source::Dap as i32;
11911                serialized_completion.sort_text = Some(sort_text.clone());
11912            }
11913        }
11914
11915        serialized_completion
11916    }
11917
11918    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11919        let old_replace_start = completion
11920            .old_replace_start
11921            .and_then(deserialize_anchor)
11922            .context("invalid old start")?;
11923        let old_replace_end = completion
11924            .old_replace_end
11925            .and_then(deserialize_anchor)
11926            .context("invalid old end")?;
11927        let insert_range = {
11928            match completion.old_insert_start.zip(completion.old_insert_end) {
11929                Some((start, end)) => {
11930                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11931                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11932                    Some(start..end)
11933                }
11934                None => None,
11935            }
11936        };
11937        Ok(CoreCompletion {
11938            replace_range: old_replace_start..old_replace_end,
11939            new_text: completion.new_text,
11940            source: match proto::completion::Source::from_i32(completion.source) {
11941                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11942                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11943                    insert_range,
11944                    server_id: LanguageServerId::from_proto(completion.server_id),
11945                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11946                    lsp_defaults: completion
11947                        .lsp_defaults
11948                        .as_deref()
11949                        .map(serde_json::from_slice)
11950                        .transpose()?,
11951                    resolved: completion.resolved,
11952                },
11953                Some(proto::completion::Source::BufferWord) => {
11954                    let word_range = completion
11955                        .buffer_word_start
11956                        .and_then(deserialize_anchor)
11957                        .context("invalid buffer word start")?
11958                        ..completion
11959                            .buffer_word_end
11960                            .and_then(deserialize_anchor)
11961                            .context("invalid buffer word end")?;
11962                    CompletionSource::BufferWord {
11963                        word_range,
11964                        resolved: completion.resolved,
11965                    }
11966                }
11967                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11968                    sort_text: completion
11969                        .sort_text
11970                        .context("expected sort text to exist")?,
11971                },
11972                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11973            },
11974        })
11975    }
11976
11977    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11978        let (kind, lsp_action) = match &action.lsp_action {
11979            LspAction::Action(code_action) => (
11980                proto::code_action::Kind::Action as i32,
11981                serde_json::to_vec(code_action).unwrap(),
11982            ),
11983            LspAction::Command(command) => (
11984                proto::code_action::Kind::Command as i32,
11985                serde_json::to_vec(command).unwrap(),
11986            ),
11987            LspAction::CodeLens(code_lens) => (
11988                proto::code_action::Kind::CodeLens as i32,
11989                serde_json::to_vec(code_lens).unwrap(),
11990            ),
11991        };
11992
11993        proto::CodeAction {
11994            server_id: action.server_id.0 as u64,
11995            start: Some(serialize_anchor(&action.range.start)),
11996            end: Some(serialize_anchor(&action.range.end)),
11997            lsp_action,
11998            kind,
11999            resolved: action.resolved,
12000        }
12001    }
12002
12003    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12004        let start = action
12005            .start
12006            .and_then(deserialize_anchor)
12007            .context("invalid start")?;
12008        let end = action
12009            .end
12010            .and_then(deserialize_anchor)
12011            .context("invalid end")?;
12012        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12013            Some(proto::code_action::Kind::Action) => {
12014                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12015            }
12016            Some(proto::code_action::Kind::Command) => {
12017                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12018            }
12019            Some(proto::code_action::Kind::CodeLens) => {
12020                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12021            }
12022            None => anyhow::bail!("Unknown action kind {}", action.kind),
12023        };
12024        Ok(CodeAction {
12025            server_id: LanguageServerId(action.server_id as usize),
12026            range: start..end,
12027            resolved: action.resolved,
12028            lsp_action,
12029        })
12030    }
12031
12032    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12033        match &formatting_result {
12034            Ok(_) => self.last_formatting_failure = None,
12035            Err(error) => {
12036                let error_string = format!("{error:#}");
12037                log::error!("Formatting failed: {error_string}");
12038                self.last_formatting_failure
12039                    .replace(error_string.lines().join(" "));
12040            }
12041        }
12042    }
12043
12044    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12045        self.lsp_server_capabilities.remove(&for_server);
12046        self.semantic_token_config.remove_server_data(for_server);
12047        for lsp_data in self.lsp_data.values_mut() {
12048            lsp_data.remove_server_data(for_server);
12049        }
12050        if let Some(local) = self.as_local_mut() {
12051            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12052            local
12053                .workspace_pull_diagnostics_result_ids
12054                .remove(&for_server);
12055            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12056                buffer_servers.remove(&for_server);
12057            }
12058        }
12059    }
12060
12061    pub fn result_id_for_buffer_pull(
12062        &self,
12063        server_id: LanguageServerId,
12064        buffer_id: BufferId,
12065        registration_id: &Option<SharedString>,
12066        cx: &App,
12067    ) -> Option<SharedString> {
12068        let abs_path = self
12069            .buffer_store
12070            .read(cx)
12071            .get(buffer_id)
12072            .and_then(|b| File::from_dyn(b.read(cx).file()))
12073            .map(|f| f.abs_path(cx))?;
12074        self.as_local()?
12075            .buffer_pull_diagnostics_result_ids
12076            .get(&server_id)?
12077            .get(registration_id)?
12078            .get(&abs_path)?
12079            .clone()
12080    }
12081
12082    /// Gets all result_ids for a workspace diagnostics pull request.
12083    /// 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.
12084    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12085    pub fn result_ids_for_workspace_refresh(
12086        &self,
12087        server_id: LanguageServerId,
12088        registration_id: &Option<SharedString>,
12089    ) -> HashMap<PathBuf, SharedString> {
12090        let Some(local) = self.as_local() else {
12091            return HashMap::default();
12092        };
12093        local
12094            .workspace_pull_diagnostics_result_ids
12095            .get(&server_id)
12096            .into_iter()
12097            .filter_map(|diagnostics| diagnostics.get(registration_id))
12098            .flatten()
12099            .filter_map(|(abs_path, result_id)| {
12100                let result_id = local
12101                    .buffer_pull_diagnostics_result_ids
12102                    .get(&server_id)
12103                    .and_then(|buffer_ids_result_ids| {
12104                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12105                    })
12106                    .cloned()
12107                    .flatten()
12108                    .or_else(|| result_id.clone())?;
12109                Some((abs_path.clone(), result_id))
12110            })
12111            .collect()
12112    }
12113
12114    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12115        if let Some(LanguageServerState::Running {
12116            workspace_diagnostics_refresh_tasks,
12117            ..
12118        }) = self
12119            .as_local_mut()
12120            .and_then(|local| local.language_servers.get_mut(&server_id))
12121        {
12122            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12123                diagnostics.refresh_tx.try_send(()).ok();
12124            }
12125        }
12126    }
12127
12128    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12129    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12130    /// which requires refreshing both workspace and document diagnostics.
12131    pub fn pull_document_diagnostics_for_server(
12132        &mut self,
12133        server_id: LanguageServerId,
12134        source_buffer_id: Option<BufferId>,
12135        cx: &mut Context<Self>,
12136    ) -> Shared<Task<()>> {
12137        let Some(local) = self.as_local_mut() else {
12138            return Task::ready(()).shared();
12139        };
12140        let mut buffers_to_refresh = HashSet::default();
12141        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12142            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12143                buffers_to_refresh.insert(*buffer_id);
12144            }
12145        }
12146
12147        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12148    }
12149
12150    pub fn pull_document_diagnostics_for_buffer_edit(
12151        &mut self,
12152        buffer_id: BufferId,
12153        cx: &mut Context<Self>,
12154    ) {
12155        let Some(local) = self.as_local_mut() else {
12156            return;
12157        };
12158        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12159        else {
12160            return;
12161        };
12162        for server_id in languages_servers {
12163            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12164        }
12165    }
12166
12167    fn apply_workspace_diagnostic_report(
12168        &mut self,
12169        server_id: LanguageServerId,
12170        report: lsp::WorkspaceDiagnosticReportResult,
12171        registration_id: Option<SharedString>,
12172        cx: &mut Context<Self>,
12173    ) {
12174        let mut workspace_diagnostics =
12175            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12176                report,
12177                server_id,
12178                registration_id,
12179            );
12180        workspace_diagnostics.retain(|d| match &d.diagnostics {
12181            LspPullDiagnostics::Response {
12182                server_id,
12183                registration_id,
12184                ..
12185            } => self.diagnostic_registration_exists(*server_id, registration_id),
12186            LspPullDiagnostics::Default => false,
12187        });
12188        let mut unchanged_buffers = HashMap::default();
12189        let workspace_diagnostics_updates = workspace_diagnostics
12190            .into_iter()
12191            .filter_map(
12192                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12193                    LspPullDiagnostics::Response {
12194                        server_id,
12195                        uri,
12196                        diagnostics,
12197                        registration_id,
12198                    } => Some((
12199                        server_id,
12200                        uri,
12201                        diagnostics,
12202                        workspace_diagnostics.version,
12203                        registration_id,
12204                    )),
12205                    LspPullDiagnostics::Default => None,
12206                },
12207            )
12208            .fold(
12209                HashMap::default(),
12210                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12211                    let (result_id, diagnostics) = match diagnostics {
12212                        PulledDiagnostics::Unchanged { result_id } => {
12213                            unchanged_buffers
12214                                .entry(new_registration_id.clone())
12215                                .or_insert_with(HashSet::default)
12216                                .insert(uri.clone());
12217                            (Some(result_id), Vec::new())
12218                        }
12219                        PulledDiagnostics::Changed {
12220                            result_id,
12221                            diagnostics,
12222                        } => (result_id, diagnostics),
12223                    };
12224                    let disk_based_sources = Cow::Owned(
12225                        self.language_server_adapter_for_id(server_id)
12226                            .as_ref()
12227                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12228                            .unwrap_or(&[])
12229                            .to_vec(),
12230                    );
12231
12232                    let Some(abs_path) = uri.to_file_path().ok() else {
12233                        return acc;
12234                    };
12235                    let Some((worktree, relative_path)) =
12236                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12237                    else {
12238                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12239                        return acc;
12240                    };
12241                    let worktree_id = worktree.read(cx).id();
12242                    let project_path = ProjectPath {
12243                        worktree_id,
12244                        path: relative_path,
12245                    };
12246                    if let Some(local_lsp_store) = self.as_local_mut() {
12247                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12248                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12249                    }
12250                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12251                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12252                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12253                        acc.entry(server_id)
12254                            .or_insert_with(HashMap::default)
12255                            .entry(new_registration_id.clone())
12256                            .or_insert_with(Vec::new)
12257                            .push(DocumentDiagnosticsUpdate {
12258                                server_id,
12259                                diagnostics: lsp::PublishDiagnosticsParams {
12260                                    uri,
12261                                    diagnostics,
12262                                    version,
12263                                },
12264                                result_id: result_id.map(SharedString::new),
12265                                disk_based_sources,
12266                                registration_id: new_registration_id,
12267                            });
12268                    }
12269                    acc
12270                },
12271            );
12272
12273        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12274            for (registration_id, diagnostic_updates) in diagnostic_updates {
12275                self.merge_lsp_diagnostics(
12276                    DiagnosticSourceKind::Pulled,
12277                    diagnostic_updates,
12278                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12279                        DiagnosticSourceKind::Pulled => {
12280                            old_diagnostic.registration_id != registration_id
12281                                || unchanged_buffers
12282                                    .get(&old_diagnostic.registration_id)
12283                                    .is_some_and(|unchanged_buffers| {
12284                                        unchanged_buffers.contains(&document_uri)
12285                                    })
12286                        }
12287                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12288                    },
12289                    cx,
12290                )
12291                .log_err();
12292            }
12293        }
12294    }
12295
12296    fn register_server_capabilities(
12297        &mut self,
12298        server_id: LanguageServerId,
12299        params: lsp::RegistrationParams,
12300        cx: &mut Context<Self>,
12301    ) -> anyhow::Result<()> {
12302        let server = self
12303            .language_server_for_id(server_id)
12304            .with_context(|| format!("no server {server_id} found"))?;
12305        for reg in params.registrations {
12306            match reg.method.as_str() {
12307                "workspace/didChangeWatchedFiles" => {
12308                    if let Some(options) = reg.register_options {
12309                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12310                            let caps = serde_json::from_value(options)?;
12311                            local_lsp_store
12312                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12313                            true
12314                        } else {
12315                            false
12316                        };
12317                        if notify {
12318                            notify_server_capabilities_updated(&server, cx);
12319                        }
12320                    }
12321                }
12322                "workspace/didChangeConfiguration" => {
12323                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12324                }
12325                "workspace/didChangeWorkspaceFolders" => {
12326                    // In this case register options is an empty object, we can ignore it
12327                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12328                        supported: Some(true),
12329                        change_notifications: Some(OneOf::Right(reg.id)),
12330                    };
12331                    server.update_capabilities(|capabilities| {
12332                        capabilities
12333                            .workspace
12334                            .get_or_insert_default()
12335                            .workspace_folders = Some(caps);
12336                    });
12337                    notify_server_capabilities_updated(&server, cx);
12338                }
12339                "workspace/symbol" => {
12340                    let options = parse_register_capabilities(reg)?;
12341                    server.update_capabilities(|capabilities| {
12342                        capabilities.workspace_symbol_provider = Some(options);
12343                    });
12344                    notify_server_capabilities_updated(&server, cx);
12345                }
12346                "workspace/fileOperations" => {
12347                    if let Some(options) = reg.register_options {
12348                        let caps = serde_json::from_value(options)?;
12349                        server.update_capabilities(|capabilities| {
12350                            capabilities
12351                                .workspace
12352                                .get_or_insert_default()
12353                                .file_operations = Some(caps);
12354                        });
12355                        notify_server_capabilities_updated(&server, cx);
12356                    }
12357                }
12358                "workspace/executeCommand" => {
12359                    if let Some(options) = reg.register_options {
12360                        let options = serde_json::from_value(options)?;
12361                        server.update_capabilities(|capabilities| {
12362                            capabilities.execute_command_provider = Some(options);
12363                        });
12364                        notify_server_capabilities_updated(&server, cx);
12365                    }
12366                }
12367                "textDocument/rangeFormatting" => {
12368                    let options = parse_register_capabilities(reg)?;
12369                    server.update_capabilities(|capabilities| {
12370                        capabilities.document_range_formatting_provider = Some(options);
12371                    });
12372                    notify_server_capabilities_updated(&server, cx);
12373                }
12374                "textDocument/onTypeFormatting" => {
12375                    if let Some(options) = reg
12376                        .register_options
12377                        .map(serde_json::from_value)
12378                        .transpose()?
12379                    {
12380                        server.update_capabilities(|capabilities| {
12381                            capabilities.document_on_type_formatting_provider = Some(options);
12382                        });
12383                        notify_server_capabilities_updated(&server, cx);
12384                    }
12385                }
12386                "textDocument/formatting" => {
12387                    let options = parse_register_capabilities(reg)?;
12388                    server.update_capabilities(|capabilities| {
12389                        capabilities.document_formatting_provider = Some(options);
12390                    });
12391                    notify_server_capabilities_updated(&server, cx);
12392                }
12393                "textDocument/rename" => {
12394                    let options = parse_register_capabilities(reg)?;
12395                    server.update_capabilities(|capabilities| {
12396                        capabilities.rename_provider = Some(options);
12397                    });
12398                    notify_server_capabilities_updated(&server, cx);
12399                }
12400                "textDocument/inlayHint" => {
12401                    let options = parse_register_capabilities(reg)?;
12402                    server.update_capabilities(|capabilities| {
12403                        capabilities.inlay_hint_provider = Some(options);
12404                    });
12405                    notify_server_capabilities_updated(&server, cx);
12406                }
12407                "textDocument/documentSymbol" => {
12408                    let options = parse_register_capabilities(reg)?;
12409                    server.update_capabilities(|capabilities| {
12410                        capabilities.document_symbol_provider = Some(options);
12411                    });
12412                    notify_server_capabilities_updated(&server, cx);
12413                }
12414                "textDocument/codeAction" => {
12415                    let options = parse_register_capabilities(reg)?;
12416                    let provider = match options {
12417                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12418                        OneOf::Right(caps) => caps,
12419                    };
12420                    server.update_capabilities(|capabilities| {
12421                        capabilities.code_action_provider = Some(provider);
12422                    });
12423                    notify_server_capabilities_updated(&server, cx);
12424                }
12425                "textDocument/definition" => {
12426                    let options = parse_register_capabilities(reg)?;
12427                    server.update_capabilities(|capabilities| {
12428                        capabilities.definition_provider = Some(options);
12429                    });
12430                    notify_server_capabilities_updated(&server, cx);
12431                }
12432                "textDocument/completion" => {
12433                    if let Some(caps) = reg
12434                        .register_options
12435                        .map(serde_json::from_value::<CompletionOptions>)
12436                        .transpose()?
12437                    {
12438                        server.update_capabilities(|capabilities| {
12439                            capabilities.completion_provider = Some(caps.clone());
12440                        });
12441
12442                        if let Some(local) = self.as_local() {
12443                            let mut buffers_with_language_server = Vec::new();
12444                            for handle in self.buffer_store.read(cx).buffers() {
12445                                let buffer_id = handle.read(cx).remote_id();
12446                                if local
12447                                    .buffers_opened_in_servers
12448                                    .get(&buffer_id)
12449                                    .filter(|s| s.contains(&server_id))
12450                                    .is_some()
12451                                {
12452                                    buffers_with_language_server.push(handle);
12453                                }
12454                            }
12455                            let triggers = caps
12456                                .trigger_characters
12457                                .unwrap_or_default()
12458                                .into_iter()
12459                                .collect::<BTreeSet<_>>();
12460                            for handle in buffers_with_language_server {
12461                                let triggers = triggers.clone();
12462                                let _ = handle.update(cx, move |buffer, cx| {
12463                                    buffer.set_completion_triggers(server_id, triggers, cx);
12464                                });
12465                            }
12466                        }
12467                        notify_server_capabilities_updated(&server, cx);
12468                    }
12469                }
12470                "textDocument/hover" => {
12471                    let options = parse_register_capabilities(reg)?;
12472                    let provider = match options {
12473                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12474                        OneOf::Right(caps) => caps,
12475                    };
12476                    server.update_capabilities(|capabilities| {
12477                        capabilities.hover_provider = Some(provider);
12478                    });
12479                    notify_server_capabilities_updated(&server, cx);
12480                }
12481                "textDocument/signatureHelp" => {
12482                    if let Some(caps) = reg
12483                        .register_options
12484                        .map(serde_json::from_value)
12485                        .transpose()?
12486                    {
12487                        server.update_capabilities(|capabilities| {
12488                            capabilities.signature_help_provider = Some(caps);
12489                        });
12490                        notify_server_capabilities_updated(&server, cx);
12491                    }
12492                }
12493                "textDocument/didChange" => {
12494                    if let Some(sync_kind) = reg
12495                        .register_options
12496                        .and_then(|opts| opts.get("syncKind").cloned())
12497                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12498                        .transpose()?
12499                    {
12500                        server.update_capabilities(|capabilities| {
12501                            let mut sync_options =
12502                                Self::take_text_document_sync_options(capabilities);
12503                            sync_options.change = Some(sync_kind);
12504                            capabilities.text_document_sync =
12505                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12506                        });
12507                        notify_server_capabilities_updated(&server, cx);
12508                    }
12509                }
12510                "textDocument/didSave" => {
12511                    if let Some(include_text) = reg
12512                        .register_options
12513                        .map(|opts| {
12514                            let transpose = opts
12515                                .get("includeText")
12516                                .cloned()
12517                                .map(serde_json::from_value::<Option<bool>>)
12518                                .transpose();
12519                            match transpose {
12520                                Ok(value) => Ok(value.flatten()),
12521                                Err(e) => Err(e),
12522                            }
12523                        })
12524                        .transpose()?
12525                    {
12526                        server.update_capabilities(|capabilities| {
12527                            let mut sync_options =
12528                                Self::take_text_document_sync_options(capabilities);
12529                            sync_options.save =
12530                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12531                                    include_text,
12532                                }));
12533                            capabilities.text_document_sync =
12534                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12535                        });
12536                        notify_server_capabilities_updated(&server, cx);
12537                    }
12538                }
12539                "textDocument/codeLens" => {
12540                    if let Some(caps) = reg
12541                        .register_options
12542                        .map(serde_json::from_value)
12543                        .transpose()?
12544                    {
12545                        server.update_capabilities(|capabilities| {
12546                            capabilities.code_lens_provider = Some(caps);
12547                        });
12548                        notify_server_capabilities_updated(&server, cx);
12549                    }
12550                }
12551                "textDocument/diagnostic" => {
12552                    if let Some(caps) = reg
12553                        .register_options
12554                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12555                        .transpose()?
12556                    {
12557                        let local = self
12558                            .as_local_mut()
12559                            .context("Expected LSP Store to be local")?;
12560                        let state = local
12561                            .language_servers
12562                            .get_mut(&server_id)
12563                            .context("Could not obtain Language Servers state")?;
12564                        local
12565                            .language_server_dynamic_registrations
12566                            .entry(server_id)
12567                            .or_default()
12568                            .diagnostics
12569                            .insert(Some(reg.id.clone()), caps.clone());
12570
12571                        let supports_workspace_diagnostics =
12572                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12573                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12574                                    diagnostic_options.workspace_diagnostics
12575                                }
12576                                DiagnosticServerCapabilities::RegistrationOptions(
12577                                    diagnostic_registration_options,
12578                                ) => {
12579                                    diagnostic_registration_options
12580                                        .diagnostic_options
12581                                        .workspace_diagnostics
12582                                }
12583                            };
12584
12585                        if supports_workspace_diagnostics(&caps) {
12586                            if let LanguageServerState::Running {
12587                                workspace_diagnostics_refresh_tasks,
12588                                ..
12589                            } = state
12590                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12591                                    Some(reg.id.clone()),
12592                                    caps.clone(),
12593                                    server.clone(),
12594                                    cx,
12595                                )
12596                            {
12597                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12598                            }
12599                        }
12600
12601                        server.update_capabilities(|capabilities| {
12602                            capabilities.diagnostic_provider = Some(caps);
12603                        });
12604
12605                        notify_server_capabilities_updated(&server, cx);
12606
12607                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12608                    }
12609                }
12610                "textDocument/documentColor" => {
12611                    let options = parse_register_capabilities(reg)?;
12612                    let provider = match options {
12613                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12614                        OneOf::Right(caps) => caps,
12615                    };
12616                    server.update_capabilities(|capabilities| {
12617                        capabilities.color_provider = Some(provider);
12618                    });
12619                    notify_server_capabilities_updated(&server, cx);
12620                }
12621                "textDocument/foldingRange" => {
12622                    let options = parse_register_capabilities(reg)?;
12623                    let provider = match options {
12624                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12625                        OneOf::Right(caps) => caps,
12626                    };
12627                    server.update_capabilities(|capabilities| {
12628                        capabilities.folding_range_provider = Some(provider);
12629                    });
12630                    notify_server_capabilities_updated(&server, cx);
12631                }
12632                _ => log::warn!("unhandled capability registration: {reg:?}"),
12633            }
12634        }
12635
12636        Ok(())
12637    }
12638
12639    fn unregister_server_capabilities(
12640        &mut self,
12641        server_id: LanguageServerId,
12642        params: lsp::UnregistrationParams,
12643        cx: &mut Context<Self>,
12644    ) -> anyhow::Result<()> {
12645        let server = self
12646            .language_server_for_id(server_id)
12647            .with_context(|| format!("no server {server_id} found"))?;
12648        for unreg in params.unregisterations.iter() {
12649            match unreg.method.as_str() {
12650                "workspace/didChangeWatchedFiles" => {
12651                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12652                        local_lsp_store
12653                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12654                        true
12655                    } else {
12656                        false
12657                    };
12658                    if notify {
12659                        notify_server_capabilities_updated(&server, cx);
12660                    }
12661                }
12662                "workspace/didChangeConfiguration" => {
12663                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12664                }
12665                "workspace/didChangeWorkspaceFolders" => {
12666                    server.update_capabilities(|capabilities| {
12667                        capabilities
12668                            .workspace
12669                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12670                                workspace_folders: None,
12671                                file_operations: None,
12672                            })
12673                            .workspace_folders = None;
12674                    });
12675                    notify_server_capabilities_updated(&server, cx);
12676                }
12677                "workspace/symbol" => {
12678                    server.update_capabilities(|capabilities| {
12679                        capabilities.workspace_symbol_provider = None
12680                    });
12681                    notify_server_capabilities_updated(&server, cx);
12682                }
12683                "workspace/fileOperations" => {
12684                    server.update_capabilities(|capabilities| {
12685                        capabilities
12686                            .workspace
12687                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12688                                workspace_folders: None,
12689                                file_operations: None,
12690                            })
12691                            .file_operations = None;
12692                    });
12693                    notify_server_capabilities_updated(&server, cx);
12694                }
12695                "workspace/executeCommand" => {
12696                    server.update_capabilities(|capabilities| {
12697                        capabilities.execute_command_provider = None;
12698                    });
12699                    notify_server_capabilities_updated(&server, cx);
12700                }
12701                "textDocument/rangeFormatting" => {
12702                    server.update_capabilities(|capabilities| {
12703                        capabilities.document_range_formatting_provider = None
12704                    });
12705                    notify_server_capabilities_updated(&server, cx);
12706                }
12707                "textDocument/onTypeFormatting" => {
12708                    server.update_capabilities(|capabilities| {
12709                        capabilities.document_on_type_formatting_provider = None;
12710                    });
12711                    notify_server_capabilities_updated(&server, cx);
12712                }
12713                "textDocument/formatting" => {
12714                    server.update_capabilities(|capabilities| {
12715                        capabilities.document_formatting_provider = None;
12716                    });
12717                    notify_server_capabilities_updated(&server, cx);
12718                }
12719                "textDocument/rename" => {
12720                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12721                    notify_server_capabilities_updated(&server, cx);
12722                }
12723                "textDocument/codeAction" => {
12724                    server.update_capabilities(|capabilities| {
12725                        capabilities.code_action_provider = None;
12726                    });
12727                    notify_server_capabilities_updated(&server, cx);
12728                }
12729                "textDocument/definition" => {
12730                    server.update_capabilities(|capabilities| {
12731                        capabilities.definition_provider = None;
12732                    });
12733                    notify_server_capabilities_updated(&server, cx);
12734                }
12735                "textDocument/completion" => {
12736                    server.update_capabilities(|capabilities| {
12737                        capabilities.completion_provider = None;
12738                    });
12739                    notify_server_capabilities_updated(&server, cx);
12740                }
12741                "textDocument/hover" => {
12742                    server.update_capabilities(|capabilities| {
12743                        capabilities.hover_provider = None;
12744                    });
12745                    notify_server_capabilities_updated(&server, cx);
12746                }
12747                "textDocument/signatureHelp" => {
12748                    server.update_capabilities(|capabilities| {
12749                        capabilities.signature_help_provider = None;
12750                    });
12751                    notify_server_capabilities_updated(&server, cx);
12752                }
12753                "textDocument/didChange" => {
12754                    server.update_capabilities(|capabilities| {
12755                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12756                        sync_options.change = None;
12757                        capabilities.text_document_sync =
12758                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12759                    });
12760                    notify_server_capabilities_updated(&server, cx);
12761                }
12762                "textDocument/didSave" => {
12763                    server.update_capabilities(|capabilities| {
12764                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12765                        sync_options.save = None;
12766                        capabilities.text_document_sync =
12767                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12768                    });
12769                    notify_server_capabilities_updated(&server, cx);
12770                }
12771                "textDocument/codeLens" => {
12772                    server.update_capabilities(|capabilities| {
12773                        capabilities.code_lens_provider = None;
12774                    });
12775                    notify_server_capabilities_updated(&server, cx);
12776                }
12777                "textDocument/diagnostic" => {
12778                    let local = self
12779                        .as_local_mut()
12780                        .context("Expected LSP Store to be local")?;
12781
12782                    let state = local
12783                        .language_servers
12784                        .get_mut(&server_id)
12785                        .context("Could not obtain Language Servers state")?;
12786                    let registrations = local
12787                        .language_server_dynamic_registrations
12788                        .get_mut(&server_id)
12789                        .with_context(|| {
12790                            format!("Expected dynamic registration to exist for server {server_id}")
12791                        })?;
12792                    registrations.diagnostics
12793                        .remove(&Some(unreg.id.clone()))
12794                        .with_context(|| format!(
12795                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12796                            unreg.id)
12797                        )?;
12798                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12799
12800                    if let LanguageServerState::Running {
12801                        workspace_diagnostics_refresh_tasks,
12802                        ..
12803                    } = state
12804                    {
12805                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12806                    }
12807
12808                    self.clear_unregistered_diagnostics(
12809                        server_id,
12810                        SharedString::from(unreg.id.clone()),
12811                        cx,
12812                    )?;
12813
12814                    if removed_last_diagnostic_provider {
12815                        server.update_capabilities(|capabilities| {
12816                            debug_assert!(capabilities.diagnostic_provider.is_some());
12817                            capabilities.diagnostic_provider = None;
12818                        });
12819                    }
12820
12821                    notify_server_capabilities_updated(&server, cx);
12822                }
12823                "textDocument/documentColor" => {
12824                    server.update_capabilities(|capabilities| {
12825                        capabilities.color_provider = None;
12826                    });
12827                    notify_server_capabilities_updated(&server, cx);
12828                }
12829                "textDocument/foldingRange" => {
12830                    server.update_capabilities(|capabilities| {
12831                        capabilities.folding_range_provider = None;
12832                    });
12833                    notify_server_capabilities_updated(&server, cx);
12834                }
12835                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12836            }
12837        }
12838
12839        Ok(())
12840    }
12841
12842    fn clear_unregistered_diagnostics(
12843        &mut self,
12844        server_id: LanguageServerId,
12845        cleared_registration_id: SharedString,
12846        cx: &mut Context<Self>,
12847    ) -> anyhow::Result<()> {
12848        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12849
12850        self.buffer_store.update(cx, |buffer_store, cx| {
12851            for buffer_handle in buffer_store.buffers() {
12852                let buffer = buffer_handle.read(cx);
12853                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12854                let Some(abs_path) = abs_path else {
12855                    continue;
12856                };
12857                affected_abs_paths.insert(abs_path);
12858            }
12859        });
12860
12861        let local = self.as_local().context("Expected LSP Store to be local")?;
12862        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12863            let Some(worktree) = self
12864                .worktree_store
12865                .read(cx)
12866                .worktree_for_id(*worktree_id, cx)
12867            else {
12868                continue;
12869            };
12870
12871            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12872                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12873                    let has_matching_registration =
12874                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12875                            entry.diagnostic.registration_id.as_ref()
12876                                == Some(&cleared_registration_id)
12877                        });
12878                    if has_matching_registration {
12879                        let abs_path = worktree.read(cx).absolutize(rel_path);
12880                        affected_abs_paths.insert(abs_path);
12881                    }
12882                }
12883            }
12884        }
12885
12886        if affected_abs_paths.is_empty() {
12887            return Ok(());
12888        }
12889
12890        // Send a fake diagnostic update which clears the state for the registration ID
12891        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12892            affected_abs_paths
12893                .into_iter()
12894                .map(|abs_path| DocumentDiagnosticsUpdate {
12895                    diagnostics: DocumentDiagnostics {
12896                        diagnostics: Vec::new(),
12897                        document_abs_path: abs_path,
12898                        version: None,
12899                    },
12900                    result_id: None,
12901                    registration_id: Some(cleared_registration_id.clone()),
12902                    server_id,
12903                    disk_based_sources: Cow::Borrowed(&[]),
12904                })
12905                .collect();
12906
12907        let merge_registration_id = cleared_registration_id.clone();
12908        self.merge_diagnostic_entries(
12909            clears,
12910            move |_, diagnostic, _| {
12911                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12912                    diagnostic.registration_id != Some(merge_registration_id.clone())
12913                } else {
12914                    true
12915                }
12916            },
12917            cx,
12918        )?;
12919
12920        Ok(())
12921    }
12922
12923    async fn deduplicate_range_based_lsp_requests<T>(
12924        lsp_store: &Entity<Self>,
12925        server_id: Option<LanguageServerId>,
12926        lsp_request_id: LspRequestId,
12927        proto_request: &T::ProtoRequest,
12928        range: Range<Anchor>,
12929        cx: &mut AsyncApp,
12930    ) -> Result<()>
12931    where
12932        T: LspCommand,
12933        T::ProtoRequest: proto::LspRequestMessage,
12934    {
12935        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12936        let version = deserialize_version(proto_request.buffer_version());
12937        let buffer = lsp_store.update(cx, |this, cx| {
12938            this.buffer_store.read(cx).get_existing(buffer_id)
12939        })?;
12940        buffer
12941            .update(cx, |buffer, _| buffer.wait_for_version(version))
12942            .await?;
12943        lsp_store.update(cx, |lsp_store, cx| {
12944            let buffer_snapshot = buffer.read(cx).snapshot();
12945            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12946            let chunks_queried_for = lsp_data
12947                .inlay_hints
12948                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12949                .collect::<Vec<_>>();
12950            match chunks_queried_for.as_slice() {
12951                &[chunk] => {
12952                    let key = LspKey {
12953                        request_type: TypeId::of::<T>(),
12954                        server_queried: server_id,
12955                    };
12956                    let previous_request = lsp_data
12957                        .chunk_lsp_requests
12958                        .entry(key)
12959                        .or_default()
12960                        .insert(chunk, lsp_request_id);
12961                    if let Some((previous_request, running_requests)) =
12962                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12963                    {
12964                        running_requests.remove(&previous_request);
12965                    }
12966                }
12967                _ambiguous_chunks => {
12968                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12969                    // there, a buffer version-based check will be performed and outdated requests discarded.
12970                }
12971            }
12972            anyhow::Ok(())
12973        })?;
12974
12975        Ok(())
12976    }
12977
12978    async fn query_lsp_locally<T>(
12979        lsp_store: Entity<Self>,
12980        for_server_id: Option<LanguageServerId>,
12981        sender_id: proto::PeerId,
12982        lsp_request_id: LspRequestId,
12983        proto_request: T::ProtoRequest,
12984        position: Option<Anchor>,
12985        cx: &mut AsyncApp,
12986    ) -> Result<()>
12987    where
12988        T: LspCommand + Clone,
12989        T::ProtoRequest: proto::LspRequestMessage,
12990        <T::ProtoRequest as proto::RequestMessage>::Response:
12991            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12992    {
12993        let (buffer_version, buffer) =
12994            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12995        let request =
12996            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12997        let key = LspKey {
12998            request_type: TypeId::of::<T>(),
12999            server_queried: for_server_id,
13000        };
13001        lsp_store.update(cx, |lsp_store, cx| {
13002            let request_task = match for_server_id {
13003                Some(server_id) => {
13004                    let server_task = lsp_store.request_lsp(
13005                        buffer.clone(),
13006                        LanguageServerToQuery::Other(server_id),
13007                        request.clone(),
13008                        cx,
13009                    );
13010                    cx.background_spawn(async move {
13011                        let mut responses = Vec::new();
13012                        match server_task.await {
13013                            Ok(response) => responses.push((server_id, response)),
13014                            // rust-analyzer likes to error with this when its still loading up
13015                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13016                            Err(e) => log::error!(
13017                                "Error handling response for request {request:?}: {e:#}"
13018                            ),
13019                        }
13020                        responses
13021                    })
13022                }
13023                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13024            };
13025            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13026            if T::ProtoRequest::stop_previous_requests() {
13027                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13028                    lsp_requests.clear();
13029                }
13030            }
13031            lsp_data.lsp_requests.entry(key).or_default().insert(
13032                lsp_request_id,
13033                cx.spawn(async move |lsp_store, cx| {
13034                    let response = request_task.await;
13035                    lsp_store
13036                        .update(cx, |lsp_store, cx| {
13037                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13038                            {
13039                                let response = response
13040                                    .into_iter()
13041                                    .map(|(server_id, response)| {
13042                                        (
13043                                            server_id.to_proto(),
13044                                            T::response_to_proto(
13045                                                response,
13046                                                lsp_store,
13047                                                sender_id,
13048                                                &buffer_version,
13049                                                cx,
13050                                            )
13051                                            .into(),
13052                                        )
13053                                    })
13054                                    .collect::<HashMap<_, _>>();
13055                                match client.send_lsp_response::<T::ProtoRequest>(
13056                                    project_id,
13057                                    lsp_request_id,
13058                                    response,
13059                                ) {
13060                                    Ok(()) => {}
13061                                    Err(e) => {
13062                                        log::error!("Failed to send LSP response: {e:#}",)
13063                                    }
13064                                }
13065                            }
13066                        })
13067                        .ok();
13068                }),
13069            );
13070        });
13071        Ok(())
13072    }
13073
13074    async fn wait_for_buffer_version<T>(
13075        lsp_store: &Entity<Self>,
13076        proto_request: &T::ProtoRequest,
13077        cx: &mut AsyncApp,
13078    ) -> Result<(Global, Entity<Buffer>)>
13079    where
13080        T: LspCommand,
13081        T::ProtoRequest: proto::LspRequestMessage,
13082    {
13083        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13084        let version = deserialize_version(proto_request.buffer_version());
13085        let buffer = lsp_store.update(cx, |this, cx| {
13086            this.buffer_store.read(cx).get_existing(buffer_id)
13087        })?;
13088        buffer
13089            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13090            .await?;
13091        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13092        Ok((buffer_version, buffer))
13093    }
13094
13095    fn take_text_document_sync_options(
13096        capabilities: &mut lsp::ServerCapabilities,
13097    ) -> lsp::TextDocumentSyncOptions {
13098        match capabilities.text_document_sync.take() {
13099            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13100            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13101                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13102                sync_options.change = Some(sync_kind);
13103                sync_options
13104            }
13105            None => lsp::TextDocumentSyncOptions::default(),
13106        }
13107    }
13108
13109    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13110        self.downstream_client.clone()
13111    }
13112
13113    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13114        self.worktree_store.clone()
13115    }
13116
13117    /// Gets what's stored in the LSP data for the given buffer.
13118    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13119        self.lsp_data.get_mut(&buffer_id)
13120    }
13121
13122    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13123    /// new [`BufferLspData`] will be created to replace the previous state.
13124    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13125        let (buffer_id, buffer_version) =
13126            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13127        let lsp_data = self
13128            .lsp_data
13129            .entry(buffer_id)
13130            .or_insert_with(|| BufferLspData::new(buffer, cx));
13131        if buffer_version.changed_since(&lsp_data.buffer_version) {
13132            // To send delta requests for semantic tokens, the previous tokens
13133            // need to be kept between buffer changes.
13134            let semantic_tokens = lsp_data.semantic_tokens.take();
13135            *lsp_data = BufferLspData::new(buffer, cx);
13136            lsp_data.semantic_tokens = semantic_tokens;
13137        }
13138        lsp_data
13139    }
13140}
13141
13142// Registration with registerOptions as null, should fallback to true.
13143// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13144fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13145    reg: lsp::Registration,
13146) -> Result<OneOf<bool, T>> {
13147    Ok(match reg.register_options {
13148        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13149        None => OneOf::Left(true),
13150    })
13151}
13152
13153fn subscribe_to_binary_statuses(
13154    languages: &Arc<LanguageRegistry>,
13155    cx: &mut Context<'_, LspStore>,
13156) -> Task<()> {
13157    let mut server_statuses = languages.language_server_binary_statuses();
13158    cx.spawn(async move |lsp_store, cx| {
13159        while let Some((server_name, binary_status)) = server_statuses.next().await {
13160            if lsp_store
13161                .update(cx, |_, cx| {
13162                    let mut message = None;
13163                    let binary_status = match binary_status {
13164                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13165                        BinaryStatus::CheckingForUpdate => {
13166                            proto::ServerBinaryStatus::CheckingForUpdate
13167                        }
13168                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13169                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13170                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13171                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13172                        BinaryStatus::Failed { error } => {
13173                            message = Some(error);
13174                            proto::ServerBinaryStatus::Failed
13175                        }
13176                    };
13177                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13178                        // Binary updates are about the binary that might not have any language server id at that point.
13179                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13180                        language_server_id: LanguageServerId(0),
13181                        name: Some(server_name),
13182                        message: proto::update_language_server::Variant::StatusUpdate(
13183                            proto::StatusUpdate {
13184                                message,
13185                                status: Some(proto::status_update::Status::Binary(
13186                                    binary_status as i32,
13187                                )),
13188                            },
13189                        ),
13190                    });
13191                })
13192                .is_err()
13193            {
13194                break;
13195            }
13196        }
13197    })
13198}
13199
13200fn lsp_workspace_diagnostics_refresh(
13201    registration_id: Option<String>,
13202    options: DiagnosticServerCapabilities,
13203    server: Arc<LanguageServer>,
13204    cx: &mut Context<'_, LspStore>,
13205) -> Option<WorkspaceRefreshTask> {
13206    let identifier = workspace_diagnostic_identifier(&options)?;
13207    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13208
13209    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13210    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13211    refresh_tx.try_send(()).ok();
13212
13213    let request_timeout = ProjectSettings::get_global(cx)
13214        .global_lsp_settings
13215        .get_request_timeout();
13216
13217    // 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.
13218    // This allows users to increase the duration if need be
13219    let timeout = if request_timeout != Duration::ZERO {
13220        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13221    } else {
13222        request_timeout
13223    };
13224
13225    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13226        let mut attempts = 0;
13227        let max_attempts = 50;
13228        let mut requests = 0;
13229
13230        loop {
13231            let Some(()) = refresh_rx.recv().await else {
13232                return;
13233            };
13234
13235            'request: loop {
13236                requests += 1;
13237                if attempts > max_attempts {
13238                    log::error!(
13239                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13240                    );
13241                    return;
13242                }
13243                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13244                cx.background_executor()
13245                    .timer(Duration::from_millis(backoff_millis))
13246                    .await;
13247                attempts += 1;
13248
13249                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13250                    lsp_store
13251                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13252                        .into_iter()
13253                        .filter_map(|(abs_path, result_id)| {
13254                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13255                            Some(lsp::PreviousResultId {
13256                                uri,
13257                                value: result_id.to_string(),
13258                            })
13259                        })
13260                        .collect()
13261                }) else {
13262                    return;
13263                };
13264
13265                let token = if let Some(registration_id) = &registration_id {
13266                    format!(
13267                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13268                        server.server_id(),
13269                    )
13270                } else {
13271                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13272                };
13273
13274                progress_rx.try_recv().ok();
13275                let timer = server.request_timer(timeout).fuse();
13276                let progress = pin!(progress_rx.recv().fuse());
13277                let response_result = server
13278                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13279                        lsp::WorkspaceDiagnosticParams {
13280                            previous_result_ids,
13281                            identifier: identifier.clone(),
13282                            work_done_progress_params: Default::default(),
13283                            partial_result_params: lsp::PartialResultParams {
13284                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13285                            },
13286                        },
13287                        select(timer, progress).then(|either| match either {
13288                            Either::Left((message, ..)) => ready(message).left_future(),
13289                            Either::Right(..) => pending::<String>().right_future(),
13290                        }),
13291                    )
13292                    .await;
13293
13294                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13295                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13296                match response_result {
13297                    ConnectionResult::Timeout => {
13298                        log::error!("Timeout during workspace diagnostics pull");
13299                        continue 'request;
13300                    }
13301                    ConnectionResult::ConnectionReset => {
13302                        log::error!("Server closed a workspace diagnostics pull request");
13303                        continue 'request;
13304                    }
13305                    ConnectionResult::Result(Err(e)) => {
13306                        log::error!("Error during workspace diagnostics pull: {e:#}");
13307                        break 'request;
13308                    }
13309                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13310                        attempts = 0;
13311                        if lsp_store
13312                            .update(cx, |lsp_store, cx| {
13313                                lsp_store.apply_workspace_diagnostic_report(
13314                                    server.server_id(),
13315                                    pulled_diagnostics,
13316                                    registration_id_shared.clone(),
13317                                    cx,
13318                                )
13319                            })
13320                            .is_err()
13321                        {
13322                            return;
13323                        }
13324                        break 'request;
13325                    }
13326                }
13327            }
13328        }
13329    });
13330
13331    Some(WorkspaceRefreshTask {
13332        refresh_tx,
13333        progress_tx,
13334        task: workspace_query_language_server,
13335    })
13336}
13337
13338fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13339    match &options {
13340        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13341            .identifier
13342            .as_deref()
13343            .map(SharedString::new),
13344        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13345            let diagnostic_options = &registration_options.diagnostic_options;
13346            diagnostic_options
13347                .identifier
13348                .as_deref()
13349                .map(SharedString::new)
13350        }
13351    }
13352}
13353
13354fn workspace_diagnostic_identifier(
13355    options: &DiagnosticServerCapabilities,
13356) -> Option<Option<String>> {
13357    match &options {
13358        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13359            if !diagnostic_options.workspace_diagnostics {
13360                return None;
13361            }
13362            Some(diagnostic_options.identifier.clone())
13363        }
13364        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13365            let diagnostic_options = &registration_options.diagnostic_options;
13366            if !diagnostic_options.workspace_diagnostics {
13367                return None;
13368            }
13369            Some(diagnostic_options.identifier.clone())
13370        }
13371    }
13372}
13373
13374fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13375    let CompletionSource::BufferWord {
13376        word_range,
13377        resolved,
13378    } = &mut completion.source
13379    else {
13380        return;
13381    };
13382    if *resolved {
13383        return;
13384    }
13385
13386    if completion.new_text
13387        != snapshot
13388            .text_for_range(word_range.clone())
13389            .collect::<String>()
13390    {
13391        return;
13392    }
13393
13394    let mut offset = 0;
13395    for chunk in snapshot.chunks(word_range.clone(), true) {
13396        let end_offset = offset + chunk.text.len();
13397        if let Some(highlight_id) = chunk.syntax_highlight_id {
13398            completion
13399                .label
13400                .runs
13401                .push((offset..end_offset, highlight_id));
13402        }
13403        offset = end_offset;
13404    }
13405    *resolved = true;
13406}
13407
13408impl EventEmitter<LspStoreEvent> for LspStore {}
13409
13410fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13411    hover
13412        .contents
13413        .retain(|hover_block| !hover_block.text.trim().is_empty());
13414    if hover.contents.is_empty() {
13415        None
13416    } else {
13417        Some(hover)
13418    }
13419}
13420
13421async fn populate_labels_for_completions(
13422    new_completions: Vec<CoreCompletion>,
13423    language: Option<Arc<Language>>,
13424    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13425) -> Vec<Completion> {
13426    let lsp_completions = new_completions
13427        .iter()
13428        .filter_map(|new_completion| {
13429            new_completion
13430                .source
13431                .lsp_completion(true)
13432                .map(|lsp_completion| lsp_completion.into_owned())
13433        })
13434        .collect::<Vec<_>>();
13435
13436    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13437        lsp_adapter
13438            .labels_for_completions(&lsp_completions, language)
13439            .await
13440            .log_err()
13441            .unwrap_or_default()
13442    } else {
13443        Vec::new()
13444    }
13445    .into_iter()
13446    .fuse();
13447
13448    let mut completions = Vec::new();
13449    for completion in new_completions {
13450        match completion.source.lsp_completion(true) {
13451            Some(lsp_completion) => {
13452                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13453
13454                let mut label = labels.next().flatten().unwrap_or_else(|| {
13455                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13456                });
13457                ensure_uniform_list_compatible_label(&mut label);
13458                completions.push(Completion {
13459                    label,
13460                    documentation,
13461                    replace_range: completion.replace_range,
13462                    new_text: completion.new_text,
13463                    insert_text_mode: lsp_completion.insert_text_mode,
13464                    source: completion.source,
13465                    icon_path: None,
13466                    confirm: None,
13467                    match_start: None,
13468                    snippet_deduplication_key: None,
13469                });
13470            }
13471            None => {
13472                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13473                ensure_uniform_list_compatible_label(&mut label);
13474                completions.push(Completion {
13475                    label,
13476                    documentation: None,
13477                    replace_range: completion.replace_range,
13478                    new_text: completion.new_text,
13479                    source: completion.source,
13480                    insert_text_mode: None,
13481                    icon_path: None,
13482                    confirm: None,
13483                    match_start: None,
13484                    snippet_deduplication_key: None,
13485                });
13486            }
13487        }
13488    }
13489    completions
13490}
13491
13492#[derive(Debug)]
13493pub enum LanguageServerToQuery {
13494    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13495    FirstCapable,
13496    /// Query a specific language server.
13497    Other(LanguageServerId),
13498}
13499
13500#[derive(Default)]
13501struct RenamePathsWatchedForServer {
13502    did_rename: Vec<RenameActionPredicate>,
13503    will_rename: Vec<RenameActionPredicate>,
13504}
13505
13506impl RenamePathsWatchedForServer {
13507    fn with_did_rename_patterns(
13508        mut self,
13509        did_rename: Option<&FileOperationRegistrationOptions>,
13510    ) -> Self {
13511        if let Some(did_rename) = did_rename {
13512            self.did_rename = did_rename
13513                .filters
13514                .iter()
13515                .filter_map(|filter| filter.try_into().log_err())
13516                .collect();
13517        }
13518        self
13519    }
13520    fn with_will_rename_patterns(
13521        mut self,
13522        will_rename: Option<&FileOperationRegistrationOptions>,
13523    ) -> Self {
13524        if let Some(will_rename) = will_rename {
13525            self.will_rename = will_rename
13526                .filters
13527                .iter()
13528                .filter_map(|filter| filter.try_into().log_err())
13529                .collect();
13530        }
13531        self
13532    }
13533
13534    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13535        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13536    }
13537    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13538        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13539    }
13540}
13541
13542impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13543    type Error = globset::Error;
13544    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13545        Ok(Self {
13546            kind: ops.pattern.matches.clone(),
13547            glob: GlobBuilder::new(&ops.pattern.glob)
13548                .case_insensitive(
13549                    ops.pattern
13550                        .options
13551                        .as_ref()
13552                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13553                )
13554                .build()?
13555                .compile_matcher(),
13556        })
13557    }
13558}
13559struct RenameActionPredicate {
13560    glob: GlobMatcher,
13561    kind: Option<FileOperationPatternKind>,
13562}
13563
13564impl RenameActionPredicate {
13565    // Returns true if language server should be notified
13566    fn eval(&self, path: &str, is_dir: bool) -> bool {
13567        self.kind.as_ref().is_none_or(|kind| {
13568            let expected_kind = if is_dir {
13569                FileOperationPatternKind::Folder
13570            } else {
13571                FileOperationPatternKind::File
13572            };
13573            kind == &expected_kind
13574        }) && self.glob.is_match(path)
13575    }
13576}
13577
13578#[derive(Default)]
13579struct LanguageServerWatchedPaths {
13580    worktree_paths: HashMap<WorktreeId, GlobSet>,
13581    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13582}
13583
13584#[derive(Default)]
13585struct LanguageServerWatchedPathsBuilder {
13586    worktree_paths: HashMap<WorktreeId, GlobSet>,
13587    abs_paths: HashMap<Arc<Path>, GlobSet>,
13588}
13589
13590impl LanguageServerWatchedPathsBuilder {
13591    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13592        self.worktree_paths.insert(worktree_id, glob_set);
13593    }
13594    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13595        self.abs_paths.insert(path, glob_set);
13596    }
13597    fn build(
13598        self,
13599        fs: Arc<dyn Fs>,
13600        language_server_id: LanguageServerId,
13601        cx: &mut Context<LspStore>,
13602    ) -> LanguageServerWatchedPaths {
13603        let lsp_store = cx.weak_entity();
13604
13605        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13606        let abs_paths = self
13607            .abs_paths
13608            .into_iter()
13609            .map(|(abs_path, globset)| {
13610                let task = cx.spawn({
13611                    let abs_path = abs_path.clone();
13612                    let fs = fs.clone();
13613
13614                    let lsp_store = lsp_store.clone();
13615                    async move |_, cx| {
13616                        maybe!(async move {
13617                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13618                            while let Some(update) = push_updates.0.next().await {
13619                                let action = lsp_store
13620                                    .update(cx, |this, _| {
13621                                        let Some(local) = this.as_local() else {
13622                                            return ControlFlow::Break(());
13623                                        };
13624                                        let Some(watcher) = local
13625                                            .language_server_watched_paths
13626                                            .get(&language_server_id)
13627                                        else {
13628                                            return ControlFlow::Break(());
13629                                        };
13630                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13631                                            "Watched abs path is not registered with a watcher",
13632                                        );
13633                                        let matching_entries = update
13634                                            .into_iter()
13635                                            .filter(|event| globs.is_match(&event.path))
13636                                            .collect::<Vec<_>>();
13637                                        this.lsp_notify_abs_paths_changed(
13638                                            language_server_id,
13639                                            matching_entries,
13640                                        );
13641                                        ControlFlow::Continue(())
13642                                    })
13643                                    .ok()?;
13644
13645                                if action.is_break() {
13646                                    break;
13647                                }
13648                            }
13649                            Some(())
13650                        })
13651                        .await;
13652                    }
13653                });
13654                (abs_path, (globset, task))
13655            })
13656            .collect();
13657        LanguageServerWatchedPaths {
13658            worktree_paths: self.worktree_paths,
13659            abs_paths,
13660        }
13661    }
13662}
13663
13664struct LspBufferSnapshot {
13665    version: i32,
13666    snapshot: TextBufferSnapshot,
13667}
13668
13669/// A prompt requested by LSP server.
13670#[derive(Clone, Debug)]
13671pub struct LanguageServerPromptRequest {
13672    pub id: usize,
13673    pub level: PromptLevel,
13674    pub message: String,
13675    pub actions: Vec<MessageActionItem>,
13676    pub lsp_name: String,
13677    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13678}
13679
13680impl LanguageServerPromptRequest {
13681    pub fn new(
13682        level: PromptLevel,
13683        message: String,
13684        actions: Vec<MessageActionItem>,
13685        lsp_name: String,
13686        response_channel: smol::channel::Sender<MessageActionItem>,
13687    ) -> Self {
13688        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13689        LanguageServerPromptRequest {
13690            id,
13691            level,
13692            message,
13693            actions,
13694            lsp_name,
13695            response_channel,
13696        }
13697    }
13698    pub async fn respond(self, index: usize) -> Option<()> {
13699        if let Some(response) = self.actions.into_iter().nth(index) {
13700            self.response_channel.send(response).await.ok()
13701        } else {
13702            None
13703        }
13704    }
13705
13706    #[cfg(any(test, feature = "test-support"))]
13707    pub fn test(
13708        level: PromptLevel,
13709        message: String,
13710        actions: Vec<MessageActionItem>,
13711        lsp_name: String,
13712    ) -> Self {
13713        let (tx, _rx) = smol::channel::unbounded();
13714        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13715    }
13716}
13717impl PartialEq for LanguageServerPromptRequest {
13718    fn eq(&self, other: &Self) -> bool {
13719        self.message == other.message && self.actions == other.actions
13720    }
13721}
13722
13723#[derive(Clone, Debug, PartialEq)]
13724pub enum LanguageServerLogType {
13725    Log(MessageType),
13726    Trace { verbose_info: Option<String> },
13727    Rpc { received: bool },
13728}
13729
13730impl LanguageServerLogType {
13731    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13732        match self {
13733            Self::Log(log_type) => {
13734                use proto::log_message::LogLevel;
13735                let level = match *log_type {
13736                    MessageType::ERROR => LogLevel::Error,
13737                    MessageType::WARNING => LogLevel::Warning,
13738                    MessageType::INFO => LogLevel::Info,
13739                    MessageType::LOG => LogLevel::Log,
13740                    other => {
13741                        log::warn!("Unknown lsp log message type: {other:?}");
13742                        LogLevel::Log
13743                    }
13744                };
13745                proto::language_server_log::LogType::Log(proto::LogMessage {
13746                    level: level as i32,
13747                })
13748            }
13749            Self::Trace { verbose_info } => {
13750                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13751                    verbose_info: verbose_info.to_owned(),
13752                })
13753            }
13754            Self::Rpc { received } => {
13755                let kind = if *received {
13756                    proto::rpc_message::Kind::Received
13757                } else {
13758                    proto::rpc_message::Kind::Sent
13759                };
13760                let kind = kind as i32;
13761                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13762            }
13763        }
13764    }
13765
13766    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13767        use proto::log_message::LogLevel;
13768        use proto::rpc_message;
13769        match log_type {
13770            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13771                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13772                    LogLevel::Error => MessageType::ERROR,
13773                    LogLevel::Warning => MessageType::WARNING,
13774                    LogLevel::Info => MessageType::INFO,
13775                    LogLevel::Log => MessageType::LOG,
13776                },
13777            ),
13778            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13779                verbose_info: trace_message.verbose_info,
13780            },
13781            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13782                received: match rpc_message::Kind::from_i32(message.kind)
13783                    .unwrap_or(rpc_message::Kind::Received)
13784                {
13785                    rpc_message::Kind::Received => true,
13786                    rpc_message::Kind::Sent => false,
13787                },
13788            },
13789        }
13790    }
13791}
13792
13793pub struct WorkspaceRefreshTask {
13794    refresh_tx: mpsc::Sender<()>,
13795    progress_tx: mpsc::Sender<()>,
13796    #[allow(dead_code)]
13797    task: Task<()>,
13798}
13799
13800pub enum LanguageServerState {
13801    Starting {
13802        startup: Task<Option<Arc<LanguageServer>>>,
13803        /// List of language servers that will be added to the workspace once it's initialization completes.
13804        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13805    },
13806
13807    Running {
13808        adapter: Arc<CachedLspAdapter>,
13809        server: Arc<LanguageServer>,
13810        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13811        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13812    },
13813}
13814
13815impl LanguageServerState {
13816    fn add_workspace_folder(&self, uri: Uri) {
13817        match self {
13818            LanguageServerState::Starting {
13819                pending_workspace_folders,
13820                ..
13821            } => {
13822                pending_workspace_folders.lock().insert(uri);
13823            }
13824            LanguageServerState::Running { server, .. } => {
13825                server.add_workspace_folder(uri);
13826            }
13827        }
13828    }
13829    fn _remove_workspace_folder(&self, uri: Uri) {
13830        match self {
13831            LanguageServerState::Starting {
13832                pending_workspace_folders,
13833                ..
13834            } => {
13835                pending_workspace_folders.lock().remove(&uri);
13836            }
13837            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13838        }
13839    }
13840}
13841
13842impl std::fmt::Debug for LanguageServerState {
13843    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13844        match self {
13845            LanguageServerState::Starting { .. } => {
13846                f.debug_struct("LanguageServerState::Starting").finish()
13847            }
13848            LanguageServerState::Running { .. } => {
13849                f.debug_struct("LanguageServerState::Running").finish()
13850            }
13851        }
13852    }
13853}
13854
13855#[derive(Clone, Debug, Serialize)]
13856pub struct LanguageServerProgress {
13857    pub is_disk_based_diagnostics_progress: bool,
13858    pub is_cancellable: bool,
13859    pub title: Option<String>,
13860    pub message: Option<String>,
13861    pub percentage: Option<usize>,
13862    #[serde(skip_serializing)]
13863    pub last_update_at: Instant,
13864}
13865
13866#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13867pub struct DiagnosticSummary {
13868    pub error_count: usize,
13869    pub warning_count: usize,
13870}
13871
13872impl DiagnosticSummary {
13873    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13874        let mut this = Self {
13875            error_count: 0,
13876            warning_count: 0,
13877        };
13878
13879        for entry in diagnostics {
13880            if entry.diagnostic.is_primary {
13881                match entry.diagnostic.severity {
13882                    DiagnosticSeverity::ERROR => this.error_count += 1,
13883                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13884                    _ => {}
13885                }
13886            }
13887        }
13888
13889        this
13890    }
13891
13892    pub fn is_empty(&self) -> bool {
13893        self.error_count == 0 && self.warning_count == 0
13894    }
13895
13896    pub fn to_proto(
13897        self,
13898        language_server_id: LanguageServerId,
13899        path: &RelPath,
13900    ) -> proto::DiagnosticSummary {
13901        proto::DiagnosticSummary {
13902            path: path.to_proto(),
13903            language_server_id: language_server_id.0 as u64,
13904            error_count: self.error_count as u32,
13905            warning_count: self.warning_count as u32,
13906        }
13907    }
13908}
13909
13910#[derive(Clone, Debug)]
13911pub enum CompletionDocumentation {
13912    /// There is no documentation for this completion.
13913    Undocumented,
13914    /// A single line of documentation.
13915    SingleLine(SharedString),
13916    /// Multiple lines of plain text documentation.
13917    MultiLinePlainText(SharedString),
13918    /// Markdown documentation.
13919    MultiLineMarkdown(SharedString),
13920    /// Both single line and multiple lines of plain text documentation.
13921    SingleLineAndMultiLinePlainText {
13922        single_line: SharedString,
13923        plain_text: Option<SharedString>,
13924    },
13925}
13926
13927impl CompletionDocumentation {
13928    #[cfg(any(test, feature = "test-support"))]
13929    pub fn text(&self) -> SharedString {
13930        match self {
13931            CompletionDocumentation::Undocumented => "".into(),
13932            CompletionDocumentation::SingleLine(s) => s.clone(),
13933            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13934            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13935            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13936                single_line.clone()
13937            }
13938        }
13939    }
13940}
13941
13942impl From<lsp::Documentation> for CompletionDocumentation {
13943    fn from(docs: lsp::Documentation) -> Self {
13944        match docs {
13945            lsp::Documentation::String(text) => {
13946                if text.lines().count() <= 1 {
13947                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13948                } else {
13949                    CompletionDocumentation::MultiLinePlainText(text.into())
13950                }
13951            }
13952
13953            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13954                lsp::MarkupKind::PlainText => {
13955                    if value.lines().count() <= 1 {
13956                        CompletionDocumentation::SingleLine(value.into())
13957                    } else {
13958                        CompletionDocumentation::MultiLinePlainText(value.into())
13959                    }
13960                }
13961
13962                lsp::MarkupKind::Markdown => {
13963                    CompletionDocumentation::MultiLineMarkdown(value.into())
13964                }
13965            },
13966        }
13967    }
13968}
13969
13970pub enum ResolvedHint {
13971    Resolved(InlayHint),
13972    Resolving(Shared<Task<()>>),
13973}
13974
13975pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13976    glob.components()
13977        .take_while(|component| match component {
13978            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13979            _ => true,
13980        })
13981        .collect()
13982}
13983
13984pub struct SshLspAdapter {
13985    name: LanguageServerName,
13986    binary: LanguageServerBinary,
13987    initialization_options: Option<String>,
13988    code_action_kinds: Option<Vec<CodeActionKind>>,
13989}
13990
13991impl SshLspAdapter {
13992    pub fn new(
13993        name: LanguageServerName,
13994        binary: LanguageServerBinary,
13995        initialization_options: Option<String>,
13996        code_action_kinds: Option<String>,
13997    ) -> Self {
13998        Self {
13999            name,
14000            binary,
14001            initialization_options,
14002            code_action_kinds: code_action_kinds
14003                .as_ref()
14004                .and_then(|c| serde_json::from_str(c).ok()),
14005        }
14006    }
14007}
14008
14009impl LspInstaller for SshLspAdapter {
14010    type BinaryVersion = ();
14011    async fn check_if_user_installed(
14012        &self,
14013        _: &dyn LspAdapterDelegate,
14014        _: Option<Toolchain>,
14015        _: &AsyncApp,
14016    ) -> Option<LanguageServerBinary> {
14017        Some(self.binary.clone())
14018    }
14019
14020    async fn cached_server_binary(
14021        &self,
14022        _: PathBuf,
14023        _: &dyn LspAdapterDelegate,
14024    ) -> Option<LanguageServerBinary> {
14025        None
14026    }
14027
14028    async fn fetch_latest_server_version(
14029        &self,
14030        _: &dyn LspAdapterDelegate,
14031        _: bool,
14032        _: &mut AsyncApp,
14033    ) -> Result<()> {
14034        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14035    }
14036
14037    async fn fetch_server_binary(
14038        &self,
14039        _: (),
14040        _: PathBuf,
14041        _: &dyn LspAdapterDelegate,
14042    ) -> Result<LanguageServerBinary> {
14043        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14044    }
14045}
14046
14047#[async_trait(?Send)]
14048impl LspAdapter for SshLspAdapter {
14049    fn name(&self) -> LanguageServerName {
14050        self.name.clone()
14051    }
14052
14053    async fn initialization_options(
14054        self: Arc<Self>,
14055        _: &Arc<dyn LspAdapterDelegate>,
14056        _: &mut AsyncApp,
14057    ) -> Result<Option<serde_json::Value>> {
14058        let Some(options) = &self.initialization_options else {
14059            return Ok(None);
14060        };
14061        let result = serde_json::from_str(options)?;
14062        Ok(result)
14063    }
14064
14065    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14066        self.code_action_kinds.clone()
14067    }
14068}
14069
14070pub fn language_server_settings<'a>(
14071    delegate: &'a dyn LspAdapterDelegate,
14072    language: &LanguageServerName,
14073    cx: &'a App,
14074) -> Option<&'a LspSettings> {
14075    language_server_settings_for(
14076        SettingsLocation {
14077            worktree_id: delegate.worktree_id(),
14078            path: RelPath::empty(),
14079        },
14080        language,
14081        cx,
14082    )
14083}
14084
14085pub fn language_server_settings_for<'a>(
14086    location: SettingsLocation<'a>,
14087    language: &LanguageServerName,
14088    cx: &'a App,
14089) -> Option<&'a LspSettings> {
14090    ProjectSettings::get(Some(location), cx).lsp.get(language)
14091}
14092
14093pub struct LocalLspAdapterDelegate {
14094    lsp_store: WeakEntity<LspStore>,
14095    worktree: worktree::Snapshot,
14096    fs: Arc<dyn Fs>,
14097    http_client: Arc<dyn HttpClient>,
14098    language_registry: Arc<LanguageRegistry>,
14099    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14100}
14101
14102impl LocalLspAdapterDelegate {
14103    pub fn new(
14104        language_registry: Arc<LanguageRegistry>,
14105        environment: &Entity<ProjectEnvironment>,
14106        lsp_store: WeakEntity<LspStore>,
14107        worktree: &Entity<Worktree>,
14108        http_client: Arc<dyn HttpClient>,
14109        fs: Arc<dyn Fs>,
14110        cx: &mut App,
14111    ) -> Arc<Self> {
14112        let load_shell_env_task =
14113            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14114
14115        Arc::new(Self {
14116            lsp_store,
14117            worktree: worktree.read(cx).snapshot(),
14118            fs,
14119            http_client,
14120            language_registry,
14121            load_shell_env_task,
14122        })
14123    }
14124
14125    pub fn from_local_lsp(
14126        local: &LocalLspStore,
14127        worktree: &Entity<Worktree>,
14128        cx: &mut App,
14129    ) -> Arc<Self> {
14130        Self::new(
14131            local.languages.clone(),
14132            &local.environment,
14133            local.weak.clone(),
14134            worktree,
14135            local.http_client.clone(),
14136            local.fs.clone(),
14137            cx,
14138        )
14139    }
14140}
14141
14142#[async_trait]
14143impl LspAdapterDelegate for LocalLspAdapterDelegate {
14144    fn show_notification(&self, message: &str, cx: &mut App) {
14145        self.lsp_store
14146            .update(cx, |_, cx| {
14147                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14148            })
14149            .ok();
14150    }
14151
14152    fn http_client(&self) -> Arc<dyn HttpClient> {
14153        self.http_client.clone()
14154    }
14155
14156    fn worktree_id(&self) -> WorktreeId {
14157        self.worktree.id()
14158    }
14159
14160    fn worktree_root_path(&self) -> &Path {
14161        self.worktree.abs_path().as_ref()
14162    }
14163
14164    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14165        self.worktree.resolve_relative_path(path)
14166    }
14167
14168    async fn shell_env(&self) -> HashMap<String, String> {
14169        let task = self.load_shell_env_task.clone();
14170        task.await.unwrap_or_default()
14171    }
14172
14173    async fn npm_package_installed_version(
14174        &self,
14175        package_name: &str,
14176    ) -> Result<Option<(PathBuf, Version)>> {
14177        let local_package_directory = self.worktree_root_path();
14178        let node_modules_directory = local_package_directory.join("node_modules");
14179
14180        if let Some(version) =
14181            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14182        {
14183            return Ok(Some((node_modules_directory, version)));
14184        }
14185        let Some(npm) = self.which("npm".as_ref()).await else {
14186            log::warn!(
14187                "Failed to find npm executable for {:?}",
14188                local_package_directory
14189            );
14190            return Ok(None);
14191        };
14192
14193        let env = self.shell_env().await;
14194        let output = util::command::new_command(&npm)
14195            .args(["root", "-g"])
14196            .envs(env)
14197            .current_dir(local_package_directory)
14198            .output()
14199            .await?;
14200        let global_node_modules =
14201            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14202
14203        if let Some(version) =
14204            read_package_installed_version(global_node_modules.clone(), package_name).await?
14205        {
14206            return Ok(Some((global_node_modules, version)));
14207        }
14208        return Ok(None);
14209    }
14210
14211    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14212        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14213        if self.fs.is_file(&worktree_abs_path).await {
14214            worktree_abs_path.pop();
14215        }
14216
14217        let env = self.shell_env().await;
14218
14219        let shell_path = env.get("PATH").cloned();
14220
14221        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14222    }
14223
14224    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14225        let mut working_dir = self.worktree_root_path().to_path_buf();
14226        if self.fs.is_file(&working_dir).await {
14227            working_dir.pop();
14228        }
14229        let output = util::command::new_command(&command.path)
14230            .args(command.arguments)
14231            .envs(command.env.clone().unwrap_or_default())
14232            .current_dir(working_dir)
14233            .output()
14234            .await?;
14235
14236        anyhow::ensure!(
14237            output.status.success(),
14238            "{}, stdout: {:?}, stderr: {:?}",
14239            output.status,
14240            String::from_utf8_lossy(&output.stdout),
14241            String::from_utf8_lossy(&output.stderr)
14242        );
14243        Ok(())
14244    }
14245
14246    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14247        self.language_registry
14248            .update_lsp_binary_status(server_name, status);
14249    }
14250
14251    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14252        self.language_registry
14253            .all_lsp_adapters()
14254            .into_iter()
14255            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14256            .collect()
14257    }
14258
14259    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14260        let dir = self.language_registry.language_server_download_dir(name)?;
14261
14262        if !dir.exists() {
14263            smol::fs::create_dir_all(&dir)
14264                .await
14265                .context("failed to create container directory")
14266                .log_err()?;
14267        }
14268
14269        Some(dir)
14270    }
14271
14272    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14273        let entry = self
14274            .worktree
14275            .entry_for_path(path)
14276            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14277        let abs_path = self.worktree.absolutize(&entry.path);
14278        self.fs.load(&abs_path).await
14279    }
14280}
14281
14282async fn populate_labels_for_symbols(
14283    symbols: Vec<CoreSymbol>,
14284    language_registry: &Arc<LanguageRegistry>,
14285    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14286    output: &mut Vec<Symbol>,
14287) {
14288    #[allow(clippy::mutable_key_type)]
14289    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14290
14291    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14292    for symbol in symbols {
14293        let Some(file_name) = symbol.path.file_name() else {
14294            continue;
14295        };
14296        let language = language_registry
14297            .load_language_for_file_path(Path::new(file_name))
14298            .await
14299            .ok()
14300            .or_else(|| {
14301                unknown_paths.insert(file_name.into());
14302                None
14303            });
14304        symbols_by_language
14305            .entry(language)
14306            .or_default()
14307            .push(symbol);
14308    }
14309
14310    for unknown_path in unknown_paths {
14311        log::info!("no language found for symbol in file {unknown_path:?}");
14312    }
14313
14314    let mut label_params = Vec::new();
14315    for (language, mut symbols) in symbols_by_language {
14316        label_params.clear();
14317        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14318            name: mem::take(&mut symbol.name),
14319            kind: symbol.kind,
14320            container_name: symbol.container_name.take(),
14321        }));
14322
14323        let mut labels = Vec::new();
14324        if let Some(language) = language {
14325            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14326                language_registry
14327                    .lsp_adapters(&language.name())
14328                    .first()
14329                    .cloned()
14330            });
14331            if let Some(lsp_adapter) = lsp_adapter {
14332                labels = lsp_adapter
14333                    .labels_for_symbols(&label_params, &language)
14334                    .await
14335                    .log_err()
14336                    .unwrap_or_default();
14337            }
14338        }
14339
14340        for (
14341            (
14342                symbol,
14343                language::Symbol {
14344                    name,
14345                    container_name,
14346                    ..
14347                },
14348            ),
14349            label,
14350        ) in symbols
14351            .into_iter()
14352            .zip(label_params.drain(..))
14353            .zip(labels.into_iter().chain(iter::repeat(None)))
14354        {
14355            output.push(Symbol {
14356                language_server_name: symbol.language_server_name,
14357                source_worktree_id: symbol.source_worktree_id,
14358                source_language_server_id: symbol.source_language_server_id,
14359                path: symbol.path,
14360                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14361                name,
14362                kind: symbol.kind,
14363                range: symbol.range,
14364                container_name,
14365            });
14366        }
14367    }
14368}
14369
14370pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14371    text.lines()
14372        .map(|line| line.trim())
14373        .filter(|line| !line.is_empty())
14374        .join(separator)
14375}
14376
14377fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14378    match server.capabilities().text_document_sync.as_ref()? {
14379        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14380            // Server wants didSave but didn't specify includeText.
14381            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14382            // Server doesn't want didSave at all.
14383            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14384            // Server provided SaveOptions.
14385            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14386                Some(save_options.include_text.unwrap_or(false))
14387            }
14388        },
14389        // We do not have any save info. Kind affects didChange only.
14390        lsp::TextDocumentSyncCapability::Kind(_) => None,
14391    }
14392}
14393
14394/// Completion items are displayed in a `UniformList`.
14395/// Usually, those items are single-line strings, but in LSP responses,
14396/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14397/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14398/// 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,
14399/// breaking the completions menu presentation.
14400///
14401/// 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.
14402pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14403    let mut new_text = String::with_capacity(label.text.len());
14404    let mut offset_map = vec![0; label.text.len() + 1];
14405    let mut last_char_was_space = false;
14406    let mut new_idx = 0;
14407    let chars = label.text.char_indices().fuse();
14408    let mut newlines_removed = false;
14409
14410    for (idx, c) in chars {
14411        offset_map[idx] = new_idx;
14412
14413        match c {
14414            '\n' if last_char_was_space => {
14415                newlines_removed = true;
14416            }
14417            '\t' | ' ' if last_char_was_space => {}
14418            '\n' if !last_char_was_space => {
14419                new_text.push(' ');
14420                new_idx += 1;
14421                last_char_was_space = true;
14422                newlines_removed = true;
14423            }
14424            ' ' | '\t' => {
14425                new_text.push(' ');
14426                new_idx += 1;
14427                last_char_was_space = true;
14428            }
14429            _ => {
14430                new_text.push(c);
14431                new_idx += c.len_utf8();
14432                last_char_was_space = false;
14433            }
14434        }
14435    }
14436    offset_map[label.text.len()] = new_idx;
14437
14438    // Only modify the label if newlines were removed.
14439    if !newlines_removed {
14440        return;
14441    }
14442
14443    let last_index = new_idx;
14444    let mut run_ranges_errors = Vec::new();
14445    label.runs.retain_mut(|(range, _)| {
14446        match offset_map.get(range.start) {
14447            Some(&start) => range.start = start,
14448            None => {
14449                run_ranges_errors.push(range.clone());
14450                return false;
14451            }
14452        }
14453
14454        match offset_map.get(range.end) {
14455            Some(&end) => range.end = end,
14456            None => {
14457                run_ranges_errors.push(range.clone());
14458                range.end = last_index;
14459            }
14460        }
14461        true
14462    });
14463    if !run_ranges_errors.is_empty() {
14464        log::error!(
14465            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14466            label.text
14467        );
14468    }
14469
14470    let mut wrong_filter_range = None;
14471    if label.filter_range == (0..label.text.len()) {
14472        label.filter_range = 0..new_text.len();
14473    } else {
14474        let mut original_filter_range = Some(label.filter_range.clone());
14475        match offset_map.get(label.filter_range.start) {
14476            Some(&start) => label.filter_range.start = start,
14477            None => {
14478                wrong_filter_range = original_filter_range.take();
14479                label.filter_range.start = last_index;
14480            }
14481        }
14482
14483        match offset_map.get(label.filter_range.end) {
14484            Some(&end) => label.filter_range.end = end,
14485            None => {
14486                wrong_filter_range = original_filter_range.take();
14487                label.filter_range.end = last_index;
14488            }
14489        }
14490    }
14491    if let Some(wrong_filter_range) = wrong_filter_range {
14492        log::error!(
14493            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14494            label.text
14495        );
14496    }
14497
14498    label.text = new_text;
14499}