lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   75    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   76    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   77    Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80        language_settings,
   81    },
   82    point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153pub use semantic_tokens::{
  154    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  155};
  156
  157pub use worktree::{
  158    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  159    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  160};
  161
  162const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  163pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  164const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  165const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  166static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  167
  168#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  169pub enum ProgressToken {
  170    Number(i32),
  171    String(SharedString),
  172}
  173
  174impl std::fmt::Display for ProgressToken {
  175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  176        match self {
  177            Self::Number(number) => write!(f, "{number}"),
  178            Self::String(string) => write!(f, "{string}"),
  179        }
  180    }
  181}
  182
  183impl ProgressToken {
  184    fn from_lsp(value: lsp::NumberOrString) -> Self {
  185        match value {
  186            lsp::NumberOrString::Number(number) => Self::Number(number),
  187            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  188        }
  189    }
  190
  191    fn to_lsp(&self) -> lsp::NumberOrString {
  192        match self {
  193            Self::Number(number) => lsp::NumberOrString::Number(*number),
  194            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  195        }
  196    }
  197
  198    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  199        Some(match value.value? {
  200            proto::progress_token::Value::Number(number) => Self::Number(number),
  201            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  202        })
  203    }
  204
  205    fn to_proto(&self) -> proto::ProgressToken {
  206        proto::ProgressToken {
  207            value: Some(match self {
  208                Self::Number(number) => proto::progress_token::Value::Number(*number),
  209                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  210            }),
  211        }
  212    }
  213}
  214
  215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  216pub enum FormatTrigger {
  217    Save,
  218    Manual,
  219}
  220
  221pub enum LspFormatTarget {
  222    Buffers,
  223    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  224}
  225
  226#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  227pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  228
  229struct OpenLspBuffer(Entity<Buffer>);
  230
  231impl FormatTrigger {
  232    fn from_proto(value: i32) -> FormatTrigger {
  233        match value {
  234            0 => FormatTrigger::Save,
  235            1 => FormatTrigger::Manual,
  236            _ => FormatTrigger::Save,
  237        }
  238    }
  239}
  240
  241#[derive(Clone)]
  242struct UnifiedLanguageServer {
  243    id: LanguageServerId,
  244    project_roots: HashSet<Arc<RelPath>>,
  245}
  246
  247/// Settings that affect language server identity.
  248///
  249/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  250/// updated via `workspace/didChangeConfiguration` without restarting the server.
  251#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  252struct LanguageServerSeedSettings {
  253    binary: Option<BinarySettings>,
  254    initialization_options: Option<serde_json::Value>,
  255}
  256
  257#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  258struct LanguageServerSeed {
  259    worktree_id: WorktreeId,
  260    name: LanguageServerName,
  261    toolchain: Option<Toolchain>,
  262    settings: LanguageServerSeedSettings,
  263}
  264
  265#[derive(Debug)]
  266pub struct DocumentDiagnosticsUpdate<'a, D> {
  267    pub diagnostics: D,
  268    pub result_id: Option<SharedString>,
  269    pub registration_id: Option<SharedString>,
  270    pub server_id: LanguageServerId,
  271    pub disk_based_sources: Cow<'a, [String]>,
  272}
  273
  274pub struct DocumentDiagnostics {
  275    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276    document_abs_path: PathBuf,
  277    version: Option<i32>,
  278}
  279
  280#[derive(Default, Debug)]
  281struct DynamicRegistrations {
  282    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  283    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  284}
  285
  286pub struct LocalLspStore {
  287    weak: WeakEntity<LspStore>,
  288    pub worktree_store: Entity<WorktreeStore>,
  289    toolchain_store: Entity<LocalToolchainStore>,
  290    http_client: Arc<dyn HttpClient>,
  291    environment: Entity<ProjectEnvironment>,
  292    fs: Arc<dyn Fs>,
  293    languages: Arc<LanguageRegistry>,
  294    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  295    yarn: Entity<YarnPathStore>,
  296    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  297    buffers_being_formatted: HashSet<BufferId>,
  298    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  299    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  300    watched_manifest_filenames: HashSet<ManifestName>,
  301    language_server_paths_watched_for_rename:
  302        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  303    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  304    supplementary_language_servers:
  305        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  306    prettier_store: Entity<PrettierStore>,
  307    next_diagnostic_group_id: usize,
  308    diagnostics: HashMap<
  309        WorktreeId,
  310        HashMap<
  311            Arc<RelPath>,
  312            Vec<(
  313                LanguageServerId,
  314                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  315            )>,
  316        >,
  317    >,
  318    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  319    _subscriptions: Vec<gpui::Subscription>,
  320    lsp_tree: LanguageServerTree,
  321    registered_buffers: HashMap<BufferId, usize>,
  322    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  323    buffer_pull_diagnostics_result_ids: HashMap<
  324        LanguageServerId,
  325        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  326    >,
  327    workspace_pull_diagnostics_result_ids: HashMap<
  328        LanguageServerId,
  329        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  330    >,
  331    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  332
  333    buffers_to_refresh_hash_set: HashSet<BufferId>,
  334    buffers_to_refresh_queue: VecDeque<BufferId>,
  335    _background_diagnostics_worker: Shared<Task<()>>,
  336}
  337
  338impl LocalLspStore {
  339    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  340    pub fn running_language_server_for_id(
  341        &self,
  342        id: LanguageServerId,
  343    ) -> Option<&Arc<LanguageServer>> {
  344        let language_server_state = self.language_servers.get(&id)?;
  345
  346        match language_server_state {
  347            LanguageServerState::Running { server, .. } => Some(server),
  348            LanguageServerState::Starting { .. } => None,
  349        }
  350    }
  351
  352    fn get_or_insert_language_server(
  353        &mut self,
  354        worktree_handle: &Entity<Worktree>,
  355        delegate: Arc<LocalLspAdapterDelegate>,
  356        disposition: &Arc<LaunchDisposition>,
  357        language_name: &LanguageName,
  358        cx: &mut App,
  359    ) -> LanguageServerId {
  360        let key = LanguageServerSeed {
  361            worktree_id: worktree_handle.read(cx).id(),
  362            name: disposition.server_name.clone(),
  363            settings: LanguageServerSeedSettings {
  364                binary: disposition.settings.binary.clone(),
  365                initialization_options: disposition.settings.initialization_options.clone(),
  366            },
  367            toolchain: disposition.toolchain.clone(),
  368        };
  369        if let Some(state) = self.language_server_ids.get_mut(&key) {
  370            state.project_roots.insert(disposition.path.path.clone());
  371            state.id
  372        } else {
  373            let adapter = self
  374                .languages
  375                .lsp_adapters(language_name)
  376                .into_iter()
  377                .find(|adapter| adapter.name() == disposition.server_name)
  378                .expect("To find LSP adapter");
  379            let new_language_server_id = self.start_language_server(
  380                worktree_handle,
  381                delegate,
  382                adapter,
  383                disposition.settings.clone(),
  384                key.clone(),
  385                language_name.clone(),
  386                cx,
  387            );
  388            if let Some(state) = self.language_server_ids.get_mut(&key) {
  389                state.project_roots.insert(disposition.path.path.clone());
  390            } else {
  391                debug_assert!(
  392                    false,
  393                    "Expected `start_language_server` to ensure that `key` exists in a map"
  394                );
  395            }
  396            new_language_server_id
  397        }
  398    }
  399
  400    fn start_language_server(
  401        &mut self,
  402        worktree_handle: &Entity<Worktree>,
  403        delegate: Arc<LocalLspAdapterDelegate>,
  404        adapter: Arc<CachedLspAdapter>,
  405        settings: Arc<LspSettings>,
  406        key: LanguageServerSeed,
  407        language_name: LanguageName,
  408        cx: &mut App,
  409    ) -> LanguageServerId {
  410        let worktree = worktree_handle.read(cx);
  411
  412        let worktree_id = worktree.id();
  413        let worktree_abs_path = worktree.abs_path();
  414        let toolchain = key.toolchain.clone();
  415        let override_options = settings.initialization_options.clone();
  416
  417        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  418
  419        let server_id = self.languages.next_language_server_id();
  420        log::trace!(
  421            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  422            adapter.name.0
  423        );
  424
  425        let wait_until_worktree_trust =
  426            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  427                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  428                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  429                });
  430                if can_trust {
  431                    self.restricted_worktrees_tasks.remove(&worktree_id);
  432                    None
  433                } else {
  434                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  435                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  436                        hash_map::Entry::Vacant(v) => {
  437                            let (mut tx, rx) = watch::channel::<bool>();
  438                            let lsp_store = self.weak.clone();
  439                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  440                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  441                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  442                                        tx.blocking_send(true).ok();
  443                                        lsp_store
  444                                            .update(cx, |lsp_store, _| {
  445                                                if let Some(local_lsp_store) =
  446                                                    lsp_store.as_local_mut()
  447                                                {
  448                                                    local_lsp_store
  449                                                        .restricted_worktrees_tasks
  450                                                        .remove(&worktree_id);
  451                                                }
  452                                            })
  453                                            .ok();
  454                                    }
  455                                }
  456                            });
  457                            v.insert((subscription, rx.clone()));
  458                            Some(rx)
  459                        }
  460                    }
  461                }
  462            });
  463        let update_binary_status = wait_until_worktree_trust.is_none();
  464
  465        let binary = self.get_language_server_binary(
  466            worktree_abs_path.clone(),
  467            adapter.clone(),
  468            settings,
  469            toolchain.clone(),
  470            delegate.clone(),
  471            true,
  472            wait_until_worktree_trust,
  473            cx,
  474        );
  475        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  476
  477        let pending_server = cx.spawn({
  478            let adapter = adapter.clone();
  479            let server_name = adapter.name.clone();
  480            let stderr_capture = stderr_capture.clone();
  481            #[cfg(any(test, feature = "test-support"))]
  482            let lsp_store = self.weak.clone();
  483            let pending_workspace_folders = pending_workspace_folders.clone();
  484            async move |cx| {
  485                let binary = binary.await?;
  486                #[cfg(any(test, feature = "test-support"))]
  487                if let Some(server) = lsp_store
  488                    .update(&mut cx.clone(), |this, cx| {
  489                        this.languages.create_fake_language_server(
  490                            server_id,
  491                            &server_name,
  492                            binary.clone(),
  493                            &mut cx.to_async(),
  494                        )
  495                    })
  496                    .ok()
  497                    .flatten()
  498                {
  499                    return Ok(server);
  500                }
  501
  502                let code_action_kinds = adapter.code_action_kinds();
  503                lsp::LanguageServer::new(
  504                    stderr_capture,
  505                    server_id,
  506                    server_name,
  507                    binary,
  508                    &worktree_abs_path,
  509                    code_action_kinds,
  510                    Some(pending_workspace_folders),
  511                    cx,
  512                )
  513            }
  514        });
  515
  516        let startup = {
  517            let server_name = adapter.name.0.clone();
  518            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  519            let key = key.clone();
  520            let adapter = adapter.clone();
  521            let lsp_store = self.weak.clone();
  522            let pending_workspace_folders = pending_workspace_folders.clone();
  523            let pull_diagnostics = ProjectSettings::get_global(cx)
  524                .diagnostics
  525                .lsp_pull_diagnostics
  526                .enabled;
  527            let settings_location = SettingsLocation {
  528                worktree_id,
  529                path: RelPath::empty(),
  530            };
  531            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  532                .language(Some(settings_location), Some(&language_name), cx)
  533                .semantic_tokens
  534                .use_tree_sitter();
  535            cx.spawn(async move |cx| {
  536                let result = async {
  537                    let language_server = pending_server.await?;
  538
  539                    let workspace_config = Self::workspace_configuration_for_adapter(
  540                        adapter.adapter.clone(),
  541                        &delegate,
  542                        toolchain,
  543                        None,
  544                        cx,
  545                    )
  546                    .await?;
  547
  548                    let mut initialization_options = Self::initialization_options_for_adapter(
  549                        adapter.adapter.clone(),
  550                        &delegate,
  551                        cx,
  552                    )
  553                    .await?;
  554
  555                    match (&mut initialization_options, override_options) {
  556                        (Some(initialization_options), Some(override_options)) => {
  557                            merge_json_value_into(override_options, initialization_options);
  558                        }
  559                        (None, override_options) => initialization_options = override_options,
  560                        _ => {}
  561                    }
  562
  563                    let initialization_params = cx.update(|cx| {
  564                        let mut params = language_server.default_initialize_params(
  565                            pull_diagnostics,
  566                            augments_syntax_tokens,
  567                            cx,
  568                        );
  569                        params.initialization_options = initialization_options;
  570                        adapter.adapter.prepare_initialize_params(params, cx)
  571                    })?;
  572
  573                    Self::setup_lsp_messages(
  574                        lsp_store.clone(),
  575                        &language_server,
  576                        delegate.clone(),
  577                        adapter.clone(),
  578                    );
  579
  580                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  581                        settings: workspace_config,
  582                    };
  583                    let language_server = cx
  584                        .update(|cx| {
  585                            let request_timeout = ProjectSettings::get_global(cx)
  586                                .global_lsp_settings
  587                                .get_request_timeout();
  588
  589                            language_server.initialize(
  590                                initialization_params,
  591                                Arc::new(did_change_configuration_params.clone()),
  592                                request_timeout,
  593                                cx,
  594                            )
  595                        })
  596                        .await
  597                        .inspect_err(|_| {
  598                            if let Some(lsp_store) = lsp_store.upgrade() {
  599                                lsp_store.update(cx, |lsp_store, cx| {
  600                                    lsp_store.cleanup_lsp_data(server_id);
  601                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  602                                });
  603                            }
  604                        })?;
  605
  606                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  607                        did_change_configuration_params,
  608                    )?;
  609
  610                    anyhow::Ok(language_server)
  611                }
  612                .await;
  613
  614                match result {
  615                    Ok(server) => {
  616                        lsp_store
  617                            .update(cx, |lsp_store, cx| {
  618                                lsp_store.insert_newly_running_language_server(
  619                                    adapter,
  620                                    server.clone(),
  621                                    server_id,
  622                                    key,
  623                                    pending_workspace_folders,
  624                                    cx,
  625                                );
  626                            })
  627                            .ok();
  628                        stderr_capture.lock().take();
  629                        Some(server)
  630                    }
  631
  632                    Err(err) => {
  633                        let log = stderr_capture.lock().take().unwrap_or_default();
  634                        delegate.update_status(
  635                            adapter.name(),
  636                            BinaryStatus::Failed {
  637                                error: if log.is_empty() {
  638                                    format!("{err:#}")
  639                                } else {
  640                                    format!("{err:#}\n-- stderr --\n{log}")
  641                                },
  642                            },
  643                        );
  644                        log::error!(
  645                            "Failed to start language server {server_name:?}: {}",
  646                            redact_command(&format!("{err:?}"))
  647                        );
  648                        if !log.is_empty() {
  649                            log::error!("server stderr: {}", redact_command(&log));
  650                        }
  651                        None
  652                    }
  653                }
  654            })
  655        };
  656        let state = LanguageServerState::Starting {
  657            startup,
  658            pending_workspace_folders,
  659        };
  660
  661        if update_binary_status {
  662            self.languages
  663                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  664        }
  665
  666        self.language_servers.insert(server_id, state);
  667        self.language_server_ids
  668            .entry(key)
  669            .or_insert(UnifiedLanguageServer {
  670                id: server_id,
  671                project_roots: Default::default(),
  672            });
  673        server_id
  674    }
  675
  676    fn get_language_server_binary(
  677        &self,
  678        worktree_abs_path: Arc<Path>,
  679        adapter: Arc<CachedLspAdapter>,
  680        settings: Arc<LspSettings>,
  681        toolchain: Option<Toolchain>,
  682        delegate: Arc<dyn LspAdapterDelegate>,
  683        allow_binary_download: bool,
  684        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  685        cx: &mut App,
  686    ) -> Task<Result<LanguageServerBinary>> {
  687        if let Some(settings) = &settings.binary
  688            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  689        {
  690            let settings = settings.clone();
  691            let languages = self.languages.clone();
  692            return cx.background_spawn(async move {
  693                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  694                    let already_trusted =  *wait_until_worktree_trust.borrow();
  695                    if !already_trusted {
  696                        log::info!(
  697                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  698                            adapter.name(),
  699                        );
  700                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  701                            if worktree_trusted {
  702                                break;
  703                            }
  704                        }
  705                        log::info!(
  706                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  707                            adapter.name(),
  708                        );
  709                    }
  710                    languages
  711                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  712                }
  713                let mut env = delegate.shell_env().await;
  714                env.extend(settings.env.unwrap_or_default());
  715
  716                Ok(LanguageServerBinary {
  717                    path: delegate.resolve_relative_path(path),
  718                    env: Some(env),
  719                    arguments: settings
  720                        .arguments
  721                        .unwrap_or_default()
  722                        .iter()
  723                        .map(Into::into)
  724                        .collect(),
  725                })
  726            });
  727        }
  728        let lsp_binary_options = LanguageServerBinaryOptions {
  729            allow_path_lookup: !settings
  730                .binary
  731                .as_ref()
  732                .and_then(|b| b.ignore_system_version)
  733                .unwrap_or_default(),
  734            allow_binary_download,
  735            pre_release: settings
  736                .fetch
  737                .as_ref()
  738                .and_then(|f| f.pre_release)
  739                .unwrap_or(false),
  740        };
  741
  742        cx.spawn(async move |cx| {
  743            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  744                let already_trusted =  *wait_until_worktree_trust.borrow();
  745                if !already_trusted {
  746                    log::info!(
  747                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  748                        adapter.name(),
  749                    );
  750                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  751                        if worktree_trusted {
  752                            break;
  753                        }
  754                    }
  755                    log::info!(
  756                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  757                            adapter.name(),
  758                    );
  759                }
  760            }
  761
  762            let (existing_binary, maybe_download_binary) = adapter
  763                .clone()
  764                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  765                .await
  766                .await;
  767
  768            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  769
  770            let mut binary = match (existing_binary, maybe_download_binary) {
  771                (binary, None) => binary?,
  772                (Err(_), Some(downloader)) => downloader.await?,
  773                (Ok(existing_binary), Some(downloader)) => {
  774                    let mut download_timeout = cx
  775                        .background_executor()
  776                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  777                        .fuse();
  778                    let mut downloader = downloader.fuse();
  779                    futures::select! {
  780                        _ = download_timeout => {
  781                            // Return existing binary and kick the existing work to the background.
  782                            cx.spawn(async move |_| downloader.await).detach();
  783                            Ok(existing_binary)
  784                        },
  785                        downloaded_or_existing_binary = downloader => {
  786                            // If download fails, this results in the existing binary.
  787                            downloaded_or_existing_binary
  788                        }
  789                    }?
  790                }
  791            };
  792            let mut shell_env = delegate.shell_env().await;
  793
  794            shell_env.extend(binary.env.unwrap_or_default());
  795
  796            if let Some(settings) = settings.binary.as_ref() {
  797                if let Some(arguments) = &settings.arguments {
  798                    binary.arguments = arguments.iter().map(Into::into).collect();
  799                }
  800                if let Some(env) = &settings.env {
  801                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  802                }
  803            }
  804
  805            binary.env = Some(shell_env);
  806            Ok(binary)
  807        })
  808    }
  809
  810    fn setup_lsp_messages(
  811        lsp_store: WeakEntity<LspStore>,
  812        language_server: &LanguageServer,
  813        delegate: Arc<dyn LspAdapterDelegate>,
  814        adapter: Arc<CachedLspAdapter>,
  815    ) {
  816        let name = language_server.name();
  817        let server_id = language_server.server_id();
  818        language_server
  819            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  820                let adapter = adapter.clone();
  821                let this = lsp_store.clone();
  822                move |mut params, cx| {
  823                    let adapter = adapter.clone();
  824                    if let Some(this) = this.upgrade() {
  825                        this.update(cx, |this, cx| {
  826                            {
  827                                let buffer = params
  828                                    .uri
  829                                    .to_file_path()
  830                                    .map(|file_path| this.get_buffer(&file_path, cx))
  831                                    .ok()
  832                                    .flatten();
  833                                adapter.process_diagnostics(&mut params, server_id, buffer);
  834                            }
  835
  836                            this.merge_lsp_diagnostics(
  837                                DiagnosticSourceKind::Pushed,
  838                                vec![DocumentDiagnosticsUpdate {
  839                                    server_id,
  840                                    diagnostics: params,
  841                                    result_id: None,
  842                                    disk_based_sources: Cow::Borrowed(
  843                                        &adapter.disk_based_diagnostic_sources,
  844                                    ),
  845                                    registration_id: None,
  846                                }],
  847                                |_, diagnostic, cx| match diagnostic.source_kind {
  848                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  849                                        adapter.retain_old_diagnostic(diagnostic, cx)
  850                                    }
  851                                    DiagnosticSourceKind::Pulled => true,
  852                                },
  853                                cx,
  854                            )
  855                            .log_err();
  856                        });
  857                    }
  858                }
  859            })
  860            .detach();
  861        language_server
  862            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  863                let adapter = adapter.adapter.clone();
  864                let delegate = delegate.clone();
  865                let this = lsp_store.clone();
  866                move |params, cx| {
  867                    let adapter = adapter.clone();
  868                    let delegate = delegate.clone();
  869                    let this = this.clone();
  870                    let mut cx = cx.clone();
  871                    async move {
  872                        let toolchain_for_id = this
  873                            .update(&mut cx, |this, _| {
  874                                this.as_local()?.language_server_ids.iter().find_map(
  875                                    |(seed, value)| {
  876                                        (value.id == server_id).then(|| seed.toolchain.clone())
  877                                    },
  878                                )
  879                            })?
  880                            .context("Expected the LSP store to be in a local mode")?;
  881
  882                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  883                        for item in &params.items {
  884                            let scope_uri = item.scope_uri.clone();
  885                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  886                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  887                            else {
  888                                // We've already queried workspace configuration of this URI.
  889                                continue;
  890                            };
  891                            let workspace_config = Self::workspace_configuration_for_adapter(
  892                                adapter.clone(),
  893                                &delegate,
  894                                toolchain_for_id.clone(),
  895                                scope_uri,
  896                                &mut cx,
  897                            )
  898                            .await?;
  899                            new_scope_uri.insert(workspace_config);
  900                        }
  901
  902                        Ok(params
  903                            .items
  904                            .into_iter()
  905                            .filter_map(|item| {
  906                                let workspace_config =
  907                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  908                                if let Some(section) = &item.section {
  909                                    Some(
  910                                        workspace_config
  911                                            .get(section)
  912                                            .cloned()
  913                                            .unwrap_or(serde_json::Value::Null),
  914                                    )
  915                                } else {
  916                                    Some(workspace_config.clone())
  917                                }
  918                            })
  919                            .collect())
  920                    }
  921                }
  922            })
  923            .detach();
  924
  925        language_server
  926            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  927                let this = lsp_store.clone();
  928                move |_, cx| {
  929                    let this = this.clone();
  930                    let cx = cx.clone();
  931                    async move {
  932                        let Some(server) =
  933                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  934                        else {
  935                            return Ok(None);
  936                        };
  937                        let root = server.workspace_folders();
  938                        Ok(Some(
  939                            root.into_iter()
  940                                .map(|uri| WorkspaceFolder {
  941                                    uri,
  942                                    name: Default::default(),
  943                                })
  944                                .collect(),
  945                        ))
  946                    }
  947                }
  948            })
  949            .detach();
  950        // Even though we don't have handling for these requests, respond to them to
  951        // avoid stalling any language server like `gopls` which waits for a response
  952        // to these requests when initializing.
  953        language_server
  954            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  955                let this = lsp_store.clone();
  956                move |params, cx| {
  957                    let this = this.clone();
  958                    let mut cx = cx.clone();
  959                    async move {
  960                        this.update(&mut cx, |this, _| {
  961                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  962                            {
  963                                status
  964                                    .progress_tokens
  965                                    .insert(ProgressToken::from_lsp(params.token));
  966                            }
  967                        })?;
  968
  969                        Ok(())
  970                    }
  971                }
  972            })
  973            .detach();
  974
  975        language_server
  976            .on_request::<lsp::request::RegisterCapability, _, _>({
  977                let lsp_store = lsp_store.clone();
  978                move |params, cx| {
  979                    let lsp_store = lsp_store.clone();
  980                    let mut cx = cx.clone();
  981                    async move {
  982                        lsp_store
  983                            .update(&mut cx, |lsp_store, cx| {
  984                                if lsp_store.as_local().is_some() {
  985                                    match lsp_store
  986                                        .register_server_capabilities(server_id, params, cx)
  987                                    {
  988                                        Ok(()) => {}
  989                                        Err(e) => {
  990                                            log::error!(
  991                                                "Failed to register server capabilities: {e:#}"
  992                                            );
  993                                        }
  994                                    };
  995                                }
  996                            })
  997                            .ok();
  998                        Ok(())
  999                    }
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        language_server
 1005            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1006                let lsp_store = lsp_store.clone();
 1007                move |params, cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let mut cx = cx.clone();
 1010                    async move {
 1011                        lsp_store
 1012                            .update(&mut cx, |lsp_store, cx| {
 1013                                if lsp_store.as_local().is_some() {
 1014                                    match lsp_store
 1015                                        .unregister_server_capabilities(server_id, params, cx)
 1016                                    {
 1017                                        Ok(()) => {}
 1018                                        Err(e) => {
 1019                                            log::error!(
 1020                                                "Failed to unregister server capabilities: {e:#}"
 1021                                            );
 1022                                        }
 1023                                    }
 1024                                }
 1025                            })
 1026                            .ok();
 1027                        Ok(())
 1028                    }
 1029                }
 1030            })
 1031            .detach();
 1032
 1033        language_server
 1034            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1035                let this = lsp_store.clone();
 1036                move |params, cx| {
 1037                    let mut cx = cx.clone();
 1038                    let this = this.clone();
 1039                    async move {
 1040                        LocalLspStore::on_lsp_workspace_edit(
 1041                            this.clone(),
 1042                            params,
 1043                            server_id,
 1044                            &mut cx,
 1045                        )
 1046                        .await
 1047                    }
 1048                }
 1049            })
 1050            .detach();
 1051
 1052        language_server
 1053            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1054                let lsp_store = lsp_store.clone();
 1055                let request_id = Arc::new(AtomicUsize::new(0));
 1056                move |(), cx| {
 1057                    let lsp_store = lsp_store.clone();
 1058                    let request_id = request_id.clone();
 1059                    let mut cx = cx.clone();
 1060                    async move {
 1061                        lsp_store
 1062                            .update(&mut cx, |lsp_store, cx| {
 1063                                let request_id =
 1064                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1065                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1066                                    server_id,
 1067                                    request_id,
 1068                                });
 1069                                lsp_store
 1070                                    .downstream_client
 1071                                    .as_ref()
 1072                                    .map(|(client, project_id)| {
 1073                                        client.send(proto::RefreshInlayHints {
 1074                                            project_id: *project_id,
 1075                                            server_id: server_id.to_proto(),
 1076                                            request_id: request_id.map(|id| id as u64),
 1077                                        })
 1078                                    })
 1079                            })?
 1080                            .transpose()?;
 1081                        Ok(())
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        language_server
 1088            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1089                let this = lsp_store.clone();
 1090                move |(), cx| {
 1091                    let this = this.clone();
 1092                    let mut cx = cx.clone();
 1093                    async move {
 1094                        this.update(&mut cx, |this, cx| {
 1095                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1096                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1097                                client.send(proto::RefreshCodeLens {
 1098                                    project_id: *project_id,
 1099                                })
 1100                            })
 1101                        })?
 1102                        .transpose()?;
 1103                        Ok(())
 1104                    }
 1105                }
 1106            })
 1107            .detach();
 1108
 1109        language_server
 1110            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1111                let lsp_store = lsp_store.clone();
 1112                let request_id = Arc::new(AtomicUsize::new(0));
 1113                move |(), cx| {
 1114                    let lsp_store = lsp_store.clone();
 1115                    let request_id = request_id.clone();
 1116                    let mut cx = cx.clone();
 1117                    async move {
 1118                        lsp_store
 1119                            .update(&mut cx, |lsp_store, cx| {
 1120                                let request_id =
 1121                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1122                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1123                                    server_id,
 1124                                    request_id,
 1125                                });
 1126                                lsp_store
 1127                                    .downstream_client
 1128                                    .as_ref()
 1129                                    .map(|(client, project_id)| {
 1130                                        client.send(proto::RefreshSemanticTokens {
 1131                                            project_id: *project_id,
 1132                                            server_id: server_id.to_proto(),
 1133                                            request_id: request_id.map(|id| id as u64),
 1134                                        })
 1135                                    })
 1136                            })?
 1137                            .transpose()?;
 1138                        Ok(())
 1139                    }
 1140                }
 1141            })
 1142            .detach();
 1143
 1144        language_server
 1145            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1146                let this = lsp_store.clone();
 1147                move |(), cx| {
 1148                    let this = this.clone();
 1149                    let mut cx = cx.clone();
 1150                    async move {
 1151                        this.update(&mut cx, |lsp_store, cx| {
 1152                            lsp_store.pull_workspace_diagnostics(server_id);
 1153                            lsp_store
 1154                                .downstream_client
 1155                                .as_ref()
 1156                                .map(|(client, project_id)| {
 1157                                    client.send(proto::PullWorkspaceDiagnostics {
 1158                                        project_id: *project_id,
 1159                                        server_id: server_id.to_proto(),
 1160                                    })
 1161                                })
 1162                                .transpose()?;
 1163                            anyhow::Ok(
 1164                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1165                            )
 1166                        })??
 1167                        .await;
 1168                        Ok(())
 1169                    }
 1170                }
 1171            })
 1172            .detach();
 1173
 1174        language_server
 1175            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1176                let this = lsp_store.clone();
 1177                let name = name.to_string();
 1178                let adapter = adapter.clone();
 1179                move |params, cx| {
 1180                    let this = this.clone();
 1181                    let name = name.to_string();
 1182                    let adapter = adapter.clone();
 1183                    let mut cx = cx.clone();
 1184                    async move {
 1185                        let actions = params.actions.unwrap_or_default();
 1186                        let message = params.message.clone();
 1187                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1188                        let level = match params.typ {
 1189                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1190                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1191                            _ => PromptLevel::Info,
 1192                        };
 1193                        let request = LanguageServerPromptRequest::new(
 1194                            level,
 1195                            params.message,
 1196                            actions,
 1197                            name.clone(),
 1198                            tx,
 1199                        );
 1200
 1201                        let did_update = this
 1202                            .update(&mut cx, |_, cx| {
 1203                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1204                            })
 1205                            .is_ok();
 1206                        if did_update {
 1207                            let response = rx.recv().await.ok();
 1208                            if let Some(ref selected_action) = response {
 1209                                let context = language::PromptResponseContext {
 1210                                    message,
 1211                                    selected_action: selected_action.clone(),
 1212                                };
 1213                                adapter.process_prompt_response(&context, &mut cx)
 1214                            }
 1215
 1216                            Ok(response)
 1217                        } else {
 1218                            Ok(None)
 1219                        }
 1220                    }
 1221                }
 1222            })
 1223            .detach();
 1224        language_server
 1225            .on_notification::<lsp::notification::ShowMessage, _>({
 1226                let this = lsp_store.clone();
 1227                let name = name.to_string();
 1228                move |params, cx| {
 1229                    let this = this.clone();
 1230                    let name = name.to_string();
 1231                    let mut cx = cx.clone();
 1232
 1233                    let (tx, _) = smol::channel::bounded(1);
 1234                    let level = match params.typ {
 1235                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1236                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1237                        _ => PromptLevel::Info,
 1238                    };
 1239                    let request =
 1240                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1241
 1242                    let _ = this.update(&mut cx, |_, cx| {
 1243                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1244                    });
 1245                }
 1246            })
 1247            .detach();
 1248
 1249        let disk_based_diagnostics_progress_token =
 1250            adapter.disk_based_diagnostics_progress_token.clone();
 1251
 1252        language_server
 1253            .on_notification::<lsp::notification::Progress, _>({
 1254                let this = lsp_store.clone();
 1255                move |params, cx| {
 1256                    if let Some(this) = this.upgrade() {
 1257                        this.update(cx, |this, cx| {
 1258                            this.on_lsp_progress(
 1259                                params,
 1260                                server_id,
 1261                                disk_based_diagnostics_progress_token.clone(),
 1262                                cx,
 1263                            );
 1264                        });
 1265                    }
 1266                }
 1267            })
 1268            .detach();
 1269
 1270        language_server
 1271            .on_notification::<lsp::notification::LogMessage, _>({
 1272                let this = lsp_store.clone();
 1273                move |params, cx| {
 1274                    if let Some(this) = this.upgrade() {
 1275                        this.update(cx, |_, cx| {
 1276                            cx.emit(LspStoreEvent::LanguageServerLog(
 1277                                server_id,
 1278                                LanguageServerLogType::Log(params.typ),
 1279                                params.message,
 1280                            ));
 1281                        });
 1282                    }
 1283                }
 1284            })
 1285            .detach();
 1286
 1287        language_server
 1288            .on_notification::<lsp::notification::LogTrace, _>({
 1289                let this = lsp_store.clone();
 1290                move |params, cx| {
 1291                    let mut cx = cx.clone();
 1292                    if let Some(this) = this.upgrade() {
 1293                        this.update(&mut cx, |_, cx| {
 1294                            cx.emit(LspStoreEvent::LanguageServerLog(
 1295                                server_id,
 1296                                LanguageServerLogType::Trace {
 1297                                    verbose_info: params.verbose,
 1298                                },
 1299                                params.message,
 1300                            ));
 1301                        });
 1302                    }
 1303                }
 1304            })
 1305            .detach();
 1306
 1307        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1308        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1309        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1310        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1311    }
 1312
 1313    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1314        let shutdown_futures = self
 1315            .language_servers
 1316            .drain()
 1317            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1318            .collect::<Vec<_>>();
 1319
 1320        async move {
 1321            join_all(shutdown_futures).await;
 1322        }
 1323    }
 1324
 1325    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1326        match server_state {
 1327            LanguageServerState::Running { server, .. } => {
 1328                if let Some(shutdown) = server.shutdown() {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332            LanguageServerState::Starting { startup, .. } => {
 1333                if let Some(server) = startup.await
 1334                    && let Some(shutdown) = server.shutdown()
 1335                {
 1336                    shutdown.await;
 1337                }
 1338            }
 1339        }
 1340        Ok(())
 1341    }
 1342
 1343    fn language_servers_for_worktree(
 1344        &self,
 1345        worktree_id: WorktreeId,
 1346    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1347        self.language_server_ids
 1348            .iter()
 1349            .filter_map(move |(seed, state)| {
 1350                if seed.worktree_id != worktree_id {
 1351                    return None;
 1352                }
 1353
 1354                if let Some(LanguageServerState::Running { server, .. }) =
 1355                    self.language_servers.get(&state.id)
 1356                {
 1357                    Some(server)
 1358                } else {
 1359                    None
 1360                }
 1361            })
 1362    }
 1363
 1364    fn language_server_ids_for_project_path(
 1365        &self,
 1366        project_path: ProjectPath,
 1367        language: &Language,
 1368        cx: &mut App,
 1369    ) -> Vec<LanguageServerId> {
 1370        let Some(worktree) = self
 1371            .worktree_store
 1372            .read(cx)
 1373            .worktree_for_id(project_path.worktree_id, cx)
 1374        else {
 1375            return Vec::new();
 1376        };
 1377        let delegate: Arc<dyn ManifestDelegate> =
 1378            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1379
 1380        self.lsp_tree
 1381            .get(
 1382                project_path,
 1383                language.name(),
 1384                language.manifest(),
 1385                &delegate,
 1386                cx,
 1387            )
 1388            .collect::<Vec<_>>()
 1389    }
 1390
 1391    fn language_server_ids_for_buffer(
 1392        &self,
 1393        buffer: &Buffer,
 1394        cx: &mut App,
 1395    ) -> Vec<LanguageServerId> {
 1396        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1397            let worktree_id = file.worktree_id(cx);
 1398
 1399            let path: Arc<RelPath> = file
 1400                .path()
 1401                .parent()
 1402                .map(Arc::from)
 1403                .unwrap_or_else(|| file.path().clone());
 1404            let worktree_path = ProjectPath { worktree_id, path };
 1405            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1406        } else {
 1407            Vec::new()
 1408        }
 1409    }
 1410
 1411    fn language_servers_for_buffer<'a>(
 1412        &'a self,
 1413        buffer: &'a Buffer,
 1414        cx: &'a mut App,
 1415    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1416        self.language_server_ids_for_buffer(buffer, cx)
 1417            .into_iter()
 1418            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1419                LanguageServerState::Running {
 1420                    adapter, server, ..
 1421                } => Some((adapter, server)),
 1422                _ => None,
 1423            })
 1424    }
 1425
 1426    async fn execute_code_action_kind_locally(
 1427        lsp_store: WeakEntity<LspStore>,
 1428        mut buffers: Vec<Entity<Buffer>>,
 1429        kind: CodeActionKind,
 1430        push_to_history: bool,
 1431        cx: &mut AsyncApp,
 1432    ) -> anyhow::Result<ProjectTransaction> {
 1433        // Do not allow multiple concurrent code actions requests for the
 1434        // same buffer.
 1435        lsp_store.update(cx, |this, cx| {
 1436            let this = this.as_local_mut().unwrap();
 1437            buffers.retain(|buffer| {
 1438                this.buffers_being_formatted
 1439                    .insert(buffer.read(cx).remote_id())
 1440            });
 1441        })?;
 1442        let _cleanup = defer({
 1443            let this = lsp_store.clone();
 1444            let mut cx = cx.clone();
 1445            let buffers = &buffers;
 1446            move || {
 1447                this.update(&mut cx, |this, cx| {
 1448                    let this = this.as_local_mut().unwrap();
 1449                    for buffer in buffers {
 1450                        this.buffers_being_formatted
 1451                            .remove(&buffer.read(cx).remote_id());
 1452                    }
 1453                })
 1454                .ok();
 1455            }
 1456        });
 1457        let mut project_transaction = ProjectTransaction::default();
 1458
 1459        for buffer in &buffers {
 1460            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1461                buffer.update(cx, |buffer, cx| {
 1462                    lsp_store
 1463                        .as_local()
 1464                        .unwrap()
 1465                        .language_servers_for_buffer(buffer, cx)
 1466                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1467                        .collect::<Vec<_>>()
 1468                })
 1469            })?;
 1470            for (_, language_server) in adapters_and_servers.iter() {
 1471                let actions = Self::get_server_code_actions_from_action_kinds(
 1472                    &lsp_store,
 1473                    language_server.server_id(),
 1474                    vec![kind.clone()],
 1475                    buffer,
 1476                    cx,
 1477                )
 1478                .await?;
 1479                Self::execute_code_actions_on_server(
 1480                    &lsp_store,
 1481                    language_server,
 1482                    actions,
 1483                    push_to_history,
 1484                    &mut project_transaction,
 1485                    cx,
 1486                )
 1487                .await?;
 1488            }
 1489        }
 1490        Ok(project_transaction)
 1491    }
 1492
 1493    async fn format_locally(
 1494        lsp_store: WeakEntity<LspStore>,
 1495        mut buffers: Vec<FormattableBuffer>,
 1496        push_to_history: bool,
 1497        trigger: FormatTrigger,
 1498        logger: zlog::Logger,
 1499        cx: &mut AsyncApp,
 1500    ) -> anyhow::Result<ProjectTransaction> {
 1501        // Do not allow multiple concurrent formatting requests for the
 1502        // same buffer.
 1503        lsp_store.update(cx, |this, cx| {
 1504            let this = this.as_local_mut().unwrap();
 1505            buffers.retain(|buffer| {
 1506                this.buffers_being_formatted
 1507                    .insert(buffer.handle.read(cx).remote_id())
 1508            });
 1509        })?;
 1510
 1511        let _cleanup = defer({
 1512            let this = lsp_store.clone();
 1513            let mut cx = cx.clone();
 1514            let buffers = &buffers;
 1515            move || {
 1516                this.update(&mut cx, |this, cx| {
 1517                    let this = this.as_local_mut().unwrap();
 1518                    for buffer in buffers {
 1519                        this.buffers_being_formatted
 1520                            .remove(&buffer.handle.read(cx).remote_id());
 1521                    }
 1522                })
 1523                .ok();
 1524            }
 1525        });
 1526
 1527        let mut project_transaction = ProjectTransaction::default();
 1528
 1529        for buffer in &buffers {
 1530            zlog::debug!(
 1531                logger =>
 1532                "formatting buffer '{:?}'",
 1533                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1534            );
 1535            // Create an empty transaction to hold all of the formatting edits.
 1536            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1537                // ensure no transactions created while formatting are
 1538                // grouped with the previous transaction in the history
 1539                // based on the transaction group interval
 1540                buffer.finalize_last_transaction();
 1541                buffer
 1542                    .start_transaction()
 1543                    .context("transaction already open")?;
 1544                buffer.end_transaction(cx);
 1545                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1546                buffer.finalize_last_transaction();
 1547                anyhow::Ok(transaction_id)
 1548            })?;
 1549
 1550            let result = Self::format_buffer_locally(
 1551                lsp_store.clone(),
 1552                buffer,
 1553                formatting_transaction_id,
 1554                trigger,
 1555                logger,
 1556                cx,
 1557            )
 1558            .await;
 1559
 1560            buffer.handle.update(cx, |buffer, cx| {
 1561                let Some(formatting_transaction) =
 1562                    buffer.get_transaction(formatting_transaction_id).cloned()
 1563                else {
 1564                    zlog::warn!(logger => "no formatting transaction");
 1565                    return;
 1566                };
 1567                if formatting_transaction.edit_ids.is_empty() {
 1568                    zlog::debug!(logger => "no changes made while formatting");
 1569                    buffer.forget_transaction(formatting_transaction_id);
 1570                    return;
 1571                }
 1572                if !push_to_history {
 1573                    zlog::trace!(logger => "forgetting format transaction");
 1574                    buffer.forget_transaction(formatting_transaction.id);
 1575                }
 1576                project_transaction
 1577                    .0
 1578                    .insert(cx.entity(), formatting_transaction);
 1579            });
 1580
 1581            result?;
 1582        }
 1583
 1584        Ok(project_transaction)
 1585    }
 1586
 1587    async fn format_buffer_locally(
 1588        lsp_store: WeakEntity<LspStore>,
 1589        buffer: &FormattableBuffer,
 1590        formatting_transaction_id: clock::Lamport,
 1591        trigger: FormatTrigger,
 1592        logger: zlog::Logger,
 1593        cx: &mut AsyncApp,
 1594    ) -> Result<()> {
 1595        let (adapters_and_servers, settings, request_timeout) =
 1596            lsp_store.update(cx, |lsp_store, cx| {
 1597                buffer.handle.update(cx, |buffer, cx| {
 1598                    let adapters_and_servers = lsp_store
 1599                        .as_local()
 1600                        .unwrap()
 1601                        .language_servers_for_buffer(buffer, cx)
 1602                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1603                        .collect::<Vec<_>>();
 1604                    let settings =
 1605                        language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1606                            .into_owned();
 1607                    let request_timeout = ProjectSettings::get_global(cx)
 1608                        .global_lsp_settings
 1609                        .get_request_timeout();
 1610                    (adapters_and_servers, settings, request_timeout)
 1611                })
 1612            })?;
 1613
 1614        /// Apply edits to the buffer that will become part of the formatting transaction.
 1615        /// Fails if the buffer has been edited since the start of that transaction.
 1616        fn extend_formatting_transaction(
 1617            buffer: &FormattableBuffer,
 1618            formatting_transaction_id: text::TransactionId,
 1619            cx: &mut AsyncApp,
 1620            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1621        ) -> anyhow::Result<()> {
 1622            buffer.handle.update(cx, |buffer, cx| {
 1623                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1624                if last_transaction_id != Some(formatting_transaction_id) {
 1625                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1626                }
 1627                buffer.start_transaction();
 1628                operation(buffer, cx);
 1629                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1630                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1631                }
 1632                Ok(())
 1633            })
 1634        }
 1635
 1636        // handle whitespace formatting
 1637        if settings.remove_trailing_whitespace_on_save {
 1638            zlog::trace!(logger => "removing trailing whitespace");
 1639            let diff = buffer
 1640                .handle
 1641                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1642                .await;
 1643            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1644                buffer.apply_diff(diff, cx);
 1645            })?;
 1646        }
 1647
 1648        if settings.ensure_final_newline_on_save {
 1649            zlog::trace!(logger => "ensuring final newline");
 1650            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1651                buffer.ensure_final_newline(cx);
 1652            })?;
 1653        }
 1654
 1655        // Formatter for `code_actions_on_format` that runs before
 1656        // the rest of the formatters
 1657        let mut code_actions_on_format_formatters = None;
 1658        let should_run_code_actions_on_format = !matches!(
 1659            (trigger, &settings.format_on_save),
 1660            (FormatTrigger::Save, &FormatOnSave::Off)
 1661        );
 1662        if should_run_code_actions_on_format {
 1663            let have_code_actions_to_run_on_format = settings
 1664                .code_actions_on_format
 1665                .values()
 1666                .any(|enabled| *enabled);
 1667            if have_code_actions_to_run_on_format {
 1668                zlog::trace!(logger => "going to run code actions on format");
 1669                code_actions_on_format_formatters = Some(
 1670                    settings
 1671                        .code_actions_on_format
 1672                        .iter()
 1673                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1674                        .cloned()
 1675                        .map(Formatter::CodeAction)
 1676                        .collect::<Vec<_>>(),
 1677                );
 1678            }
 1679        }
 1680
 1681        let formatters = match (trigger, &settings.format_on_save) {
 1682            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1683            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1684                settings.formatter.as_ref()
 1685            }
 1686        };
 1687
 1688        let formatters = code_actions_on_format_formatters
 1689            .iter()
 1690            .flatten()
 1691            .chain(formatters);
 1692
 1693        for formatter in formatters {
 1694            let formatter = if formatter == &Formatter::Auto {
 1695                if settings.prettier.allowed {
 1696                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1697                    &Formatter::Prettier
 1698                } else {
 1699                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1700                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1701                }
 1702            } else {
 1703                formatter
 1704            };
 1705            match formatter {
 1706                Formatter::None => {
 1707                    zlog::trace!(logger => "skipping formatter 'none'");
 1708                    continue;
 1709                }
 1710                Formatter::Auto => unreachable!("Auto resolved above"),
 1711                Formatter::Prettier => {
 1712                    let logger = zlog::scoped!(logger => "prettier");
 1713                    zlog::trace!(logger => "formatting");
 1714                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1715
 1716                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1717                        lsp_store.prettier_store().unwrap().downgrade()
 1718                    })?;
 1719                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1720                        .await
 1721                        .transpose()?;
 1722                    let Some(diff) = diff else {
 1723                        zlog::trace!(logger => "No changes");
 1724                        continue;
 1725                    };
 1726
 1727                    extend_formatting_transaction(
 1728                        buffer,
 1729                        formatting_transaction_id,
 1730                        cx,
 1731                        |buffer, cx| {
 1732                            buffer.apply_diff(diff, cx);
 1733                        },
 1734                    )?;
 1735                }
 1736                Formatter::External { command, arguments } => {
 1737                    let logger = zlog::scoped!(logger => "command");
 1738                    zlog::trace!(logger => "formatting");
 1739                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1740
 1741                    let diff = Self::format_via_external_command(
 1742                        buffer,
 1743                        &command,
 1744                        arguments.as_deref(),
 1745                        cx,
 1746                    )
 1747                    .await
 1748                    .with_context(|| {
 1749                        format!("Failed to format buffer via external command: {}", command)
 1750                    })?;
 1751                    let Some(diff) = diff else {
 1752                        zlog::trace!(logger => "No changes");
 1753                        continue;
 1754                    };
 1755
 1756                    extend_formatting_transaction(
 1757                        buffer,
 1758                        formatting_transaction_id,
 1759                        cx,
 1760                        |buffer, cx| {
 1761                            buffer.apply_diff(diff, cx);
 1762                        },
 1763                    )?;
 1764                }
 1765                Formatter::LanguageServer(specifier) => {
 1766                    let logger = zlog::scoped!(logger => "language-server");
 1767                    zlog::trace!(logger => "formatting");
 1768                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1769
 1770                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1771                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1772                        continue;
 1773                    };
 1774
 1775                    let language_server = match specifier {
 1776                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1777                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1778                                if adapter.name.0.as_ref() == name {
 1779                                    Some(server.clone())
 1780                                } else {
 1781                                    None
 1782                                }
 1783                            })
 1784                        }
 1785                        settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1786                            .iter()
 1787                            .find(|(_, server)| Self::server_supports_formatting(server))
 1788                            .map(|(_, server)| server.clone()),
 1789                    };
 1790
 1791                    let Some(language_server) = language_server else {
 1792                        log::debug!(
 1793                            "No language server found to format buffer '{:?}'. Skipping",
 1794                            buffer_path_abs.as_path().to_string_lossy()
 1795                        );
 1796                        continue;
 1797                    };
 1798
 1799                    zlog::trace!(
 1800                        logger =>
 1801                        "Formatting buffer '{:?}' using language server '{:?}'",
 1802                        buffer_path_abs.as_path().to_string_lossy(),
 1803                        language_server.name()
 1804                    );
 1805
 1806                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1807                        zlog::trace!(logger => "formatting ranges");
 1808                        Self::format_ranges_via_lsp(
 1809                            &lsp_store,
 1810                            &buffer.handle,
 1811                            ranges,
 1812                            buffer_path_abs,
 1813                            &language_server,
 1814                            &settings,
 1815                            cx,
 1816                        )
 1817                        .await
 1818                        .context("Failed to format ranges via language server")?
 1819                    } else {
 1820                        zlog::trace!(logger => "formatting full");
 1821                        Self::format_via_lsp(
 1822                            &lsp_store,
 1823                            &buffer.handle,
 1824                            buffer_path_abs,
 1825                            &language_server,
 1826                            &settings,
 1827                            cx,
 1828                        )
 1829                        .await
 1830                        .context("failed to format via language server")?
 1831                    };
 1832
 1833                    if edits.is_empty() {
 1834                        zlog::trace!(logger => "No changes");
 1835                        continue;
 1836                    }
 1837                    extend_formatting_transaction(
 1838                        buffer,
 1839                        formatting_transaction_id,
 1840                        cx,
 1841                        |buffer, cx| {
 1842                            buffer.edit(edits, None, cx);
 1843                        },
 1844                    )?;
 1845                }
 1846                Formatter::CodeAction(code_action_name) => {
 1847                    let logger = zlog::scoped!(logger => "code-actions");
 1848                    zlog::trace!(logger => "formatting");
 1849                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1850
 1851                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1852                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1853                        continue;
 1854                    };
 1855
 1856                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1857                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1858
 1859                    let mut actions_and_servers = Vec::new();
 1860
 1861                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1862                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1863                            &lsp_store,
 1864                            language_server.server_id(),
 1865                            vec![code_action_kind.clone()],
 1866                            &buffer.handle,
 1867                            cx,
 1868                        )
 1869                        .await
 1870                        .with_context(|| {
 1871                            format!(
 1872                                "Failed to resolve code action {:?} with language server {}",
 1873                                code_action_kind,
 1874                                language_server.name()
 1875                            )
 1876                        });
 1877                        let Ok(actions) = actions_result else {
 1878                            // note: it may be better to set result to the error and break formatters here
 1879                            // but for now we try to execute the actions that we can resolve and skip the rest
 1880                            zlog::error!(
 1881                                logger =>
 1882                                "Failed to resolve code action {:?} with language server {}",
 1883                                code_action_kind,
 1884                                language_server.name()
 1885                            );
 1886                            continue;
 1887                        };
 1888                        for action in actions {
 1889                            actions_and_servers.push((action, index));
 1890                        }
 1891                    }
 1892
 1893                    if actions_and_servers.is_empty() {
 1894                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1895                        continue;
 1896                    }
 1897
 1898                    'actions: for (mut action, server_index) in actions_and_servers {
 1899                        let server = &adapters_and_servers[server_index].1;
 1900
 1901                        let describe_code_action = |action: &CodeAction| {
 1902                            format!(
 1903                                "code action '{}' with title \"{}\" on server {}",
 1904                                action
 1905                                    .lsp_action
 1906                                    .action_kind()
 1907                                    .unwrap_or("unknown".into())
 1908                                    .as_str(),
 1909                                action.lsp_action.title(),
 1910                                server.name(),
 1911                            )
 1912                        };
 1913
 1914                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1915
 1916                        if let Err(err) =
 1917                            Self::try_resolve_code_action(server, &mut action, request_timeout)
 1918                                .await
 1919                        {
 1920                            zlog::error!(
 1921                                logger =>
 1922                                "Failed to resolve {}. Error: {}",
 1923                                describe_code_action(&action),
 1924                                err
 1925                            );
 1926                            continue;
 1927                        }
 1928
 1929                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1930                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1931                            // but filters out and logs warnings for code actions that require unreasonably
 1932                            // difficult handling on our part, such as:
 1933                            // - applying edits that call commands
 1934                            //   which can result in arbitrary workspace edits being sent from the server that
 1935                            //   have no way of being tied back to the command that initiated them (i.e. we
 1936                            //   can't know which edits are part of the format request, or if the server is done sending
 1937                            //   actions in response to the command)
 1938                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1939                            //   as we then would need to handle such changes correctly in the local history as well
 1940                            //   as the remote history through the ProjectTransaction
 1941                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1942                            // Supporting these actions is not impossible, but not supported as of yet.
 1943                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1944                                zlog::trace!(
 1945                                    logger =>
 1946                                    "No changes for code action. Skipping {}",
 1947                                    describe_code_action(&action),
 1948                                );
 1949                                continue;
 1950                            }
 1951
 1952                            let mut operations = Vec::new();
 1953                            if let Some(document_changes) = edit.document_changes {
 1954                                match document_changes {
 1955                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1956                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1957                                    ),
 1958                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1959                                }
 1960                            } else if let Some(changes) = edit.changes {
 1961                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1962                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1963                                        text_document:
 1964                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1965                                                uri,
 1966                                                version: None,
 1967                                            },
 1968                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1969                                    })
 1970                                }));
 1971                            }
 1972
 1973                            let mut edits = Vec::with_capacity(operations.len());
 1974
 1975                            if operations.is_empty() {
 1976                                zlog::trace!(
 1977                                    logger =>
 1978                                    "No changes for code action. Skipping {}",
 1979                                    describe_code_action(&action),
 1980                                );
 1981                                continue;
 1982                            }
 1983                            for operation in operations {
 1984                                let op = match operation {
 1985                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1986                                    lsp::DocumentChangeOperation::Op(_) => {
 1987                                        zlog::warn!(
 1988                                            logger =>
 1989                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1990                                            describe_code_action(&action),
 1991                                        );
 1992                                        continue 'actions;
 1993                                    }
 1994                                };
 1995                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1996                                    zlog::warn!(
 1997                                        logger =>
 1998                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1999                                        &op.text_document.uri,
 2000                                        describe_code_action(&action),
 2001                                    );
 2002                                    continue 'actions;
 2003                                };
 2004                                if &file_path != buffer_path_abs {
 2005                                    zlog::warn!(
 2006                                        logger =>
 2007                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2008                                        file_path,
 2009                                        buffer_path_abs,
 2010                                        describe_code_action(&action),
 2011                                    );
 2012                                    continue 'actions;
 2013                                }
 2014
 2015                                let mut lsp_edits = Vec::new();
 2016                                for edit in op.edits {
 2017                                    match edit {
 2018                                        Edit::Plain(edit) => {
 2019                                            if !lsp_edits.contains(&edit) {
 2020                                                lsp_edits.push(edit);
 2021                                            }
 2022                                        }
 2023                                        Edit::Annotated(edit) => {
 2024                                            if !lsp_edits.contains(&edit.text_edit) {
 2025                                                lsp_edits.push(edit.text_edit);
 2026                                            }
 2027                                        }
 2028                                        Edit::Snippet(_) => {
 2029                                            zlog::warn!(
 2030                                                logger =>
 2031                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2032                                                describe_code_action(&action),
 2033                                            );
 2034                                            continue 'actions;
 2035                                        }
 2036                                    }
 2037                                }
 2038                                let edits_result = lsp_store
 2039                                    .update(cx, |lsp_store, cx| {
 2040                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2041                                            &buffer.handle,
 2042                                            lsp_edits,
 2043                                            server.server_id(),
 2044                                            op.text_document.version,
 2045                                            cx,
 2046                                        )
 2047                                    })?
 2048                                    .await;
 2049                                let Ok(resolved_edits) = edits_result else {
 2050                                    zlog::warn!(
 2051                                        logger =>
 2052                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2053                                        buffer_path_abs.as_path(),
 2054                                        describe_code_action(&action),
 2055                                    );
 2056                                    continue 'actions;
 2057                                };
 2058                                edits.extend(resolved_edits);
 2059                            }
 2060
 2061                            if edits.is_empty() {
 2062                                zlog::warn!(logger => "No edits resolved from LSP");
 2063                                continue;
 2064                            }
 2065
 2066                            extend_formatting_transaction(
 2067                                buffer,
 2068                                formatting_transaction_id,
 2069                                cx,
 2070                                |buffer, cx| {
 2071                                    zlog::info!(
 2072                                        "Applying edits {edits:?}. Content: {:?}",
 2073                                        buffer.text()
 2074                                    );
 2075                                    buffer.edit(edits, None, cx);
 2076                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2077                                },
 2078                            )?;
 2079                        }
 2080
 2081                        // bail early if command is invalid
 2082                        let Some(command) = action.lsp_action.command() else {
 2083                            continue;
 2084                        };
 2085
 2086                        zlog::warn!(
 2087                            logger =>
 2088                            "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2089                            &command.command,
 2090                        );
 2091
 2092                        let server_capabilities = server.capabilities();
 2093                        let available_commands = server_capabilities
 2094                            .execute_command_provider
 2095                            .as_ref()
 2096                            .map(|options| options.commands.as_slice())
 2097                            .unwrap_or_default();
 2098                        if !available_commands.contains(&command.command) {
 2099                            zlog::warn!(
 2100                                logger =>
 2101                                "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2102                                command.command,
 2103                                server.name(),
 2104                            );
 2105                            continue;
 2106                        }
 2107
 2108                        // noop so we just ensure buffer hasn't been edited since resolving code actions
 2109                        extend_formatting_transaction(
 2110                            buffer,
 2111                            formatting_transaction_id,
 2112                            cx,
 2113                            |_, _| {},
 2114                        )?;
 2115                        zlog::info!(logger => "Executing command {}", &command.command);
 2116
 2117                        lsp_store.update(cx, |this, _| {
 2118                            this.as_local_mut()
 2119                                .unwrap()
 2120                                .last_workspace_edits_by_language_server
 2121                                .remove(&server.server_id());
 2122                        })?;
 2123
 2124                        let execute_command_result = server
 2125                            .request::<lsp::request::ExecuteCommand>(
 2126                                lsp::ExecuteCommandParams {
 2127                                    command: command.command.clone(),
 2128                                    arguments: command.arguments.clone().unwrap_or_default(),
 2129                                    ..Default::default()
 2130                                },
 2131                                request_timeout,
 2132                            )
 2133                            .await
 2134                            .into_response();
 2135
 2136                        if execute_command_result.is_err() {
 2137                            zlog::error!(
 2138                                logger =>
 2139                                "Failed to execute command '{}' as part of {}",
 2140                                &command.command,
 2141                                describe_code_action(&action),
 2142                            );
 2143                            continue 'actions;
 2144                        }
 2145
 2146                        let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2147                            this.as_local_mut()
 2148                                .unwrap()
 2149                                .last_workspace_edits_by_language_server
 2150                                .remove(&server.server_id())
 2151                                .unwrap_or_default()
 2152                        })?;
 2153
 2154                        if let Some(transaction) =
 2155                            project_transaction_command.0.remove(&buffer.handle)
 2156                        {
 2157                            zlog::trace!(
 2158                                logger =>
 2159                                "Successfully captured {} edits that resulted from command {}",
 2160                                transaction.edit_ids.len(),
 2161                                &command.command,
 2162                            );
 2163                            let transaction_id_project_transaction = transaction.id;
 2164                            buffer.handle.update(cx, |buffer, _| {
 2165                                // it may have been removed from history if push_to_history was
 2166                                // false in deserialize_workspace_edit. If so push it so we
 2167                                // can merge it with the format transaction
 2168                                // and pop the combined transaction off the history stack
 2169                                // later if push_to_history is false
 2170                                if buffer.get_transaction(transaction.id).is_none() {
 2171                                    buffer.push_transaction(transaction, Instant::now());
 2172                                }
 2173                                buffer.merge_transactions(
 2174                                    transaction_id_project_transaction,
 2175                                    formatting_transaction_id,
 2176                                );
 2177                            });
 2178                        }
 2179
 2180                        if project_transaction_command.0.is_empty() {
 2181                            continue;
 2182                        }
 2183
 2184                        let mut extra_buffers = String::new();
 2185                        for buffer in project_transaction_command.0.keys() {
 2186                            buffer.read_with(cx, |b, cx| {
 2187                                let Some(path) = b.project_path(cx) else {
 2188                                    return;
 2189                                };
 2190
 2191                                if !extra_buffers.is_empty() {
 2192                                    extra_buffers.push_str(", ");
 2193                                }
 2194                                extra_buffers.push_str(path.path.as_unix_str());
 2195                            });
 2196                        }
 2197                        zlog::warn!(
 2198                            logger =>
 2199                            "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2200                            &command.command,
 2201                            extra_buffers,
 2202                        );
 2203                        // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2204                        // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2205                        // add it so it's included, and merge it into the format transaction when its created later
 2206                    }
 2207                }
 2208            }
 2209        }
 2210
 2211        Ok(())
 2212    }
 2213
 2214    pub async fn format_ranges_via_lsp(
 2215        this: &WeakEntity<LspStore>,
 2216        buffer_handle: &Entity<Buffer>,
 2217        ranges: &[Range<Anchor>],
 2218        abs_path: &Path,
 2219        language_server: &Arc<LanguageServer>,
 2220        settings: &LanguageSettings,
 2221        cx: &mut AsyncApp,
 2222    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2223        let capabilities = &language_server.capabilities();
 2224        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2225        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2226            anyhow::bail!(
 2227                "{} language server does not support range formatting",
 2228                language_server.name()
 2229            );
 2230        }
 2231
 2232        let uri = file_path_to_lsp_url(abs_path)?;
 2233        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2234
 2235        let request_timeout = cx.update(|app| {
 2236            ProjectSettings::get_global(app)
 2237                .global_lsp_settings
 2238                .get_request_timeout()
 2239        });
 2240        let lsp_edits = {
 2241            let mut lsp_ranges = Vec::new();
 2242            this.update(cx, |_this, cx| {
 2243                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2244                // not have been sent to the language server. This seems like a fairly systemic
 2245                // issue, though, the resolution probably is not specific to formatting.
 2246                //
 2247                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2248                // LSP.
 2249                let snapshot = buffer_handle.read(cx).snapshot();
 2250                for range in ranges {
 2251                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2252                }
 2253                anyhow::Ok(())
 2254            })??;
 2255
 2256            let mut edits = None;
 2257            for range in lsp_ranges {
 2258                if let Some(mut edit) = language_server
 2259                    .request::<lsp::request::RangeFormatting>(
 2260                        lsp::DocumentRangeFormattingParams {
 2261                            text_document: text_document.clone(),
 2262                            range,
 2263                            options: lsp_command::lsp_formatting_options(settings),
 2264                            work_done_progress_params: Default::default(),
 2265                        },
 2266                        request_timeout,
 2267                    )
 2268                    .await
 2269                    .into_response()?
 2270                {
 2271                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2272                }
 2273            }
 2274            edits
 2275        };
 2276
 2277        if let Some(lsp_edits) = lsp_edits {
 2278            this.update(cx, |this, cx| {
 2279                this.as_local_mut().unwrap().edits_from_lsp(
 2280                    buffer_handle,
 2281                    lsp_edits,
 2282                    language_server.server_id(),
 2283                    None,
 2284                    cx,
 2285                )
 2286            })?
 2287            .await
 2288        } else {
 2289            Ok(Vec::with_capacity(0))
 2290        }
 2291    }
 2292
 2293    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2294        let capabilities = server.capabilities();
 2295        let formatting = capabilities.document_formatting_provider.as_ref();
 2296        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2297        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2298            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2299    }
 2300
 2301    async fn format_via_lsp(
 2302        this: &WeakEntity<LspStore>,
 2303        buffer: &Entity<Buffer>,
 2304        abs_path: &Path,
 2305        language_server: &Arc<LanguageServer>,
 2306        settings: &LanguageSettings,
 2307        cx: &mut AsyncApp,
 2308    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2309        let logger = zlog::scoped!("lsp_format");
 2310        zlog::debug!(logger => "Formatting via LSP");
 2311
 2312        let uri = file_path_to_lsp_url(abs_path)?;
 2313        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2314        let capabilities = &language_server.capabilities();
 2315
 2316        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2317        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2318
 2319        let request_timeout = cx.update(|app| {
 2320            ProjectSettings::get_global(app)
 2321                .global_lsp_settings
 2322                .get_request_timeout()
 2323        });
 2324
 2325        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2326            let _timer = zlog::time!(logger => "format-full");
 2327            language_server
 2328                .request::<lsp::request::Formatting>(
 2329                    lsp::DocumentFormattingParams {
 2330                        text_document,
 2331                        options: lsp_command::lsp_formatting_options(settings),
 2332                        work_done_progress_params: Default::default(),
 2333                    },
 2334                    request_timeout,
 2335                )
 2336                .await
 2337                .into_response()?
 2338        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2339            let _timer = zlog::time!(logger => "format-range");
 2340            let buffer_start = lsp::Position::new(0, 0);
 2341            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2342            language_server
 2343                .request::<lsp::request::RangeFormatting>(
 2344                    lsp::DocumentRangeFormattingParams {
 2345                        text_document: text_document.clone(),
 2346                        range: lsp::Range::new(buffer_start, buffer_end),
 2347                        options: lsp_command::lsp_formatting_options(settings),
 2348                        work_done_progress_params: Default::default(),
 2349                    },
 2350                    request_timeout,
 2351                )
 2352                .await
 2353                .into_response()?
 2354        } else {
 2355            None
 2356        };
 2357
 2358        if let Some(lsp_edits) = lsp_edits {
 2359            this.update(cx, |this, cx| {
 2360                this.as_local_mut().unwrap().edits_from_lsp(
 2361                    buffer,
 2362                    lsp_edits,
 2363                    language_server.server_id(),
 2364                    None,
 2365                    cx,
 2366                )
 2367            })?
 2368            .await
 2369        } else {
 2370            Ok(Vec::with_capacity(0))
 2371        }
 2372    }
 2373
 2374    async fn format_via_external_command(
 2375        buffer: &FormattableBuffer,
 2376        command: &str,
 2377        arguments: Option<&[String]>,
 2378        cx: &mut AsyncApp,
 2379    ) -> Result<Option<Diff>> {
 2380        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2381            let file = File::from_dyn(buffer.file())?;
 2382            let worktree = file.worktree.read(cx);
 2383            let mut worktree_path = worktree.abs_path().to_path_buf();
 2384            if worktree.root_entry()?.is_file() {
 2385                worktree_path.pop();
 2386            }
 2387            Some(worktree_path)
 2388        });
 2389
 2390        use util::command::Stdio;
 2391        let mut child = util::command::new_command(command);
 2392
 2393        if let Some(buffer_env) = buffer.env.as_ref() {
 2394            child.envs(buffer_env);
 2395        }
 2396
 2397        if let Some(working_dir_path) = working_dir_path {
 2398            child.current_dir(working_dir_path);
 2399        }
 2400
 2401        if let Some(arguments) = arguments {
 2402            child.args(arguments.iter().map(|arg| {
 2403                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2404                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2405                } else {
 2406                    arg.replace("{buffer_path}", "Untitled")
 2407                }
 2408            }));
 2409        }
 2410
 2411        let mut child = child
 2412            .stdin(Stdio::piped())
 2413            .stdout(Stdio::piped())
 2414            .stderr(Stdio::piped())
 2415            .spawn()?;
 2416
 2417        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2418        let text = buffer
 2419            .handle
 2420            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2421        for chunk in text.chunks() {
 2422            stdin.write_all(chunk.as_bytes()).await?;
 2423        }
 2424        stdin.flush().await?;
 2425
 2426        let output = child.output().await?;
 2427        anyhow::ensure!(
 2428            output.status.success(),
 2429            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2430            output.status.code(),
 2431            String::from_utf8_lossy(&output.stdout),
 2432            String::from_utf8_lossy(&output.stderr),
 2433        );
 2434
 2435        let stdout = String::from_utf8(output.stdout)?;
 2436        Ok(Some(
 2437            buffer
 2438                .handle
 2439                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2440                .await,
 2441        ))
 2442    }
 2443
 2444    async fn try_resolve_code_action(
 2445        lang_server: &LanguageServer,
 2446        action: &mut CodeAction,
 2447        request_timeout: Duration,
 2448    ) -> anyhow::Result<()> {
 2449        match &mut action.lsp_action {
 2450            LspAction::Action(lsp_action) => {
 2451                if !action.resolved
 2452                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2453                    && lsp_action.data.is_some()
 2454                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2455                {
 2456                    **lsp_action = lang_server
 2457                        .request::<lsp::request::CodeActionResolveRequest>(
 2458                            *lsp_action.clone(),
 2459                            request_timeout,
 2460                        )
 2461                        .await
 2462                        .into_response()?;
 2463                }
 2464            }
 2465            LspAction::CodeLens(lens) => {
 2466                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2467                    *lens = lang_server
 2468                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2469                        .await
 2470                        .into_response()?;
 2471                }
 2472            }
 2473            LspAction::Command(_) => {}
 2474        }
 2475
 2476        action.resolved = true;
 2477        anyhow::Ok(())
 2478    }
 2479
 2480    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2481        let buffer = buffer_handle.read(cx);
 2482
 2483        let file = buffer.file().cloned();
 2484
 2485        let Some(file) = File::from_dyn(file.as_ref()) else {
 2486            return;
 2487        };
 2488        if !file.is_local() {
 2489            return;
 2490        }
 2491        let path = ProjectPath::from_file(file, cx);
 2492        let worktree_id = file.worktree_id(cx);
 2493        let language = buffer.language().cloned();
 2494
 2495        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2496            for (server_id, diagnostics) in
 2497                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2498            {
 2499                self.update_buffer_diagnostics(
 2500                    buffer_handle,
 2501                    server_id,
 2502                    None,
 2503                    None,
 2504                    None,
 2505                    Vec::new(),
 2506                    diagnostics,
 2507                    cx,
 2508                )
 2509                .log_err();
 2510            }
 2511        }
 2512        let Some(language) = language else {
 2513            return;
 2514        };
 2515        let Some(snapshot) = self
 2516            .worktree_store
 2517            .read(cx)
 2518            .worktree_for_id(worktree_id, cx)
 2519            .map(|worktree| worktree.read(cx).snapshot())
 2520        else {
 2521            return;
 2522        };
 2523        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2524
 2525        for server_id in
 2526            self.lsp_tree
 2527                .get(path, language.name(), language.manifest(), &delegate, cx)
 2528        {
 2529            let server = self
 2530                .language_servers
 2531                .get(&server_id)
 2532                .and_then(|server_state| {
 2533                    if let LanguageServerState::Running { server, .. } = server_state {
 2534                        Some(server.clone())
 2535                    } else {
 2536                        None
 2537                    }
 2538                });
 2539            let server = match server {
 2540                Some(server) => server,
 2541                None => continue,
 2542            };
 2543
 2544            buffer_handle.update(cx, |buffer, cx| {
 2545                buffer.set_completion_triggers(
 2546                    server.server_id(),
 2547                    server
 2548                        .capabilities()
 2549                        .completion_provider
 2550                        .as_ref()
 2551                        .and_then(|provider| {
 2552                            provider
 2553                                .trigger_characters
 2554                                .as_ref()
 2555                                .map(|characters| characters.iter().cloned().collect())
 2556                        })
 2557                        .unwrap_or_default(),
 2558                    cx,
 2559                );
 2560            });
 2561        }
 2562    }
 2563
 2564    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2565        buffer.update(cx, |buffer, cx| {
 2566            let Some(language) = buffer.language() else {
 2567                return;
 2568            };
 2569            let path = ProjectPath {
 2570                worktree_id: old_file.worktree_id(cx),
 2571                path: old_file.path.clone(),
 2572            };
 2573            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2574                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2575                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2576            }
 2577        });
 2578    }
 2579
 2580    fn update_buffer_diagnostics(
 2581        &mut self,
 2582        buffer: &Entity<Buffer>,
 2583        server_id: LanguageServerId,
 2584        registration_id: Option<Option<SharedString>>,
 2585        result_id: Option<SharedString>,
 2586        version: Option<i32>,
 2587        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2588        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2589        cx: &mut Context<LspStore>,
 2590    ) -> Result<()> {
 2591        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2592            Ordering::Equal
 2593                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2594                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2595                .then_with(|| a.severity.cmp(&b.severity))
 2596                .then_with(|| a.message.cmp(&b.message))
 2597        }
 2598
 2599        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2600        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2601        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2602
 2603        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2604            Ordering::Equal
 2605                .then_with(|| a.range.start.cmp(&b.range.start))
 2606                .then_with(|| b.range.end.cmp(&a.range.end))
 2607                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2608        });
 2609
 2610        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2611
 2612        let edits_since_save = std::cell::LazyCell::new(|| {
 2613            let saved_version = buffer.read(cx).saved_version();
 2614            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2615        });
 2616
 2617        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2618
 2619        for (new_diagnostic, entry) in diagnostics {
 2620            let start;
 2621            let end;
 2622            if new_diagnostic && entry.diagnostic.is_disk_based {
 2623                // Some diagnostics are based on files on disk instead of buffers'
 2624                // current contents. Adjust these diagnostics' ranges to reflect
 2625                // any unsaved edits.
 2626                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2627                // and were properly adjusted on reuse.
 2628                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2629                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2630            } else {
 2631                start = entry.range.start;
 2632                end = entry.range.end;
 2633            }
 2634
 2635            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2636                ..snapshot.clip_point_utf16(end, Bias::Right);
 2637
 2638            // Expand empty ranges by one codepoint
 2639            if range.start == range.end {
 2640                // This will be go to the next boundary when being clipped
 2641                range.end.column += 1;
 2642                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2643                if range.start == range.end && range.end.column > 0 {
 2644                    range.start.column -= 1;
 2645                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2646                }
 2647            }
 2648
 2649            sanitized_diagnostics.push(DiagnosticEntry {
 2650                range,
 2651                diagnostic: entry.diagnostic,
 2652            });
 2653        }
 2654        drop(edits_since_save);
 2655
 2656        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2657        buffer.update(cx, |buffer, cx| {
 2658            if let Some(registration_id) = registration_id {
 2659                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2660                    self.buffer_pull_diagnostics_result_ids
 2661                        .entry(server_id)
 2662                        .or_default()
 2663                        .entry(registration_id)
 2664                        .or_default()
 2665                        .insert(abs_path, result_id);
 2666                }
 2667            }
 2668
 2669            buffer.update_diagnostics(server_id, set, cx)
 2670        });
 2671
 2672        Ok(())
 2673    }
 2674
 2675    fn register_language_server_for_invisible_worktree(
 2676        &mut self,
 2677        worktree: &Entity<Worktree>,
 2678        language_server_id: LanguageServerId,
 2679        cx: &mut App,
 2680    ) {
 2681        let worktree = worktree.read(cx);
 2682        let worktree_id = worktree.id();
 2683        debug_assert!(!worktree.is_visible());
 2684        let Some(mut origin_seed) = self
 2685            .language_server_ids
 2686            .iter()
 2687            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2688        else {
 2689            return;
 2690        };
 2691        origin_seed.worktree_id = worktree_id;
 2692        self.language_server_ids
 2693            .entry(origin_seed)
 2694            .or_insert_with(|| UnifiedLanguageServer {
 2695                id: language_server_id,
 2696                project_roots: Default::default(),
 2697            });
 2698    }
 2699
 2700    fn register_buffer_with_language_servers(
 2701        &mut self,
 2702        buffer_handle: &Entity<Buffer>,
 2703        only_register_servers: HashSet<LanguageServerSelector>,
 2704        cx: &mut Context<LspStore>,
 2705    ) {
 2706        let buffer = buffer_handle.read(cx);
 2707        let buffer_id = buffer.remote_id();
 2708
 2709        let Some(file) = File::from_dyn(buffer.file()) else {
 2710            return;
 2711        };
 2712        if !file.is_local() {
 2713            return;
 2714        }
 2715
 2716        let abs_path = file.abs_path(cx);
 2717        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2718            return;
 2719        };
 2720        let initial_snapshot = buffer.text_snapshot();
 2721        let worktree_id = file.worktree_id(cx);
 2722
 2723        let Some(language) = buffer.language().cloned() else {
 2724            return;
 2725        };
 2726        let path: Arc<RelPath> = file
 2727            .path()
 2728            .parent()
 2729            .map(Arc::from)
 2730            .unwrap_or_else(|| file.path().clone());
 2731        let Some(worktree) = self
 2732            .worktree_store
 2733            .read(cx)
 2734            .worktree_for_id(worktree_id, cx)
 2735        else {
 2736            return;
 2737        };
 2738        let language_name = language.name();
 2739        let (reused, delegate, servers) = self
 2740            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2741            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2742            .unwrap_or_else(|| {
 2743                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2744                let delegate: Arc<dyn ManifestDelegate> =
 2745                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2746
 2747                let servers = self
 2748                    .lsp_tree
 2749                    .walk(
 2750                        ProjectPath { worktree_id, path },
 2751                        language.name(),
 2752                        language.manifest(),
 2753                        &delegate,
 2754                        cx,
 2755                    )
 2756                    .collect::<Vec<_>>();
 2757                (false, lsp_delegate, servers)
 2758            });
 2759        let servers_and_adapters = servers
 2760            .into_iter()
 2761            .filter_map(|server_node| {
 2762                if reused && server_node.server_id().is_none() {
 2763                    return None;
 2764                }
 2765                if !only_register_servers.is_empty() {
 2766                    if let Some(server_id) = server_node.server_id()
 2767                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2768                    {
 2769                        return None;
 2770                    }
 2771                    if let Some(name) = server_node.name()
 2772                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2773                    {
 2774                        return None;
 2775                    }
 2776                }
 2777
 2778                let server_id = server_node.server_id_or_init(|disposition| {
 2779                    let path = &disposition.path;
 2780
 2781                    {
 2782                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2783
 2784                        let server_id = self.get_or_insert_language_server(
 2785                            &worktree,
 2786                            delegate.clone(),
 2787                            disposition,
 2788                            &language_name,
 2789                            cx,
 2790                        );
 2791
 2792                        if let Some(state) = self.language_servers.get(&server_id)
 2793                            && let Ok(uri) = uri
 2794                        {
 2795                            state.add_workspace_folder(uri);
 2796                        };
 2797                        server_id
 2798                    }
 2799                })?;
 2800                let server_state = self.language_servers.get(&server_id)?;
 2801                if let LanguageServerState::Running {
 2802                    server, adapter, ..
 2803                } = server_state
 2804                {
 2805                    Some((server.clone(), adapter.clone()))
 2806                } else {
 2807                    None
 2808                }
 2809            })
 2810            .collect::<Vec<_>>();
 2811        for (server, adapter) in servers_and_adapters {
 2812            buffer_handle.update(cx, |buffer, cx| {
 2813                buffer.set_completion_triggers(
 2814                    server.server_id(),
 2815                    server
 2816                        .capabilities()
 2817                        .completion_provider
 2818                        .as_ref()
 2819                        .and_then(|provider| {
 2820                            provider
 2821                                .trigger_characters
 2822                                .as_ref()
 2823                                .map(|characters| characters.iter().cloned().collect())
 2824                        })
 2825                        .unwrap_or_default(),
 2826                    cx,
 2827                );
 2828            });
 2829
 2830            let snapshot = LspBufferSnapshot {
 2831                version: 0,
 2832                snapshot: initial_snapshot.clone(),
 2833            };
 2834
 2835            let mut registered = false;
 2836            self.buffer_snapshots
 2837                .entry(buffer_id)
 2838                .or_default()
 2839                .entry(server.server_id())
 2840                .or_insert_with(|| {
 2841                    registered = true;
 2842                    server.register_buffer(
 2843                        uri.clone(),
 2844                        adapter.language_id(&language.name()),
 2845                        0,
 2846                        initial_snapshot.text(),
 2847                    );
 2848
 2849                    vec![snapshot]
 2850                });
 2851
 2852            self.buffers_opened_in_servers
 2853                .entry(buffer_id)
 2854                .or_default()
 2855                .insert(server.server_id());
 2856            if registered {
 2857                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2858                    language_server_id: server.server_id(),
 2859                    name: None,
 2860                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2861                        proto::RegisteredForBuffer {
 2862                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2863                            buffer_id: buffer_id.to_proto(),
 2864                        },
 2865                    ),
 2866                });
 2867            }
 2868        }
 2869    }
 2870
 2871    fn reuse_existing_language_server<'lang_name>(
 2872        &self,
 2873        server_tree: &LanguageServerTree,
 2874        worktree: &Entity<Worktree>,
 2875        language_name: &'lang_name LanguageName,
 2876        cx: &mut App,
 2877    ) -> Option<(
 2878        Arc<LocalLspAdapterDelegate>,
 2879        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2880    )> {
 2881        if worktree.read(cx).is_visible() {
 2882            return None;
 2883        }
 2884
 2885        let worktree_store = self.worktree_store.read(cx);
 2886        let servers = server_tree
 2887            .instances
 2888            .iter()
 2889            .filter(|(worktree_id, _)| {
 2890                worktree_store
 2891                    .worktree_for_id(**worktree_id, cx)
 2892                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2893            })
 2894            .flat_map(|(worktree_id, servers)| {
 2895                servers
 2896                    .roots
 2897                    .iter()
 2898                    .flat_map(|(_, language_servers)| language_servers)
 2899                    .map(move |(_, (server_node, server_languages))| {
 2900                        (worktree_id, server_node, server_languages)
 2901                    })
 2902                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2903                    .map(|(worktree_id, server_node, _)| {
 2904                        (
 2905                            *worktree_id,
 2906                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2907                        )
 2908                    })
 2909            })
 2910            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2911                acc.entry(worktree_id)
 2912                    .or_insert_with(Vec::new)
 2913                    .push(server_node);
 2914                acc
 2915            })
 2916            .into_values()
 2917            .max_by_key(|servers| servers.len())?;
 2918
 2919        let worktree_id = worktree.read(cx).id();
 2920        let apply = move |tree: &mut LanguageServerTree| {
 2921            for server_node in &servers {
 2922                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2923            }
 2924            servers
 2925        };
 2926
 2927        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2928        Some((delegate, apply))
 2929    }
 2930
 2931    pub(crate) fn unregister_old_buffer_from_language_servers(
 2932        &mut self,
 2933        buffer: &Entity<Buffer>,
 2934        old_file: &File,
 2935        cx: &mut App,
 2936    ) {
 2937        let old_path = match old_file.as_local() {
 2938            Some(local) => local.abs_path(cx),
 2939            None => return,
 2940        };
 2941
 2942        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2943            debug_panic!("{old_path:?} is not parseable as an URI");
 2944            return;
 2945        };
 2946        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2947    }
 2948
 2949    pub(crate) fn unregister_buffer_from_language_servers(
 2950        &mut self,
 2951        buffer: &Entity<Buffer>,
 2952        file_url: &lsp::Uri,
 2953        cx: &mut App,
 2954    ) {
 2955        buffer.update(cx, |buffer, cx| {
 2956            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2957
 2958            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2959                if snapshots
 2960                    .as_mut()
 2961                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2962                {
 2963                    language_server.unregister_buffer(file_url.clone());
 2964                }
 2965            }
 2966        });
 2967    }
 2968
 2969    fn buffer_snapshot_for_lsp_version(
 2970        &mut self,
 2971        buffer: &Entity<Buffer>,
 2972        server_id: LanguageServerId,
 2973        version: Option<i32>,
 2974        cx: &App,
 2975    ) -> Result<TextBufferSnapshot> {
 2976        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2977
 2978        if let Some(version) = version {
 2979            let buffer_id = buffer.read(cx).remote_id();
 2980            let snapshots = if let Some(snapshots) = self
 2981                .buffer_snapshots
 2982                .get_mut(&buffer_id)
 2983                .and_then(|m| m.get_mut(&server_id))
 2984            {
 2985                snapshots
 2986            } else if version == 0 {
 2987                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2988                // We detect this case and treat it as if the version was `None`.
 2989                return Ok(buffer.read(cx).text_snapshot());
 2990            } else {
 2991                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2992            };
 2993
 2994            let found_snapshot = snapshots
 2995                    .binary_search_by_key(&version, |e| e.version)
 2996                    .map(|ix| snapshots[ix].snapshot.clone())
 2997                    .map_err(|_| {
 2998                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2999                    })?;
 3000
 3001            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3002            Ok(found_snapshot)
 3003        } else {
 3004            Ok((buffer.read(cx)).text_snapshot())
 3005        }
 3006    }
 3007
 3008    async fn get_server_code_actions_from_action_kinds(
 3009        lsp_store: &WeakEntity<LspStore>,
 3010        language_server_id: LanguageServerId,
 3011        code_action_kinds: Vec<lsp::CodeActionKind>,
 3012        buffer: &Entity<Buffer>,
 3013        cx: &mut AsyncApp,
 3014    ) -> Result<Vec<CodeAction>> {
 3015        let actions = lsp_store
 3016            .update(cx, move |this, cx| {
 3017                let request = GetCodeActions {
 3018                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3019                    kinds: Some(code_action_kinds),
 3020                };
 3021                let server = LanguageServerToQuery::Other(language_server_id);
 3022                this.request_lsp(buffer.clone(), server, request, cx)
 3023            })?
 3024            .await?;
 3025        Ok(actions)
 3026    }
 3027
 3028    pub async fn execute_code_actions_on_server(
 3029        lsp_store: &WeakEntity<LspStore>,
 3030        language_server: &Arc<LanguageServer>,
 3031        actions: Vec<CodeAction>,
 3032        push_to_history: bool,
 3033        project_transaction: &mut ProjectTransaction,
 3034        cx: &mut AsyncApp,
 3035    ) -> anyhow::Result<()> {
 3036        let request_timeout = cx.update(|app| {
 3037            ProjectSettings::get_global(app)
 3038                .global_lsp_settings
 3039                .get_request_timeout()
 3040        });
 3041
 3042        for mut action in actions {
 3043            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3044                .await
 3045                .context("resolving a formatting code action")?;
 3046
 3047            if let Some(edit) = action.lsp_action.edit() {
 3048                if edit.changes.is_none() && edit.document_changes.is_none() {
 3049                    continue;
 3050                }
 3051
 3052                let new = Self::deserialize_workspace_edit(
 3053                    lsp_store.upgrade().context("project dropped")?,
 3054                    edit.clone(),
 3055                    push_to_history,
 3056                    language_server.clone(),
 3057                    cx,
 3058                )
 3059                .await?;
 3060                project_transaction.0.extend(new.0);
 3061            }
 3062
 3063            let Some(command) = action.lsp_action.command() else {
 3064                continue;
 3065            };
 3066
 3067            let server_capabilities = language_server.capabilities();
 3068            let available_commands = server_capabilities
 3069                .execute_command_provider
 3070                .as_ref()
 3071                .map(|options| options.commands.as_slice())
 3072                .unwrap_or_default();
 3073            if !available_commands.contains(&command.command) {
 3074                log::warn!(
 3075                    "Cannot execute a command {} not listed in the language server capabilities",
 3076                    command.command
 3077                );
 3078                continue;
 3079            }
 3080
 3081            lsp_store.update(cx, |lsp_store, _| {
 3082                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3083                    mode.last_workspace_edits_by_language_server
 3084                        .remove(&language_server.server_id());
 3085                }
 3086            })?;
 3087
 3088            language_server
 3089                .request::<lsp::request::ExecuteCommand>(
 3090                    lsp::ExecuteCommandParams {
 3091                        command: command.command.clone(),
 3092                        arguments: command.arguments.clone().unwrap_or_default(),
 3093                        ..Default::default()
 3094                    },
 3095                    request_timeout,
 3096                )
 3097                .await
 3098                .into_response()
 3099                .context("execute command")?;
 3100
 3101            lsp_store.update(cx, |this, _| {
 3102                if let LspStoreMode::Local(mode) = &mut this.mode {
 3103                    project_transaction.0.extend(
 3104                        mode.last_workspace_edits_by_language_server
 3105                            .remove(&language_server.server_id())
 3106                            .unwrap_or_default()
 3107                            .0,
 3108                    )
 3109                }
 3110            })?;
 3111        }
 3112        Ok(())
 3113    }
 3114
 3115    pub async fn deserialize_text_edits(
 3116        this: Entity<LspStore>,
 3117        buffer_to_edit: Entity<Buffer>,
 3118        edits: Vec<lsp::TextEdit>,
 3119        push_to_history: bool,
 3120        _: Arc<CachedLspAdapter>,
 3121        language_server: Arc<LanguageServer>,
 3122        cx: &mut AsyncApp,
 3123    ) -> Result<Option<Transaction>> {
 3124        let edits = this
 3125            .update(cx, |this, cx| {
 3126                this.as_local_mut().unwrap().edits_from_lsp(
 3127                    &buffer_to_edit,
 3128                    edits,
 3129                    language_server.server_id(),
 3130                    None,
 3131                    cx,
 3132                )
 3133            })
 3134            .await?;
 3135
 3136        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3137            buffer.finalize_last_transaction();
 3138            buffer.start_transaction();
 3139            for (range, text) in edits {
 3140                buffer.edit([(range, text)], None, cx);
 3141            }
 3142
 3143            if buffer.end_transaction(cx).is_some() {
 3144                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3145                if !push_to_history {
 3146                    buffer.forget_transaction(transaction.id);
 3147                }
 3148                Some(transaction)
 3149            } else {
 3150                None
 3151            }
 3152        });
 3153
 3154        Ok(transaction)
 3155    }
 3156
 3157    #[allow(clippy::type_complexity)]
 3158    pub fn edits_from_lsp(
 3159        &mut self,
 3160        buffer: &Entity<Buffer>,
 3161        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3162        server_id: LanguageServerId,
 3163        version: Option<i32>,
 3164        cx: &mut Context<LspStore>,
 3165    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3166        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3167        cx.background_spawn(async move {
 3168            let snapshot = snapshot?;
 3169            let mut lsp_edits = lsp_edits
 3170                .into_iter()
 3171                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3172                .collect::<Vec<_>>();
 3173
 3174            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3175
 3176            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3177            let mut edits = Vec::new();
 3178            while let Some((range, mut new_text)) = lsp_edits.next() {
 3179                // Clip invalid ranges provided by the language server.
 3180                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3181                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3182
 3183                // Combine any LSP edits that are adjacent.
 3184                //
 3185                // Also, combine LSP edits that are separated from each other by only
 3186                // a newline. This is important because for some code actions,
 3187                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3188                // are separated by unchanged newline characters.
 3189                //
 3190                // In order for the diffing logic below to work properly, any edits that
 3191                // cancel each other out must be combined into one.
 3192                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3193                    if next_range.start.0 > range.end {
 3194                        if next_range.start.0.row > range.end.row + 1
 3195                            || next_range.start.0.column > 0
 3196                            || snapshot.clip_point_utf16(
 3197                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3198                                Bias::Left,
 3199                            ) > range.end
 3200                        {
 3201                            break;
 3202                        }
 3203                        new_text.push('\n');
 3204                    }
 3205                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3206                    new_text.push_str(next_text);
 3207                    lsp_edits.next();
 3208                }
 3209
 3210                // For multiline edits, perform a diff of the old and new text so that
 3211                // we can identify the changes more precisely, preserving the locations
 3212                // of any anchors positioned in the unchanged regions.
 3213                if range.end.row > range.start.row {
 3214                    let offset = range.start.to_offset(&snapshot);
 3215                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3216                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3217                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3218                        (
 3219                            snapshot.anchor_after(offset + range.start)
 3220                                ..snapshot.anchor_before(offset + range.end),
 3221                            replacement,
 3222                        )
 3223                    }));
 3224                } else if range.end == range.start {
 3225                    let anchor = snapshot.anchor_after(range.start);
 3226                    edits.push((anchor..anchor, new_text.into()));
 3227                } else {
 3228                    let edit_start = snapshot.anchor_after(range.start);
 3229                    let edit_end = snapshot.anchor_before(range.end);
 3230                    edits.push((edit_start..edit_end, new_text.into()));
 3231                }
 3232            }
 3233
 3234            Ok(edits)
 3235        })
 3236    }
 3237
 3238    pub(crate) async fn deserialize_workspace_edit(
 3239        this: Entity<LspStore>,
 3240        edit: lsp::WorkspaceEdit,
 3241        push_to_history: bool,
 3242        language_server: Arc<LanguageServer>,
 3243        cx: &mut AsyncApp,
 3244    ) -> Result<ProjectTransaction> {
 3245        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3246
 3247        let mut operations = Vec::new();
 3248        if let Some(document_changes) = edit.document_changes {
 3249            match document_changes {
 3250                lsp::DocumentChanges::Edits(edits) => {
 3251                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3252                }
 3253                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3254            }
 3255        } else if let Some(changes) = edit.changes {
 3256            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3257                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3258                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3259                        uri,
 3260                        version: None,
 3261                    },
 3262                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3263                })
 3264            }));
 3265        }
 3266
 3267        let mut project_transaction = ProjectTransaction::default();
 3268        for operation in operations {
 3269            match operation {
 3270                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3271                    let abs_path = op
 3272                        .uri
 3273                        .to_file_path()
 3274                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3275
 3276                    if let Some(parent_path) = abs_path.parent() {
 3277                        fs.create_dir(parent_path).await?;
 3278                    }
 3279                    if abs_path.ends_with("/") {
 3280                        fs.create_dir(&abs_path).await?;
 3281                    } else {
 3282                        fs.create_file(
 3283                            &abs_path,
 3284                            op.options
 3285                                .map(|options| fs::CreateOptions {
 3286                                    overwrite: options.overwrite.unwrap_or(false),
 3287                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3288                                })
 3289                                .unwrap_or_default(),
 3290                        )
 3291                        .await?;
 3292                    }
 3293                }
 3294
 3295                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3296                    let source_abs_path = op
 3297                        .old_uri
 3298                        .to_file_path()
 3299                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3300                    let target_abs_path = op
 3301                        .new_uri
 3302                        .to_file_path()
 3303                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3304
 3305                    let options = fs::RenameOptions {
 3306                        overwrite: op
 3307                            .options
 3308                            .as_ref()
 3309                            .and_then(|options| options.overwrite)
 3310                            .unwrap_or(false),
 3311                        ignore_if_exists: op
 3312                            .options
 3313                            .as_ref()
 3314                            .and_then(|options| options.ignore_if_exists)
 3315                            .unwrap_or(false),
 3316                        create_parents: true,
 3317                    };
 3318
 3319                    fs.rename(&source_abs_path, &target_abs_path, options)
 3320                        .await?;
 3321                }
 3322
 3323                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3324                    let abs_path = op
 3325                        .uri
 3326                        .to_file_path()
 3327                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3328                    let options = op
 3329                        .options
 3330                        .map(|options| fs::RemoveOptions {
 3331                            recursive: options.recursive.unwrap_or(false),
 3332                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3333                        })
 3334                        .unwrap_or_default();
 3335                    if abs_path.ends_with("/") {
 3336                        fs.remove_dir(&abs_path, options).await?;
 3337                    } else {
 3338                        fs.remove_file(&abs_path, options).await?;
 3339                    }
 3340                }
 3341
 3342                lsp::DocumentChangeOperation::Edit(op) => {
 3343                    let buffer_to_edit = this
 3344                        .update(cx, |this, cx| {
 3345                            this.open_local_buffer_via_lsp(
 3346                                op.text_document.uri.clone(),
 3347                                language_server.server_id(),
 3348                                cx,
 3349                            )
 3350                        })
 3351                        .await?;
 3352
 3353                    let edits = this
 3354                        .update(cx, |this, cx| {
 3355                            let path = buffer_to_edit.read(cx).project_path(cx);
 3356                            let active_entry = this.active_entry;
 3357                            let is_active_entry = path.is_some_and(|project_path| {
 3358                                this.worktree_store
 3359                                    .read(cx)
 3360                                    .entry_for_path(&project_path, cx)
 3361                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3362                            });
 3363                            let local = this.as_local_mut().unwrap();
 3364
 3365                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3366                            for edit in op.edits {
 3367                                match edit {
 3368                                    Edit::Plain(edit) => {
 3369                                        if !edits.contains(&edit) {
 3370                                            edits.push(edit)
 3371                                        }
 3372                                    }
 3373                                    Edit::Annotated(edit) => {
 3374                                        if !edits.contains(&edit.text_edit) {
 3375                                            edits.push(edit.text_edit)
 3376                                        }
 3377                                    }
 3378                                    Edit::Snippet(edit) => {
 3379                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3380                                        else {
 3381                                            continue;
 3382                                        };
 3383
 3384                                        if is_active_entry {
 3385                                            snippet_edits.push((edit.range, snippet));
 3386                                        } else {
 3387                                            // Since this buffer is not focused, apply a normal edit.
 3388                                            let new_edit = TextEdit {
 3389                                                range: edit.range,
 3390                                                new_text: snippet.text,
 3391                                            };
 3392                                            if !edits.contains(&new_edit) {
 3393                                                edits.push(new_edit);
 3394                                            }
 3395                                        }
 3396                                    }
 3397                                }
 3398                            }
 3399                            if !snippet_edits.is_empty() {
 3400                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3401                                let version = if let Some(buffer_version) = op.text_document.version
 3402                                {
 3403                                    local
 3404                                        .buffer_snapshot_for_lsp_version(
 3405                                            &buffer_to_edit,
 3406                                            language_server.server_id(),
 3407                                            Some(buffer_version),
 3408                                            cx,
 3409                                        )
 3410                                        .ok()
 3411                                        .map(|snapshot| snapshot.version)
 3412                                } else {
 3413                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3414                                };
 3415
 3416                                let most_recent_edit =
 3417                                    version.and_then(|version| version.most_recent());
 3418                                // Check if the edit that triggered that edit has been made by this participant.
 3419
 3420                                if let Some(most_recent_edit) = most_recent_edit {
 3421                                    cx.emit(LspStoreEvent::SnippetEdit {
 3422                                        buffer_id,
 3423                                        edits: snippet_edits,
 3424                                        most_recent_edit,
 3425                                    });
 3426                                }
 3427                            }
 3428
 3429                            local.edits_from_lsp(
 3430                                &buffer_to_edit,
 3431                                edits,
 3432                                language_server.server_id(),
 3433                                op.text_document.version,
 3434                                cx,
 3435                            )
 3436                        })
 3437                        .await?;
 3438
 3439                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3440                        buffer.finalize_last_transaction();
 3441                        buffer.start_transaction();
 3442                        for (range, text) in edits {
 3443                            buffer.edit([(range, text)], None, cx);
 3444                        }
 3445
 3446                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3447                            if push_to_history {
 3448                                buffer.finalize_last_transaction();
 3449                                buffer.get_transaction(transaction_id).cloned()
 3450                            } else {
 3451                                buffer.forget_transaction(transaction_id)
 3452                            }
 3453                        })
 3454                    });
 3455                    if let Some(transaction) = transaction {
 3456                        project_transaction.0.insert(buffer_to_edit, transaction);
 3457                    }
 3458                }
 3459            }
 3460        }
 3461
 3462        Ok(project_transaction)
 3463    }
 3464
 3465    async fn on_lsp_workspace_edit(
 3466        this: WeakEntity<LspStore>,
 3467        params: lsp::ApplyWorkspaceEditParams,
 3468        server_id: LanguageServerId,
 3469        cx: &mut AsyncApp,
 3470    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3471        let this = this.upgrade().context("project project closed")?;
 3472        let language_server = this
 3473            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3474            .context("language server not found")?;
 3475        let transaction = Self::deserialize_workspace_edit(
 3476            this.clone(),
 3477            params.edit,
 3478            true,
 3479            language_server.clone(),
 3480            cx,
 3481        )
 3482        .await
 3483        .log_err();
 3484        this.update(cx, |this, cx| {
 3485            if let Some(transaction) = transaction {
 3486                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3487
 3488                this.as_local_mut()
 3489                    .unwrap()
 3490                    .last_workspace_edits_by_language_server
 3491                    .insert(server_id, transaction);
 3492            }
 3493        });
 3494        Ok(lsp::ApplyWorkspaceEditResponse {
 3495            applied: true,
 3496            failed_change: None,
 3497            failure_reason: None,
 3498        })
 3499    }
 3500
 3501    fn remove_worktree(
 3502        &mut self,
 3503        id_to_remove: WorktreeId,
 3504        cx: &mut Context<LspStore>,
 3505    ) -> Vec<LanguageServerId> {
 3506        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3507        self.diagnostics.remove(&id_to_remove);
 3508        self.prettier_store.update(cx, |prettier_store, cx| {
 3509            prettier_store.remove_worktree(id_to_remove, cx);
 3510        });
 3511
 3512        let mut servers_to_remove = BTreeSet::default();
 3513        let mut servers_to_preserve = HashSet::default();
 3514        for (seed, state) in &self.language_server_ids {
 3515            if seed.worktree_id == id_to_remove {
 3516                servers_to_remove.insert(state.id);
 3517            } else {
 3518                servers_to_preserve.insert(state.id);
 3519            }
 3520        }
 3521        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3522        self.language_server_ids
 3523            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3524        for server_id_to_remove in &servers_to_remove {
 3525            self.language_server_watched_paths
 3526                .remove(server_id_to_remove);
 3527            self.language_server_paths_watched_for_rename
 3528                .remove(server_id_to_remove);
 3529            self.last_workspace_edits_by_language_server
 3530                .remove(server_id_to_remove);
 3531            self.language_servers.remove(server_id_to_remove);
 3532            self.buffer_pull_diagnostics_result_ids
 3533                .remove(server_id_to_remove);
 3534            self.workspace_pull_diagnostics_result_ids
 3535                .remove(server_id_to_remove);
 3536            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3537                buffer_servers.remove(server_id_to_remove);
 3538            }
 3539            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3540        }
 3541        servers_to_remove.into_iter().collect()
 3542    }
 3543
 3544    fn rebuild_watched_paths_inner<'a>(
 3545        &'a self,
 3546        language_server_id: LanguageServerId,
 3547        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3548        cx: &mut Context<LspStore>,
 3549    ) -> LanguageServerWatchedPathsBuilder {
 3550        let worktrees = self
 3551            .worktree_store
 3552            .read(cx)
 3553            .worktrees()
 3554            .filter_map(|worktree| {
 3555                self.language_servers_for_worktree(worktree.read(cx).id())
 3556                    .find(|server| server.server_id() == language_server_id)
 3557                    .map(|_| worktree)
 3558            })
 3559            .collect::<Vec<_>>();
 3560
 3561        let mut worktree_globs = HashMap::default();
 3562        let mut abs_globs = HashMap::default();
 3563        log::trace!(
 3564            "Processing new watcher paths for language server with id {}",
 3565            language_server_id
 3566        );
 3567
 3568        for watcher in watchers {
 3569            if let Some((worktree, literal_prefix, pattern)) =
 3570                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3571            {
 3572                worktree.update(cx, |worktree, _| {
 3573                    if let Some((tree, glob)) =
 3574                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3575                    {
 3576                        tree.add_path_prefix_to_scan(literal_prefix);
 3577                        worktree_globs
 3578                            .entry(tree.id())
 3579                            .or_insert_with(GlobSetBuilder::new)
 3580                            .add(glob);
 3581                    }
 3582                });
 3583            } else {
 3584                let (path, pattern) = match &watcher.glob_pattern {
 3585                    lsp::GlobPattern::String(s) => {
 3586                        let watcher_path = SanitizedPath::new(s);
 3587                        let path = glob_literal_prefix(watcher_path.as_path());
 3588                        let pattern = watcher_path
 3589                            .as_path()
 3590                            .strip_prefix(&path)
 3591                            .map(|p| p.to_string_lossy().into_owned())
 3592                            .unwrap_or_else(|e| {
 3593                                debug_panic!(
 3594                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3595                                    s,
 3596                                    path.display(),
 3597                                    e
 3598                                );
 3599                                watcher_path.as_path().to_string_lossy().into_owned()
 3600                            });
 3601                        (path, pattern)
 3602                    }
 3603                    lsp::GlobPattern::Relative(rp) => {
 3604                        let Ok(mut base_uri) = match &rp.base_uri {
 3605                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3606                            lsp::OneOf::Right(base_uri) => base_uri,
 3607                        }
 3608                        .to_file_path() else {
 3609                            continue;
 3610                        };
 3611
 3612                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3613                        let pattern = Path::new(&rp.pattern)
 3614                            .strip_prefix(&path)
 3615                            .map(|p| p.to_string_lossy().into_owned())
 3616                            .unwrap_or_else(|e| {
 3617                                debug_panic!(
 3618                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3619                                    rp.pattern,
 3620                                    path.display(),
 3621                                    e
 3622                                );
 3623                                rp.pattern.clone()
 3624                            });
 3625                        base_uri.push(path);
 3626                        (base_uri, pattern)
 3627                    }
 3628                };
 3629
 3630                if let Some(glob) = Glob::new(&pattern).log_err() {
 3631                    if !path
 3632                        .components()
 3633                        .any(|c| matches!(c, path::Component::Normal(_)))
 3634                    {
 3635                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3636                        // rather than adding a new watcher for `/`.
 3637                        for worktree in &worktrees {
 3638                            worktree_globs
 3639                                .entry(worktree.read(cx).id())
 3640                                .or_insert_with(GlobSetBuilder::new)
 3641                                .add(glob.clone());
 3642                        }
 3643                    } else {
 3644                        abs_globs
 3645                            .entry(path.into())
 3646                            .or_insert_with(GlobSetBuilder::new)
 3647                            .add(glob);
 3648                    }
 3649                }
 3650            }
 3651        }
 3652
 3653        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3654        for (worktree_id, builder) in worktree_globs {
 3655            if let Ok(globset) = builder.build() {
 3656                watch_builder.watch_worktree(worktree_id, globset);
 3657            }
 3658        }
 3659        for (abs_path, builder) in abs_globs {
 3660            if let Ok(globset) = builder.build() {
 3661                watch_builder.watch_abs_path(abs_path, globset);
 3662            }
 3663        }
 3664        watch_builder
 3665    }
 3666
 3667    fn worktree_and_path_for_file_watcher(
 3668        worktrees: &[Entity<Worktree>],
 3669        watcher: &FileSystemWatcher,
 3670        cx: &App,
 3671    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3672        worktrees.iter().find_map(|worktree| {
 3673            let tree = worktree.read(cx);
 3674            let worktree_root_path = tree.abs_path();
 3675            let path_style = tree.path_style();
 3676            match &watcher.glob_pattern {
 3677                lsp::GlobPattern::String(s) => {
 3678                    let watcher_path = SanitizedPath::new(s);
 3679                    let relative = watcher_path
 3680                        .as_path()
 3681                        .strip_prefix(&worktree_root_path)
 3682                        .ok()?;
 3683                    let literal_prefix = glob_literal_prefix(relative);
 3684                    Some((
 3685                        worktree.clone(),
 3686                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3687                        relative.to_string_lossy().into_owned(),
 3688                    ))
 3689                }
 3690                lsp::GlobPattern::Relative(rp) => {
 3691                    let base_uri = match &rp.base_uri {
 3692                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3693                        lsp::OneOf::Right(base_uri) => base_uri,
 3694                    }
 3695                    .to_file_path()
 3696                    .ok()?;
 3697                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3698                    let mut literal_prefix = relative.to_owned();
 3699                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3700                    Some((
 3701                        worktree.clone(),
 3702                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3703                        rp.pattern.clone(),
 3704                    ))
 3705                }
 3706            }
 3707        })
 3708    }
 3709
 3710    fn rebuild_watched_paths(
 3711        &mut self,
 3712        language_server_id: LanguageServerId,
 3713        cx: &mut Context<LspStore>,
 3714    ) {
 3715        let Some(registrations) = self
 3716            .language_server_dynamic_registrations
 3717            .get(&language_server_id)
 3718        else {
 3719            return;
 3720        };
 3721
 3722        let watch_builder = self.rebuild_watched_paths_inner(
 3723            language_server_id,
 3724            registrations.did_change_watched_files.values().flatten(),
 3725            cx,
 3726        );
 3727        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3728        self.language_server_watched_paths
 3729            .insert(language_server_id, watcher);
 3730
 3731        cx.notify();
 3732    }
 3733
 3734    fn on_lsp_did_change_watched_files(
 3735        &mut self,
 3736        language_server_id: LanguageServerId,
 3737        registration_id: &str,
 3738        params: DidChangeWatchedFilesRegistrationOptions,
 3739        cx: &mut Context<LspStore>,
 3740    ) {
 3741        let registrations = self
 3742            .language_server_dynamic_registrations
 3743            .entry(language_server_id)
 3744            .or_default();
 3745
 3746        registrations
 3747            .did_change_watched_files
 3748            .insert(registration_id.to_string(), params.watchers);
 3749
 3750        self.rebuild_watched_paths(language_server_id, cx);
 3751    }
 3752
 3753    fn on_lsp_unregister_did_change_watched_files(
 3754        &mut self,
 3755        language_server_id: LanguageServerId,
 3756        registration_id: &str,
 3757        cx: &mut Context<LspStore>,
 3758    ) {
 3759        let registrations = self
 3760            .language_server_dynamic_registrations
 3761            .entry(language_server_id)
 3762            .or_default();
 3763
 3764        if registrations
 3765            .did_change_watched_files
 3766            .remove(registration_id)
 3767            .is_some()
 3768        {
 3769            log::info!(
 3770                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3771                language_server_id,
 3772                registration_id
 3773            );
 3774        } else {
 3775            log::warn!(
 3776                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3777                language_server_id,
 3778                registration_id
 3779            );
 3780        }
 3781
 3782        self.rebuild_watched_paths(language_server_id, cx);
 3783    }
 3784
 3785    async fn initialization_options_for_adapter(
 3786        adapter: Arc<dyn LspAdapter>,
 3787        delegate: &Arc<dyn LspAdapterDelegate>,
 3788        cx: &mut AsyncApp,
 3789    ) -> Result<Option<serde_json::Value>> {
 3790        let Some(mut initialization_config) =
 3791            adapter.clone().initialization_options(delegate, cx).await?
 3792        else {
 3793            return Ok(None);
 3794        };
 3795
 3796        for other_adapter in delegate.registered_lsp_adapters() {
 3797            if other_adapter.name() == adapter.name() {
 3798                continue;
 3799            }
 3800            if let Ok(Some(target_config)) = other_adapter
 3801                .clone()
 3802                .additional_initialization_options(adapter.name(), delegate)
 3803                .await
 3804            {
 3805                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3806            }
 3807        }
 3808
 3809        Ok(Some(initialization_config))
 3810    }
 3811
 3812    async fn workspace_configuration_for_adapter(
 3813        adapter: Arc<dyn LspAdapter>,
 3814        delegate: &Arc<dyn LspAdapterDelegate>,
 3815        toolchain: Option<Toolchain>,
 3816        requested_uri: Option<Uri>,
 3817        cx: &mut AsyncApp,
 3818    ) -> Result<serde_json::Value> {
 3819        let mut workspace_config = adapter
 3820            .clone()
 3821            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3822            .await?;
 3823
 3824        for other_adapter in delegate.registered_lsp_adapters() {
 3825            if other_adapter.name() == adapter.name() {
 3826                continue;
 3827            }
 3828            if let Ok(Some(target_config)) = other_adapter
 3829                .clone()
 3830                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3831                .await
 3832            {
 3833                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3834            }
 3835        }
 3836
 3837        Ok(workspace_config)
 3838    }
 3839
 3840    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3841        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3842            Some(server.clone())
 3843        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3844            Some(Arc::clone(server))
 3845        } else {
 3846            None
 3847        }
 3848    }
 3849}
 3850
 3851fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3852    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3853        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3854            language_server_id: server.server_id(),
 3855            name: Some(server.name()),
 3856            message: proto::update_language_server::Variant::MetadataUpdated(
 3857                proto::ServerMetadataUpdated {
 3858                    capabilities: Some(capabilities),
 3859                    binary: Some(proto::LanguageServerBinaryInfo {
 3860                        path: server.binary().path.to_string_lossy().into_owned(),
 3861                        arguments: server
 3862                            .binary()
 3863                            .arguments
 3864                            .iter()
 3865                            .map(|arg| arg.to_string_lossy().into_owned())
 3866                            .collect(),
 3867                    }),
 3868                    configuration: serde_json::to_string(server.configuration()).ok(),
 3869                    workspace_folders: server
 3870                        .workspace_folders()
 3871                        .iter()
 3872                        .map(|uri| uri.to_string())
 3873                        .collect(),
 3874                },
 3875            ),
 3876        });
 3877    }
 3878}
 3879
 3880#[derive(Debug)]
 3881pub struct FormattableBuffer {
 3882    handle: Entity<Buffer>,
 3883    abs_path: Option<PathBuf>,
 3884    env: Option<HashMap<String, String>>,
 3885    ranges: Option<Vec<Range<Anchor>>>,
 3886}
 3887
 3888pub struct RemoteLspStore {
 3889    upstream_client: Option<AnyProtoClient>,
 3890    upstream_project_id: u64,
 3891}
 3892
 3893pub(crate) enum LspStoreMode {
 3894    Local(LocalLspStore),   // ssh host and collab host
 3895    Remote(RemoteLspStore), // collab guest
 3896}
 3897
 3898impl LspStoreMode {
 3899    fn is_local(&self) -> bool {
 3900        matches!(self, LspStoreMode::Local(_))
 3901    }
 3902}
 3903
 3904pub struct LspStore {
 3905    mode: LspStoreMode,
 3906    last_formatting_failure: Option<String>,
 3907    downstream_client: Option<(AnyProtoClient, u64)>,
 3908    nonce: u128,
 3909    buffer_store: Entity<BufferStore>,
 3910    worktree_store: Entity<WorktreeStore>,
 3911    pub languages: Arc<LanguageRegistry>,
 3912    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3913    active_entry: Option<ProjectEntryId>,
 3914    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3915    _maintain_buffer_languages: Task<()>,
 3916    diagnostic_summaries:
 3917        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3918    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3919    semantic_token_config: SemanticTokenConfig,
 3920    lsp_data: HashMap<BufferId, BufferLspData>,
 3921    next_hint_id: Arc<AtomicUsize>,
 3922}
 3923
 3924#[derive(Debug)]
 3925pub struct BufferLspData {
 3926    buffer_version: Global,
 3927    document_colors: Option<DocumentColorData>,
 3928    code_lens: Option<CodeLensData>,
 3929    semantic_tokens: Option<SemanticTokensData>,
 3930    folding_ranges: Option<FoldingRangeData>,
 3931    document_symbols: Option<DocumentSymbolsData>,
 3932    inlay_hints: BufferInlayHints,
 3933    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3934    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3935}
 3936
 3937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3938struct LspKey {
 3939    request_type: TypeId,
 3940    server_queried: Option<LanguageServerId>,
 3941}
 3942
 3943impl BufferLspData {
 3944    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3945        Self {
 3946            buffer_version: buffer.read(cx).version(),
 3947            document_colors: None,
 3948            code_lens: None,
 3949            semantic_tokens: None,
 3950            folding_ranges: None,
 3951            document_symbols: None,
 3952            inlay_hints: BufferInlayHints::new(buffer, cx),
 3953            lsp_requests: HashMap::default(),
 3954            chunk_lsp_requests: HashMap::default(),
 3955        }
 3956    }
 3957
 3958    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3959        if let Some(document_colors) = &mut self.document_colors {
 3960            document_colors.remove_server_data(for_server);
 3961        }
 3962
 3963        if let Some(code_lens) = &mut self.code_lens {
 3964            code_lens.remove_server_data(for_server);
 3965        }
 3966
 3967        self.inlay_hints.remove_server_data(for_server);
 3968
 3969        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 3970            semantic_tokens.remove_server_data(for_server);
 3971        }
 3972
 3973        if let Some(folding_ranges) = &mut self.folding_ranges {
 3974            folding_ranges.ranges.remove(&for_server);
 3975        }
 3976
 3977        if let Some(document_symbols) = &mut self.document_symbols {
 3978            document_symbols.remove_server_data(for_server);
 3979        }
 3980    }
 3981
 3982    #[cfg(any(test, feature = "test-support"))]
 3983    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3984        &self.inlay_hints
 3985    }
 3986}
 3987
 3988#[derive(Debug)]
 3989pub enum LspStoreEvent {
 3990    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3991    LanguageServerRemoved(LanguageServerId),
 3992    LanguageServerUpdate {
 3993        language_server_id: LanguageServerId,
 3994        name: Option<LanguageServerName>,
 3995        message: proto::update_language_server::Variant,
 3996    },
 3997    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3998    LanguageServerPrompt(LanguageServerPromptRequest),
 3999    LanguageDetected {
 4000        buffer: Entity<Buffer>,
 4001        new_language: Option<Arc<Language>>,
 4002    },
 4003    Notification(String),
 4004    RefreshInlayHints {
 4005        server_id: LanguageServerId,
 4006        request_id: Option<usize>,
 4007    },
 4008    RefreshSemanticTokens {
 4009        server_id: LanguageServerId,
 4010        request_id: Option<usize>,
 4011    },
 4012    RefreshCodeLens,
 4013    DiagnosticsUpdated {
 4014        server_id: LanguageServerId,
 4015        paths: Vec<ProjectPath>,
 4016    },
 4017    DiskBasedDiagnosticsStarted {
 4018        language_server_id: LanguageServerId,
 4019    },
 4020    DiskBasedDiagnosticsFinished {
 4021        language_server_id: LanguageServerId,
 4022    },
 4023    SnippetEdit {
 4024        buffer_id: BufferId,
 4025        edits: Vec<(lsp::Range, Snippet)>,
 4026        most_recent_edit: clock::Lamport,
 4027    },
 4028    WorkspaceEditApplied(ProjectTransaction),
 4029}
 4030
 4031#[derive(Clone, Debug, Serialize)]
 4032pub struct LanguageServerStatus {
 4033    pub name: LanguageServerName,
 4034    pub server_version: Option<SharedString>,
 4035    pub server_readable_version: Option<SharedString>,
 4036    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4037    pub has_pending_diagnostic_updates: bool,
 4038    pub progress_tokens: HashSet<ProgressToken>,
 4039    pub worktree: Option<WorktreeId>,
 4040    pub binary: Option<LanguageServerBinary>,
 4041    pub configuration: Option<Value>,
 4042    pub workspace_folders: BTreeSet<Uri>,
 4043    pub process_id: Option<u32>,
 4044}
 4045
 4046#[derive(Clone, Debug)]
 4047struct CoreSymbol {
 4048    pub language_server_name: LanguageServerName,
 4049    pub source_worktree_id: WorktreeId,
 4050    pub source_language_server_id: LanguageServerId,
 4051    pub path: SymbolLocation,
 4052    pub name: String,
 4053    pub kind: lsp::SymbolKind,
 4054    pub range: Range<Unclipped<PointUtf16>>,
 4055    pub container_name: Option<String>,
 4056}
 4057
 4058#[derive(Clone, Debug, PartialEq, Eq)]
 4059pub enum SymbolLocation {
 4060    InProject(ProjectPath),
 4061    OutsideProject {
 4062        abs_path: Arc<Path>,
 4063        signature: [u8; 32],
 4064    },
 4065}
 4066
 4067impl SymbolLocation {
 4068    fn file_name(&self) -> Option<&str> {
 4069        match self {
 4070            Self::InProject(path) => path.path.file_name(),
 4071            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4072        }
 4073    }
 4074}
 4075
 4076impl LspStore {
 4077    pub fn init(client: &AnyProtoClient) {
 4078        client.add_entity_request_handler(Self::handle_lsp_query);
 4079        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4080        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4081        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4082        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4083        client.add_entity_message_handler(Self::handle_start_language_server);
 4084        client.add_entity_message_handler(Self::handle_update_language_server);
 4085        client.add_entity_message_handler(Self::handle_language_server_log);
 4086        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4087        client.add_entity_request_handler(Self::handle_format_buffers);
 4088        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4089        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4090        client.add_entity_request_handler(Self::handle_apply_code_action);
 4091        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4092        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4093        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4094        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4095        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4096        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4097        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4098        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4099        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4100        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4101        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4102        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4103        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4104        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4105        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4106        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4107        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4108        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4109
 4110        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4111        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4112        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4113        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4114        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4115        client.add_entity_request_handler(
 4116            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4117        );
 4118        client.add_entity_request_handler(
 4119            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4120        );
 4121        client.add_entity_request_handler(
 4122            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4123        );
 4124    }
 4125
 4126    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4127        match &self.mode {
 4128            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4129            _ => None,
 4130        }
 4131    }
 4132
 4133    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4134        match &self.mode {
 4135            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4136            _ => None,
 4137        }
 4138    }
 4139
 4140    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4141        match &mut self.mode {
 4142            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4143            _ => None,
 4144        }
 4145    }
 4146
 4147    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4148        match &self.mode {
 4149            LspStoreMode::Remote(RemoteLspStore {
 4150                upstream_client: Some(upstream_client),
 4151                upstream_project_id,
 4152                ..
 4153            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4154
 4155            LspStoreMode::Remote(RemoteLspStore {
 4156                upstream_client: None,
 4157                ..
 4158            }) => None,
 4159            LspStoreMode::Local(_) => None,
 4160        }
 4161    }
 4162
 4163    fn shutdown_language_servers(&mut self, cx: &mut App) {
 4164        if let Some(local) = self.as_local_mut() {
 4165            let shutdown_futures: Vec<_> = local
 4166                .language_servers
 4167                .drain()
 4168                .map(|(_, server_state)| LocalLspStore::shutdown_server(server_state))
 4169                .collect();
 4170
 4171            let supplementary_shutdown_futures: Vec<_> = local
 4172                .supplementary_language_servers
 4173                .drain()
 4174                .filter_map(|(_, (_, server))| server.shutdown())
 4175                .collect();
 4176
 4177            cx.background_spawn(async move {
 4178                join_all(shutdown_futures).await;
 4179                join_all(supplementary_shutdown_futures).await;
 4180            })
 4181            .detach();
 4182        }
 4183    }
 4184
 4185    pub fn new_local(
 4186        buffer_store: Entity<BufferStore>,
 4187        worktree_store: Entity<WorktreeStore>,
 4188        prettier_store: Entity<PrettierStore>,
 4189        toolchain_store: Entity<LocalToolchainStore>,
 4190        environment: Entity<ProjectEnvironment>,
 4191        manifest_tree: Entity<ManifestTree>,
 4192        languages: Arc<LanguageRegistry>,
 4193        http_client: Arc<dyn HttpClient>,
 4194        fs: Arc<dyn Fs>,
 4195        cx: &mut Context<Self>,
 4196    ) -> Self {
 4197        let yarn = YarnPathStore::new(fs.clone(), cx);
 4198        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4199            .detach();
 4200        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4201            .detach();
 4202        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4203            .detach();
 4204        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4205            .detach();
 4206        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4207            .detach();
 4208        subscribe_to_binary_statuses(&languages, cx).detach();
 4209
 4210        let _maintain_workspace_config = {
 4211            let (sender, receiver) = watch::channel();
 4212            (Self::maintain_workspace_config(receiver, cx), sender)
 4213        };
 4214
 4215        Self {
 4216            mode: LspStoreMode::Local(LocalLspStore {
 4217                weak: cx.weak_entity(),
 4218                worktree_store: worktree_store.clone(),
 4219
 4220                supplementary_language_servers: Default::default(),
 4221                languages: languages.clone(),
 4222                language_server_ids: Default::default(),
 4223                language_servers: Default::default(),
 4224                last_workspace_edits_by_language_server: Default::default(),
 4225                language_server_watched_paths: Default::default(),
 4226                language_server_paths_watched_for_rename: Default::default(),
 4227                language_server_dynamic_registrations: Default::default(),
 4228                buffers_being_formatted: Default::default(),
 4229                buffers_to_refresh_hash_set: HashSet::default(),
 4230                buffers_to_refresh_queue: VecDeque::new(),
 4231                _background_diagnostics_worker: Task::ready(()).shared(),
 4232                buffer_snapshots: Default::default(),
 4233                prettier_store,
 4234                environment,
 4235                http_client,
 4236                fs,
 4237                yarn,
 4238                next_diagnostic_group_id: Default::default(),
 4239                diagnostics: Default::default(),
 4240                _subscriptions: vec![
 4241                    cx.on_app_quit(|this, _| {
 4242                        this.as_local_mut()
 4243                            .unwrap()
 4244                            .shutdown_language_servers_on_quit()
 4245                    }),
 4246                    cx.on_release(Self::shutdown_language_servers),
 4247                ],
 4248                lsp_tree: LanguageServerTree::new(
 4249                    manifest_tree,
 4250                    languages.clone(),
 4251                    toolchain_store.clone(),
 4252                ),
 4253                toolchain_store,
 4254                registered_buffers: HashMap::default(),
 4255                buffers_opened_in_servers: HashMap::default(),
 4256                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4257                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4258                restricted_worktrees_tasks: HashMap::default(),
 4259                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4260                    .manifest_file_names(),
 4261            }),
 4262            last_formatting_failure: None,
 4263            downstream_client: None,
 4264            buffer_store,
 4265            worktree_store,
 4266            languages: languages.clone(),
 4267            language_server_statuses: Default::default(),
 4268            nonce: StdRng::from_os_rng().random(),
 4269            diagnostic_summaries: HashMap::default(),
 4270            lsp_server_capabilities: HashMap::default(),
 4271            semantic_token_config: SemanticTokenConfig::new(cx),
 4272            lsp_data: HashMap::default(),
 4273            next_hint_id: Arc::default(),
 4274            active_entry: None,
 4275            _maintain_workspace_config,
 4276            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4277        }
 4278    }
 4279
 4280    fn send_lsp_proto_request<R: LspCommand>(
 4281        &self,
 4282        buffer: Entity<Buffer>,
 4283        client: AnyProtoClient,
 4284        upstream_project_id: u64,
 4285        request: R,
 4286        cx: &mut Context<LspStore>,
 4287    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4288        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4289            return Task::ready(Ok(R::Response::default()));
 4290        }
 4291        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4292        cx.spawn(async move |this, cx| {
 4293            let response = client.request(message).await?;
 4294            let this = this.upgrade().context("project dropped")?;
 4295            request
 4296                .response_from_proto(response, this, buffer, cx.clone())
 4297                .await
 4298        })
 4299    }
 4300
 4301    pub(super) fn new_remote(
 4302        buffer_store: Entity<BufferStore>,
 4303        worktree_store: Entity<WorktreeStore>,
 4304        languages: Arc<LanguageRegistry>,
 4305        upstream_client: AnyProtoClient,
 4306        project_id: u64,
 4307        cx: &mut Context<Self>,
 4308    ) -> Self {
 4309        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4310            .detach();
 4311        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4312            .detach();
 4313        subscribe_to_binary_statuses(&languages, cx).detach();
 4314        let _maintain_workspace_config = {
 4315            let (sender, receiver) = watch::channel();
 4316            (Self::maintain_workspace_config(receiver, cx), sender)
 4317        };
 4318        Self {
 4319            mode: LspStoreMode::Remote(RemoteLspStore {
 4320                upstream_client: Some(upstream_client),
 4321                upstream_project_id: project_id,
 4322            }),
 4323            downstream_client: None,
 4324            last_formatting_failure: None,
 4325            buffer_store,
 4326            worktree_store,
 4327            languages: languages.clone(),
 4328            language_server_statuses: Default::default(),
 4329            nonce: StdRng::from_os_rng().random(),
 4330            diagnostic_summaries: HashMap::default(),
 4331            lsp_server_capabilities: HashMap::default(),
 4332            semantic_token_config: SemanticTokenConfig::new(cx),
 4333            next_hint_id: Arc::default(),
 4334            lsp_data: HashMap::default(),
 4335            active_entry: None,
 4336
 4337            _maintain_workspace_config,
 4338            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4339        }
 4340    }
 4341
 4342    fn on_buffer_store_event(
 4343        &mut self,
 4344        _: Entity<BufferStore>,
 4345        event: &BufferStoreEvent,
 4346        cx: &mut Context<Self>,
 4347    ) {
 4348        match event {
 4349            BufferStoreEvent::BufferAdded(buffer) => {
 4350                self.on_buffer_added(buffer, cx).log_err();
 4351            }
 4352            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4353                let buffer_id = buffer.read(cx).remote_id();
 4354                if let Some(local) = self.as_local_mut()
 4355                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4356                {
 4357                    local.reset_buffer(buffer, old_file, cx);
 4358
 4359                    if local.registered_buffers.contains_key(&buffer_id) {
 4360                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4361                    }
 4362                }
 4363
 4364                self.detect_language_for_buffer(buffer, cx);
 4365                if let Some(local) = self.as_local_mut() {
 4366                    local.initialize_buffer(buffer, cx);
 4367                    if local.registered_buffers.contains_key(&buffer_id) {
 4368                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4369                    }
 4370                }
 4371            }
 4372            _ => {}
 4373        }
 4374    }
 4375
 4376    fn on_worktree_store_event(
 4377        &mut self,
 4378        _: Entity<WorktreeStore>,
 4379        event: &WorktreeStoreEvent,
 4380        cx: &mut Context<Self>,
 4381    ) {
 4382        match event {
 4383            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4384                if !worktree.read(cx).is_local() {
 4385                    return;
 4386                }
 4387                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4388                    worktree::Event::UpdatedEntries(changes) => {
 4389                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4390                    }
 4391                    worktree::Event::UpdatedGitRepositories(_)
 4392                    | worktree::Event::DeletedEntry(_) => {}
 4393                })
 4394                .detach()
 4395            }
 4396            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4397            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4398                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4399            }
 4400            WorktreeStoreEvent::WorktreeReleased(..)
 4401            | WorktreeStoreEvent::WorktreeOrderChanged
 4402            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4403            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4404            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4405        }
 4406    }
 4407
 4408    fn on_prettier_store_event(
 4409        &mut self,
 4410        _: Entity<PrettierStore>,
 4411        event: &PrettierStoreEvent,
 4412        cx: &mut Context<Self>,
 4413    ) {
 4414        match event {
 4415            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4416                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4417            }
 4418            PrettierStoreEvent::LanguageServerAdded {
 4419                new_server_id,
 4420                name,
 4421                prettier_server,
 4422            } => {
 4423                self.register_supplementary_language_server(
 4424                    *new_server_id,
 4425                    name.clone(),
 4426                    prettier_server.clone(),
 4427                    cx,
 4428                );
 4429            }
 4430        }
 4431    }
 4432
 4433    fn on_toolchain_store_event(
 4434        &mut self,
 4435        _: Entity<LocalToolchainStore>,
 4436        event: &ToolchainStoreEvent,
 4437        _: &mut Context<Self>,
 4438    ) {
 4439        if let ToolchainStoreEvent::ToolchainActivated = event {
 4440            self.request_workspace_config_refresh()
 4441        }
 4442    }
 4443
 4444    fn request_workspace_config_refresh(&mut self) {
 4445        *self._maintain_workspace_config.1.borrow_mut() = ();
 4446    }
 4447
 4448    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4449        self.as_local().map(|local| local.prettier_store.clone())
 4450    }
 4451
 4452    fn on_buffer_event(
 4453        &mut self,
 4454        buffer: Entity<Buffer>,
 4455        event: &language::BufferEvent,
 4456        cx: &mut Context<Self>,
 4457    ) {
 4458        match event {
 4459            language::BufferEvent::Edited { .. } => {
 4460                self.on_buffer_edited(buffer, cx);
 4461            }
 4462
 4463            language::BufferEvent::Saved => {
 4464                self.on_buffer_saved(buffer, cx);
 4465            }
 4466
 4467            _ => {}
 4468        }
 4469    }
 4470
 4471    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4472        buffer
 4473            .read(cx)
 4474            .set_language_registry(self.languages.clone());
 4475
 4476        cx.subscribe(buffer, |this, buffer, event, cx| {
 4477            this.on_buffer_event(buffer, event, cx);
 4478        })
 4479        .detach();
 4480
 4481        self.detect_language_for_buffer(buffer, cx);
 4482        if let Some(local) = self.as_local_mut() {
 4483            local.initialize_buffer(buffer, cx);
 4484        }
 4485
 4486        Ok(())
 4487    }
 4488
 4489    pub fn refresh_background_diagnostics_for_buffers(
 4490        &mut self,
 4491        buffers: HashSet<BufferId>,
 4492        cx: &mut Context<Self>,
 4493    ) -> Shared<Task<()>> {
 4494        let Some(local) = self.as_local_mut() else {
 4495            return Task::ready(()).shared();
 4496        };
 4497        for buffer in buffers {
 4498            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4499                local.buffers_to_refresh_queue.push_back(buffer);
 4500                if local.buffers_to_refresh_queue.len() == 1 {
 4501                    local._background_diagnostics_worker =
 4502                        Self::background_diagnostics_worker(cx).shared();
 4503                }
 4504            }
 4505        }
 4506
 4507        local._background_diagnostics_worker.clone()
 4508    }
 4509
 4510    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4511        let buffer_store = self.buffer_store.clone();
 4512        let local = self.as_local_mut()?;
 4513        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4514            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4515            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4516                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4517            }
 4518        }
 4519        None
 4520    }
 4521
 4522    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4523        cx.spawn(async move |this, cx| {
 4524            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4525                task.await.log_err();
 4526            }
 4527        })
 4528    }
 4529
 4530    pub(crate) fn register_buffer_with_language_servers(
 4531        &mut self,
 4532        buffer: &Entity<Buffer>,
 4533        only_register_servers: HashSet<LanguageServerSelector>,
 4534        ignore_refcounts: bool,
 4535        cx: &mut Context<Self>,
 4536    ) -> OpenLspBufferHandle {
 4537        let buffer_id = buffer.read(cx).remote_id();
 4538        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4539        if let Some(local) = self.as_local_mut() {
 4540            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4541            if !ignore_refcounts {
 4542                *refcount += 1;
 4543            }
 4544
 4545            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4546            // 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
 4547            // 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
 4548            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4549            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4550                return handle;
 4551            };
 4552            if !file.is_local() {
 4553                return handle;
 4554            }
 4555
 4556            if ignore_refcounts || *refcount == 1 {
 4557                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4558            }
 4559            if !ignore_refcounts {
 4560                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4561                    let refcount = {
 4562                        let local = lsp_store.as_local_mut().unwrap();
 4563                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4564                            debug_panic!("bad refcounting");
 4565                            return;
 4566                        };
 4567
 4568                        *refcount -= 1;
 4569                        *refcount
 4570                    };
 4571                    if refcount == 0 {
 4572                        lsp_store.lsp_data.remove(&buffer_id);
 4573                        let local = lsp_store.as_local_mut().unwrap();
 4574                        local.registered_buffers.remove(&buffer_id);
 4575
 4576                        local.buffers_opened_in_servers.remove(&buffer_id);
 4577                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4578                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4579
 4580                            let buffer_abs_path = file.abs_path(cx);
 4581                            for (_, buffer_pull_diagnostics_result_ids) in
 4582                                &mut local.buffer_pull_diagnostics_result_ids
 4583                            {
 4584                                buffer_pull_diagnostics_result_ids.retain(
 4585                                    |_, buffer_result_ids| {
 4586                                        buffer_result_ids.remove(&buffer_abs_path);
 4587                                        !buffer_result_ids.is_empty()
 4588                                    },
 4589                                );
 4590                            }
 4591
 4592                            let diagnostic_updates = local
 4593                                .language_servers
 4594                                .keys()
 4595                                .cloned()
 4596                                .map(|server_id| DocumentDiagnosticsUpdate {
 4597                                    diagnostics: DocumentDiagnostics {
 4598                                        document_abs_path: buffer_abs_path.clone(),
 4599                                        version: None,
 4600                                        diagnostics: Vec::new(),
 4601                                    },
 4602                                    result_id: None,
 4603                                    registration_id: None,
 4604                                    server_id,
 4605                                    disk_based_sources: Cow::Borrowed(&[]),
 4606                                })
 4607                                .collect::<Vec<_>>();
 4608
 4609                            lsp_store
 4610                                .merge_diagnostic_entries(
 4611                                    diagnostic_updates,
 4612                                    |_, diagnostic, _| {
 4613                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4614                                    },
 4615                                    cx,
 4616                                )
 4617                                .context("Clearing diagnostics for the closed buffer")
 4618                                .log_err();
 4619                        }
 4620                    }
 4621                })
 4622                .detach();
 4623            }
 4624        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4625            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4626            cx.background_spawn(async move {
 4627                upstream_client
 4628                    .request(proto::RegisterBufferWithLanguageServers {
 4629                        project_id: upstream_project_id,
 4630                        buffer_id,
 4631                        only_servers: only_register_servers
 4632                            .into_iter()
 4633                            .map(|selector| {
 4634                                let selector = match selector {
 4635                                    LanguageServerSelector::Id(language_server_id) => {
 4636                                        proto::language_server_selector::Selector::ServerId(
 4637                                            language_server_id.to_proto(),
 4638                                        )
 4639                                    }
 4640                                    LanguageServerSelector::Name(language_server_name) => {
 4641                                        proto::language_server_selector::Selector::Name(
 4642                                            language_server_name.to_string(),
 4643                                        )
 4644                                    }
 4645                                };
 4646                                proto::LanguageServerSelector {
 4647                                    selector: Some(selector),
 4648                                }
 4649                            })
 4650                            .collect(),
 4651                    })
 4652                    .await
 4653            })
 4654            .detach();
 4655        } else {
 4656            // Our remote connection got closed
 4657        }
 4658        handle
 4659    }
 4660
 4661    fn maintain_buffer_languages(
 4662        languages: Arc<LanguageRegistry>,
 4663        cx: &mut Context<Self>,
 4664    ) -> Task<()> {
 4665        let mut subscription = languages.subscribe();
 4666        let mut prev_reload_count = languages.reload_count();
 4667        cx.spawn(async move |this, cx| {
 4668            while let Some(()) = subscription.next().await {
 4669                if let Some(this) = this.upgrade() {
 4670                    // If the language registry has been reloaded, then remove and
 4671                    // re-assign the languages on all open buffers.
 4672                    let reload_count = languages.reload_count();
 4673                    if reload_count > prev_reload_count {
 4674                        prev_reload_count = reload_count;
 4675                        this.update(cx, |this, cx| {
 4676                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4677                                for buffer in buffer_store.buffers() {
 4678                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4679                                    {
 4680                                        buffer.update(cx, |buffer, cx| {
 4681                                            buffer.set_language_async(None, cx)
 4682                                        });
 4683                                        if let Some(local) = this.as_local_mut() {
 4684                                            local.reset_buffer(&buffer, &f, cx);
 4685
 4686                                            if local
 4687                                                .registered_buffers
 4688                                                .contains_key(&buffer.read(cx).remote_id())
 4689                                                && let Some(file_url) =
 4690                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4691                                            {
 4692                                                local.unregister_buffer_from_language_servers(
 4693                                                    &buffer, &file_url, cx,
 4694                                                );
 4695                                            }
 4696                                        }
 4697                                    }
 4698                                }
 4699                            });
 4700                        });
 4701                    }
 4702
 4703                    this.update(cx, |this, cx| {
 4704                        let mut plain_text_buffers = Vec::new();
 4705                        let mut buffers_with_unknown_injections = Vec::new();
 4706                        for handle in this.buffer_store.read(cx).buffers() {
 4707                            let buffer = handle.read(cx);
 4708                            if buffer.language().is_none()
 4709                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4710                            {
 4711                                plain_text_buffers.push(handle);
 4712                            } else if buffer.contains_unknown_injections() {
 4713                                buffers_with_unknown_injections.push(handle);
 4714                            }
 4715                        }
 4716
 4717                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4718                        // and reused later in the invisible worktrees.
 4719                        plain_text_buffers.sort_by_key(|buffer| {
 4720                            Reverse(
 4721                                File::from_dyn(buffer.read(cx).file())
 4722                                    .map(|file| file.worktree.read(cx).is_visible()),
 4723                            )
 4724                        });
 4725
 4726                        for buffer in plain_text_buffers {
 4727                            this.detect_language_for_buffer(&buffer, cx);
 4728                            if let Some(local) = this.as_local_mut() {
 4729                                local.initialize_buffer(&buffer, cx);
 4730                                if local
 4731                                    .registered_buffers
 4732                                    .contains_key(&buffer.read(cx).remote_id())
 4733                                {
 4734                                    local.register_buffer_with_language_servers(
 4735                                        &buffer,
 4736                                        HashSet::default(),
 4737                                        cx,
 4738                                    );
 4739                                }
 4740                            }
 4741                        }
 4742
 4743                        for buffer in buffers_with_unknown_injections {
 4744                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4745                        }
 4746                    });
 4747                }
 4748            }
 4749        })
 4750    }
 4751
 4752    fn detect_language_for_buffer(
 4753        &mut self,
 4754        buffer_handle: &Entity<Buffer>,
 4755        cx: &mut Context<Self>,
 4756    ) -> Option<language::AvailableLanguage> {
 4757        // If the buffer has a language, set it and start the language server if we haven't already.
 4758        let buffer = buffer_handle.read(cx);
 4759        let file = buffer.file()?;
 4760
 4761        let content = buffer.as_rope();
 4762        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4763        if let Some(available_language) = &available_language {
 4764            if let Some(Ok(Ok(new_language))) = self
 4765                .languages
 4766                .load_language(available_language)
 4767                .now_or_never()
 4768            {
 4769                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4770            }
 4771        } else {
 4772            cx.emit(LspStoreEvent::LanguageDetected {
 4773                buffer: buffer_handle.clone(),
 4774                new_language: None,
 4775            });
 4776        }
 4777
 4778        available_language
 4779    }
 4780
 4781    pub(crate) fn set_language_for_buffer(
 4782        &mut self,
 4783        buffer_entity: &Entity<Buffer>,
 4784        new_language: Arc<Language>,
 4785        cx: &mut Context<Self>,
 4786    ) {
 4787        let buffer = buffer_entity.read(cx);
 4788        let buffer_file = buffer.file().cloned();
 4789        let buffer_id = buffer.remote_id();
 4790        if let Some(local_store) = self.as_local_mut()
 4791            && local_store.registered_buffers.contains_key(&buffer_id)
 4792            && let Some(abs_path) =
 4793                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4794            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4795        {
 4796            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4797        }
 4798        buffer_entity.update(cx, |buffer, cx| {
 4799            if buffer
 4800                .language()
 4801                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4802            {
 4803                buffer.set_language_async(Some(new_language.clone()), cx);
 4804            }
 4805        });
 4806
 4807        let settings =
 4808            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4809        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4810
 4811        let worktree_id = if let Some(file) = buffer_file {
 4812            let worktree = file.worktree.clone();
 4813
 4814            if let Some(local) = self.as_local_mut()
 4815                && local.registered_buffers.contains_key(&buffer_id)
 4816            {
 4817                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4818            }
 4819            Some(worktree.read(cx).id())
 4820        } else {
 4821            None
 4822        };
 4823
 4824        if settings.prettier.allowed
 4825            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4826        {
 4827            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4828            if let Some(prettier_store) = prettier_store {
 4829                prettier_store.update(cx, |prettier_store, cx| {
 4830                    prettier_store.install_default_prettier(
 4831                        worktree_id,
 4832                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4833                        cx,
 4834                    )
 4835                })
 4836            }
 4837        }
 4838
 4839        cx.emit(LspStoreEvent::LanguageDetected {
 4840            buffer: buffer_entity.clone(),
 4841            new_language: Some(new_language),
 4842        })
 4843    }
 4844
 4845    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4846        self.buffer_store.clone()
 4847    }
 4848
 4849    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4850        self.active_entry = active_entry;
 4851    }
 4852
 4853    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4854        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4855            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4856        {
 4857            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4858                summaries
 4859                    .iter()
 4860                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4861            });
 4862            if let Some(summary) = summaries.next() {
 4863                client
 4864                    .send(proto::UpdateDiagnosticSummary {
 4865                        project_id: downstream_project_id,
 4866                        worktree_id: worktree.id().to_proto(),
 4867                        summary: Some(summary),
 4868                        more_summaries: summaries.collect(),
 4869                    })
 4870                    .log_err();
 4871            }
 4872        }
 4873    }
 4874
 4875    fn is_capable_for_proto_request<R>(
 4876        &self,
 4877        buffer: &Entity<Buffer>,
 4878        request: &R,
 4879        cx: &App,
 4880    ) -> bool
 4881    where
 4882        R: LspCommand,
 4883    {
 4884        self.check_if_capable_for_proto_request(
 4885            buffer,
 4886            |capabilities| {
 4887                request.check_capabilities(AdapterServerCapabilities {
 4888                    server_capabilities: capabilities.clone(),
 4889                    code_action_kinds: None,
 4890                })
 4891            },
 4892            cx,
 4893        )
 4894    }
 4895
 4896    fn check_if_capable_for_proto_request<F>(
 4897        &self,
 4898        buffer: &Entity<Buffer>,
 4899        check: F,
 4900        cx: &App,
 4901    ) -> bool
 4902    where
 4903        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4904    {
 4905        let Some(language) = buffer.read(cx).language().cloned() else {
 4906            return false;
 4907        };
 4908        let registered_language_servers = self
 4909            .languages
 4910            .lsp_adapters(&language.name())
 4911            .into_iter()
 4912            .map(|lsp_adapter| lsp_adapter.name())
 4913            .collect::<HashSet<_>>();
 4914        self.language_server_statuses
 4915            .iter()
 4916            .filter_map(|(server_id, server_status)| {
 4917                // Include servers that are either registered for this language OR
 4918                // available to be loaded (for SSH remote mode where adapters like
 4919                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4920                // but only loaded on the server side)
 4921                let is_relevant = registered_language_servers.contains(&server_status.name)
 4922                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4923                is_relevant.then_some(server_id)
 4924            })
 4925            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4926            .any(check)
 4927    }
 4928
 4929    fn all_capable_for_proto_request<F>(
 4930        &self,
 4931        buffer: &Entity<Buffer>,
 4932        mut check: F,
 4933        cx: &App,
 4934    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 4935    where
 4936        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4937    {
 4938        let Some(language) = buffer.read(cx).language().cloned() else {
 4939            return Vec::default();
 4940        };
 4941        let registered_language_servers = self
 4942            .languages
 4943            .lsp_adapters(&language.name())
 4944            .into_iter()
 4945            .map(|lsp_adapter| lsp_adapter.name())
 4946            .collect::<HashSet<_>>();
 4947        self.language_server_statuses
 4948            .iter()
 4949            .filter_map(|(server_id, server_status)| {
 4950                // Include servers that are either registered for this language OR
 4951                // available to be loaded (for SSH remote mode where adapters like
 4952                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4953                // but only loaded on the server side)
 4954                let is_relevant = registered_language_servers.contains(&server_status.name)
 4955                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4956                is_relevant.then_some((server_id, &server_status.name))
 4957            })
 4958            .filter_map(|(server_id, server_name)| {
 4959                self.lsp_server_capabilities
 4960                    .get(server_id)
 4961                    .map(|c| (server_id, server_name, c))
 4962            })
 4963            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4964            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 4965            .collect()
 4966    }
 4967
 4968    pub fn request_lsp<R>(
 4969        &mut self,
 4970        buffer: Entity<Buffer>,
 4971        server: LanguageServerToQuery,
 4972        request: R,
 4973        cx: &mut Context<Self>,
 4974    ) -> Task<Result<R::Response>>
 4975    where
 4976        R: LspCommand,
 4977        <R::LspRequest as lsp::request::Request>::Result: Send,
 4978        <R::LspRequest as lsp::request::Request>::Params: Send,
 4979    {
 4980        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4981            return self.send_lsp_proto_request(
 4982                buffer,
 4983                upstream_client,
 4984                upstream_project_id,
 4985                request,
 4986                cx,
 4987            );
 4988        }
 4989
 4990        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4991            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4992                local
 4993                    .language_servers_for_buffer(buffer, cx)
 4994                    .find(|(_, server)| {
 4995                        request.check_capabilities(server.adapter_server_capabilities())
 4996                    })
 4997                    .map(|(_, server)| server.clone())
 4998            }),
 4999            LanguageServerToQuery::Other(id) => self
 5000                .language_server_for_local_buffer(buffer, id, cx)
 5001                .and_then(|(_, server)| {
 5002                    request
 5003                        .check_capabilities(server.adapter_server_capabilities())
 5004                        .then(|| Arc::clone(server))
 5005                }),
 5006        }) else {
 5007            return Task::ready(Ok(Default::default()));
 5008        };
 5009
 5010        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5011
 5012        let Some(file) = file else {
 5013            return Task::ready(Ok(Default::default()));
 5014        };
 5015
 5016        let lsp_params = match request.to_lsp_params_or_response(
 5017            &file.abs_path(cx),
 5018            buffer.read(cx),
 5019            &language_server,
 5020            cx,
 5021        ) {
 5022            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5023            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5024            Err(err) => {
 5025                let message = format!(
 5026                    "{} via {} failed: {}",
 5027                    request.display_name(),
 5028                    language_server.name(),
 5029                    err
 5030                );
 5031                // rust-analyzer likes to error with this when its still loading up
 5032                if !message.ends_with("content modified") {
 5033                    log::warn!("{message}");
 5034                }
 5035                return Task::ready(Err(anyhow!(message)));
 5036            }
 5037        };
 5038
 5039        let status = request.status();
 5040        let request_timeout = ProjectSettings::get_global(cx)
 5041            .global_lsp_settings
 5042            .get_request_timeout();
 5043
 5044        cx.spawn(async move |this, cx| {
 5045            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5046
 5047            let id = lsp_request.id();
 5048            let _cleanup = if status.is_some() {
 5049                cx.update(|cx| {
 5050                    this.update(cx, |this, cx| {
 5051                        this.on_lsp_work_start(
 5052                            language_server.server_id(),
 5053                            ProgressToken::Number(id),
 5054                            LanguageServerProgress {
 5055                                is_disk_based_diagnostics_progress: false,
 5056                                is_cancellable: false,
 5057                                title: None,
 5058                                message: status.clone(),
 5059                                percentage: None,
 5060                                last_update_at: cx.background_executor().now(),
 5061                            },
 5062                            cx,
 5063                        );
 5064                    })
 5065                })
 5066                .log_err();
 5067
 5068                Some(defer(|| {
 5069                    cx.update(|cx| {
 5070                        this.update(cx, |this, cx| {
 5071                            this.on_lsp_work_end(
 5072                                language_server.server_id(),
 5073                                ProgressToken::Number(id),
 5074                                cx,
 5075                            );
 5076                        })
 5077                    })
 5078                    .log_err();
 5079                }))
 5080            } else {
 5081                None
 5082            };
 5083
 5084            let result = lsp_request.await.into_response();
 5085
 5086            let response = result.map_err(|err| {
 5087                let message = format!(
 5088                    "{} via {} failed: {}",
 5089                    request.display_name(),
 5090                    language_server.name(),
 5091                    err
 5092                );
 5093                // rust-analyzer likes to error with this when its still loading up
 5094                if !message.ends_with("content modified") {
 5095                    log::warn!("{message}");
 5096                }
 5097                anyhow::anyhow!(message)
 5098            })?;
 5099
 5100            request
 5101                .response_from_lsp(
 5102                    response,
 5103                    this.upgrade().context("no app context")?,
 5104                    buffer,
 5105                    language_server.server_id(),
 5106                    cx.clone(),
 5107                )
 5108                .await
 5109        })
 5110    }
 5111
 5112    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5113        let mut language_formatters_to_check = Vec::new();
 5114        for buffer in self.buffer_store.read(cx).buffers() {
 5115            let buffer = buffer.read(cx);
 5116            let buffer_file = File::from_dyn(buffer.file());
 5117            let buffer_language = buffer.language();
 5118            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 5119            if buffer_language.is_some() {
 5120                language_formatters_to_check.push((
 5121                    buffer_file.map(|f| f.worktree_id(cx)),
 5122                    settings.into_owned(),
 5123                ));
 5124            }
 5125        }
 5126
 5127        self.request_workspace_config_refresh();
 5128
 5129        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5130            prettier_store.update(cx, |prettier_store, cx| {
 5131                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5132            })
 5133        }
 5134
 5135        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5136            .global_lsp_settings
 5137            .semantic_token_rules
 5138            .clone();
 5139        self.semantic_token_config
 5140            .update_rules(new_semantic_token_rules);
 5141        // Always clear cached stylizers so that changes to language-specific
 5142        // semantic token rules (e.g. from extension install/uninstall) are
 5143        // picked up. Stylizers are recreated lazily, so this is cheap.
 5144        self.semantic_token_config.clear_stylizers();
 5145
 5146        let new_global_semantic_tokens_mode =
 5147            all_language_settings(None, cx).defaults.semantic_tokens;
 5148        if self
 5149            .semantic_token_config
 5150            .update_global_mode(new_global_semantic_tokens_mode)
 5151        {
 5152            self.restart_all_language_servers(cx);
 5153        }
 5154
 5155        cx.notify();
 5156    }
 5157
 5158    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5159        let buffer_store = self.buffer_store.clone();
 5160        let Some(local) = self.as_local_mut() else {
 5161            return;
 5162        };
 5163        let mut adapters = BTreeMap::default();
 5164        let get_adapter = {
 5165            let languages = local.languages.clone();
 5166            let environment = local.environment.clone();
 5167            let weak = local.weak.clone();
 5168            let worktree_store = local.worktree_store.clone();
 5169            let http_client = local.http_client.clone();
 5170            let fs = local.fs.clone();
 5171            move |worktree_id, cx: &mut App| {
 5172                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5173                Some(LocalLspAdapterDelegate::new(
 5174                    languages.clone(),
 5175                    &environment,
 5176                    weak.clone(),
 5177                    &worktree,
 5178                    http_client.clone(),
 5179                    fs.clone(),
 5180                    cx,
 5181                ))
 5182            }
 5183        };
 5184
 5185        let mut messages_to_report = Vec::new();
 5186        let (new_tree, to_stop) = {
 5187            let mut rebase = local.lsp_tree.rebase();
 5188            let buffers = buffer_store
 5189                .read(cx)
 5190                .buffers()
 5191                .filter_map(|buffer| {
 5192                    let raw_buffer = buffer.read(cx);
 5193                    if !local
 5194                        .registered_buffers
 5195                        .contains_key(&raw_buffer.remote_id())
 5196                    {
 5197                        return None;
 5198                    }
 5199                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5200                    let language = raw_buffer.language().cloned()?;
 5201                    Some((file, language, raw_buffer.remote_id()))
 5202                })
 5203                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5204            for (file, language, buffer_id) in buffers {
 5205                let worktree_id = file.worktree_id(cx);
 5206                let Some(worktree) = local
 5207                    .worktree_store
 5208                    .read(cx)
 5209                    .worktree_for_id(worktree_id, cx)
 5210                else {
 5211                    continue;
 5212                };
 5213
 5214                if let Some((_, apply)) = local.reuse_existing_language_server(
 5215                    rebase.server_tree(),
 5216                    &worktree,
 5217                    &language.name(),
 5218                    cx,
 5219                ) {
 5220                    (apply)(rebase.server_tree());
 5221                } else if let Some(lsp_delegate) = adapters
 5222                    .entry(worktree_id)
 5223                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5224                    .clone()
 5225                {
 5226                    let delegate =
 5227                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5228                    let path = file
 5229                        .path()
 5230                        .parent()
 5231                        .map(Arc::from)
 5232                        .unwrap_or_else(|| file.path().clone());
 5233                    let worktree_path = ProjectPath { worktree_id, path };
 5234                    let abs_path = file.abs_path(cx);
 5235                    let nodes = rebase
 5236                        .walk(
 5237                            worktree_path,
 5238                            language.name(),
 5239                            language.manifest(),
 5240                            delegate.clone(),
 5241                            cx,
 5242                        )
 5243                        .collect::<Vec<_>>();
 5244                    for node in nodes {
 5245                        let server_id = node.server_id_or_init(|disposition| {
 5246                            let path = &disposition.path;
 5247                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5248                            let key = LanguageServerSeed {
 5249                                worktree_id,
 5250                                name: disposition.server_name.clone(),
 5251                                settings: LanguageServerSeedSettings {
 5252                                    binary: disposition.settings.binary.clone(),
 5253                                    initialization_options: disposition
 5254                                        .settings
 5255                                        .initialization_options
 5256                                        .clone(),
 5257                                },
 5258                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5259                                    path.worktree_id,
 5260                                    &path.path,
 5261                                    language.name(),
 5262                                ),
 5263                            };
 5264                            local.language_server_ids.remove(&key);
 5265
 5266                            let server_id = local.get_or_insert_language_server(
 5267                                &worktree,
 5268                                lsp_delegate.clone(),
 5269                                disposition,
 5270                                &language.name(),
 5271                                cx,
 5272                            );
 5273                            if let Some(state) = local.language_servers.get(&server_id)
 5274                                && let Ok(uri) = uri
 5275                            {
 5276                                state.add_workspace_folder(uri);
 5277                            };
 5278                            server_id
 5279                        });
 5280
 5281                        if let Some(language_server_id) = server_id {
 5282                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5283                                language_server_id,
 5284                                name: node.name(),
 5285                                message:
 5286                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5287                                        proto::RegisteredForBuffer {
 5288                                            buffer_abs_path: abs_path
 5289                                                .to_string_lossy()
 5290                                                .into_owned(),
 5291                                            buffer_id: buffer_id.to_proto(),
 5292                                        },
 5293                                    ),
 5294                            });
 5295                        }
 5296                    }
 5297                } else {
 5298                    continue;
 5299                }
 5300            }
 5301            rebase.finish()
 5302        };
 5303        for message in messages_to_report {
 5304            cx.emit(message);
 5305        }
 5306        local.lsp_tree = new_tree;
 5307        for (id, _) in to_stop {
 5308            self.stop_local_language_server(id, cx).detach();
 5309        }
 5310    }
 5311
 5312    pub fn apply_code_action(
 5313        &self,
 5314        buffer_handle: Entity<Buffer>,
 5315        mut action: CodeAction,
 5316        push_to_history: bool,
 5317        cx: &mut Context<Self>,
 5318    ) -> Task<Result<ProjectTransaction>> {
 5319        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5320            let request = proto::ApplyCodeAction {
 5321                project_id,
 5322                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5323                action: Some(Self::serialize_code_action(&action)),
 5324            };
 5325            let buffer_store = self.buffer_store();
 5326            cx.spawn(async move |_, cx| {
 5327                let response = upstream_client
 5328                    .request(request)
 5329                    .await?
 5330                    .transaction
 5331                    .context("missing transaction")?;
 5332
 5333                buffer_store
 5334                    .update(cx, |buffer_store, cx| {
 5335                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5336                    })
 5337                    .await
 5338            })
 5339        } else if self.mode.is_local() {
 5340            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5341                let request_timeout = ProjectSettings::get_global(cx)
 5342                    .global_lsp_settings
 5343                    .get_request_timeout();
 5344                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5345                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5346            }) else {
 5347                return Task::ready(Ok(ProjectTransaction::default()));
 5348            };
 5349
 5350            cx.spawn(async move |this, cx| {
 5351                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5352                    .await
 5353                    .context("resolving a code action")?;
 5354                if let Some(edit) = action.lsp_action.edit()
 5355                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5356                        return LocalLspStore::deserialize_workspace_edit(
 5357                            this.upgrade().context("no app present")?,
 5358                            edit.clone(),
 5359                            push_to_history,
 5360
 5361                            lang_server.clone(),
 5362                            cx,
 5363                        )
 5364                        .await;
 5365                    }
 5366
 5367                let Some(command) = action.lsp_action.command() else {
 5368                    return Ok(ProjectTransaction::default())
 5369                };
 5370
 5371                let server_capabilities = lang_server.capabilities();
 5372                let available_commands = server_capabilities
 5373                    .execute_command_provider
 5374                    .as_ref()
 5375                    .map(|options| options.commands.as_slice())
 5376                    .unwrap_or_default();
 5377
 5378                if !available_commands.contains(&command.command) {
 5379                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5380                    return Ok(ProjectTransaction::default())
 5381                }
 5382
 5383                let request_timeout = cx.update(|app|
 5384                    ProjectSettings::get_global(app)
 5385                    .global_lsp_settings
 5386                    .get_request_timeout()
 5387                );
 5388
 5389                this.update(cx, |this, _| {
 5390                    this.as_local_mut()
 5391                        .unwrap()
 5392                        .last_workspace_edits_by_language_server
 5393                        .remove(&lang_server.server_id());
 5394                })?;
 5395
 5396                let _result = lang_server
 5397                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5398                        command: command.command.clone(),
 5399                        arguments: command.arguments.clone().unwrap_or_default(),
 5400                        ..lsp::ExecuteCommandParams::default()
 5401                    }, request_timeout)
 5402                    .await.into_response()
 5403                    .context("execute command")?;
 5404
 5405                return this.update(cx, |this, _| {
 5406                    this.as_local_mut()
 5407                        .unwrap()
 5408                        .last_workspace_edits_by_language_server
 5409                        .remove(&lang_server.server_id())
 5410                        .unwrap_or_default()
 5411                });
 5412            })
 5413        } else {
 5414            Task::ready(Err(anyhow!("no upstream client and not local")))
 5415        }
 5416    }
 5417
 5418    pub fn apply_code_action_kind(
 5419        &mut self,
 5420        buffers: HashSet<Entity<Buffer>>,
 5421        kind: CodeActionKind,
 5422        push_to_history: bool,
 5423        cx: &mut Context<Self>,
 5424    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5425        if self.as_local().is_some() {
 5426            cx.spawn(async move |lsp_store, cx| {
 5427                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5428                let result = LocalLspStore::execute_code_action_kind_locally(
 5429                    lsp_store.clone(),
 5430                    buffers,
 5431                    kind,
 5432                    push_to_history,
 5433                    cx,
 5434                )
 5435                .await;
 5436                lsp_store.update(cx, |lsp_store, _| {
 5437                    lsp_store.update_last_formatting_failure(&result);
 5438                })?;
 5439                result
 5440            })
 5441        } else if let Some((client, project_id)) = self.upstream_client() {
 5442            let buffer_store = self.buffer_store();
 5443            cx.spawn(async move |lsp_store, cx| {
 5444                let result = client
 5445                    .request(proto::ApplyCodeActionKind {
 5446                        project_id,
 5447                        kind: kind.as_str().to_owned(),
 5448                        buffer_ids: buffers
 5449                            .iter()
 5450                            .map(|buffer| {
 5451                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5452                            })
 5453                            .collect(),
 5454                    })
 5455                    .await
 5456                    .and_then(|result| result.transaction.context("missing transaction"));
 5457                lsp_store.update(cx, |lsp_store, _| {
 5458                    lsp_store.update_last_formatting_failure(&result);
 5459                })?;
 5460
 5461                let transaction_response = result?;
 5462                buffer_store
 5463                    .update(cx, |buffer_store, cx| {
 5464                        buffer_store.deserialize_project_transaction(
 5465                            transaction_response,
 5466                            push_to_history,
 5467                            cx,
 5468                        )
 5469                    })
 5470                    .await
 5471            })
 5472        } else {
 5473            Task::ready(Ok(ProjectTransaction::default()))
 5474        }
 5475    }
 5476
 5477    pub fn resolved_hint(
 5478        &mut self,
 5479        buffer_id: BufferId,
 5480        id: InlayId,
 5481        cx: &mut Context<Self>,
 5482    ) -> Option<ResolvedHint> {
 5483        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5484
 5485        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5486        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5487        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5488        let (server_id, resolve_data) = match &hint.resolve_state {
 5489            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5490            ResolveState::Resolving => {
 5491                return Some(ResolvedHint::Resolving(
 5492                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5493                ));
 5494            }
 5495            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5496        };
 5497
 5498        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5499        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5500        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5501            id,
 5502            cx.spawn(async move |lsp_store, cx| {
 5503                let resolved_hint = resolve_task.await;
 5504                lsp_store
 5505                    .update(cx, |lsp_store, _| {
 5506                        if let Some(old_inlay_hint) = lsp_store
 5507                            .lsp_data
 5508                            .get_mut(&buffer_id)
 5509                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5510                        {
 5511                            match resolved_hint {
 5512                                Ok(resolved_hint) => {
 5513                                    *old_inlay_hint = resolved_hint;
 5514                                }
 5515                                Err(e) => {
 5516                                    old_inlay_hint.resolve_state =
 5517                                        ResolveState::CanResolve(server_id, resolve_data);
 5518                                    log::error!("Inlay hint resolve failed: {e:#}");
 5519                                }
 5520                            }
 5521                        }
 5522                    })
 5523                    .ok();
 5524            })
 5525            .shared(),
 5526        );
 5527        debug_assert!(
 5528            previous_task.is_none(),
 5529            "Did not change hint's resolve state after spawning its resolve"
 5530        );
 5531        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5532        None
 5533    }
 5534
 5535    pub(crate) fn linked_edits(
 5536        &mut self,
 5537        buffer: &Entity<Buffer>,
 5538        position: Anchor,
 5539        cx: &mut Context<Self>,
 5540    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5541        let snapshot = buffer.read(cx).snapshot();
 5542        let scope = snapshot.language_scope_at(position);
 5543        let Some(server_id) = self
 5544            .as_local()
 5545            .and_then(|local| {
 5546                buffer.update(cx, |buffer, cx| {
 5547                    local
 5548                        .language_servers_for_buffer(buffer, cx)
 5549                        .filter(|(_, server)| {
 5550                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5551                        })
 5552                        .filter(|(adapter, _)| {
 5553                            scope
 5554                                .as_ref()
 5555                                .map(|scope| scope.language_allowed(&adapter.name))
 5556                                .unwrap_or(true)
 5557                        })
 5558                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5559                        .next()
 5560                })
 5561            })
 5562            .or_else(|| {
 5563                self.upstream_client()
 5564                    .is_some()
 5565                    .then_some(LanguageServerToQuery::FirstCapable)
 5566            })
 5567            .filter(|_| {
 5568                maybe!({
 5569                    let language = buffer.read(cx).language_at(position)?;
 5570                    Some(
 5571                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5572                            .linked_edits,
 5573                    )
 5574                }) == Some(true)
 5575            })
 5576        else {
 5577            return Task::ready(Ok(Vec::new()));
 5578        };
 5579
 5580        self.request_lsp(
 5581            buffer.clone(),
 5582            server_id,
 5583            LinkedEditingRange { position },
 5584            cx,
 5585        )
 5586    }
 5587
 5588    fn apply_on_type_formatting(
 5589        &mut self,
 5590        buffer: Entity<Buffer>,
 5591        position: Anchor,
 5592        trigger: String,
 5593        cx: &mut Context<Self>,
 5594    ) -> Task<Result<Option<Transaction>>> {
 5595        if let Some((client, project_id)) = self.upstream_client() {
 5596            if !self.check_if_capable_for_proto_request(
 5597                &buffer,
 5598                |capabilities| {
 5599                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5600                },
 5601                cx,
 5602            ) {
 5603                return Task::ready(Ok(None));
 5604            }
 5605            let request = proto::OnTypeFormatting {
 5606                project_id,
 5607                buffer_id: buffer.read(cx).remote_id().into(),
 5608                position: Some(serialize_anchor(&position)),
 5609                trigger,
 5610                version: serialize_version(&buffer.read(cx).version()),
 5611            };
 5612            cx.background_spawn(async move {
 5613                client
 5614                    .request(request)
 5615                    .await?
 5616                    .transaction
 5617                    .map(language::proto::deserialize_transaction)
 5618                    .transpose()
 5619            })
 5620        } else if let Some(local) = self.as_local_mut() {
 5621            let buffer_id = buffer.read(cx).remote_id();
 5622            local.buffers_being_formatted.insert(buffer_id);
 5623            cx.spawn(async move |this, cx| {
 5624                let _cleanup = defer({
 5625                    let this = this.clone();
 5626                    let mut cx = cx.clone();
 5627                    move || {
 5628                        this.update(&mut cx, |this, _| {
 5629                            if let Some(local) = this.as_local_mut() {
 5630                                local.buffers_being_formatted.remove(&buffer_id);
 5631                            }
 5632                        })
 5633                        .ok();
 5634                    }
 5635                });
 5636
 5637                buffer
 5638                    .update(cx, |buffer, _| {
 5639                        buffer.wait_for_edits(Some(position.timestamp()))
 5640                    })
 5641                    .await?;
 5642                this.update(cx, |this, cx| {
 5643                    let position = position.to_point_utf16(buffer.read(cx));
 5644                    this.on_type_format(buffer, position, trigger, false, cx)
 5645                })?
 5646                .await
 5647            })
 5648        } else {
 5649            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5650        }
 5651    }
 5652
 5653    pub fn on_type_format<T: ToPointUtf16>(
 5654        &mut self,
 5655        buffer: Entity<Buffer>,
 5656        position: T,
 5657        trigger: String,
 5658        push_to_history: bool,
 5659        cx: &mut Context<Self>,
 5660    ) -> Task<Result<Option<Transaction>>> {
 5661        let position = position.to_point_utf16(buffer.read(cx));
 5662        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5663    }
 5664
 5665    fn on_type_format_impl(
 5666        &mut self,
 5667        buffer: Entity<Buffer>,
 5668        position: PointUtf16,
 5669        trigger: String,
 5670        push_to_history: bool,
 5671        cx: &mut Context<Self>,
 5672    ) -> Task<Result<Option<Transaction>>> {
 5673        let options = buffer.update(cx, |buffer, cx| {
 5674            lsp_command::lsp_formatting_options(
 5675                language_settings(
 5676                    buffer.language_at(position).map(|l| l.name()),
 5677                    buffer.file(),
 5678                    cx,
 5679                )
 5680                .as_ref(),
 5681            )
 5682        });
 5683
 5684        cx.spawn(async move |this, cx| {
 5685            if let Some(waiter) =
 5686                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5687            {
 5688                waiter.await?;
 5689            }
 5690            cx.update(|cx| {
 5691                this.update(cx, |this, cx| {
 5692                    this.request_lsp(
 5693                        buffer.clone(),
 5694                        LanguageServerToQuery::FirstCapable,
 5695                        OnTypeFormatting {
 5696                            position,
 5697                            trigger,
 5698                            options,
 5699                            push_to_history,
 5700                        },
 5701                        cx,
 5702                    )
 5703                })
 5704            })?
 5705            .await
 5706        })
 5707    }
 5708
 5709    pub fn definitions(
 5710        &mut self,
 5711        buffer: &Entity<Buffer>,
 5712        position: PointUtf16,
 5713        cx: &mut Context<Self>,
 5714    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5715        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5716            let request = GetDefinitions { position };
 5717            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5718                return Task::ready(Ok(None));
 5719            }
 5720
 5721            let request_timeout = ProjectSettings::get_global(cx)
 5722                .global_lsp_settings
 5723                .get_request_timeout();
 5724
 5725            let request_task = upstream_client.request_lsp(
 5726                project_id,
 5727                None,
 5728                request_timeout,
 5729                cx.background_executor().clone(),
 5730                request.to_proto(project_id, buffer.read(cx)),
 5731            );
 5732            let buffer = buffer.clone();
 5733            cx.spawn(async move |weak_lsp_store, cx| {
 5734                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5735                    return Ok(None);
 5736                };
 5737                let Some(responses) = request_task.await? else {
 5738                    return Ok(None);
 5739                };
 5740                let actions = join_all(responses.payload.into_iter().map(|response| {
 5741                    GetDefinitions { position }.response_from_proto(
 5742                        response.response,
 5743                        lsp_store.clone(),
 5744                        buffer.clone(),
 5745                        cx.clone(),
 5746                    )
 5747                }))
 5748                .await;
 5749
 5750                Ok(Some(
 5751                    actions
 5752                        .into_iter()
 5753                        .collect::<Result<Vec<Vec<_>>>>()?
 5754                        .into_iter()
 5755                        .flatten()
 5756                        .dedup()
 5757                        .collect(),
 5758                ))
 5759            })
 5760        } else {
 5761            let definitions_task = self.request_multiple_lsp_locally(
 5762                buffer,
 5763                Some(position),
 5764                GetDefinitions { position },
 5765                cx,
 5766            );
 5767            cx.background_spawn(async move {
 5768                Ok(Some(
 5769                    definitions_task
 5770                        .await
 5771                        .into_iter()
 5772                        .flat_map(|(_, definitions)| definitions)
 5773                        .dedup()
 5774                        .collect(),
 5775                ))
 5776            })
 5777        }
 5778    }
 5779
 5780    pub fn declarations(
 5781        &mut self,
 5782        buffer: &Entity<Buffer>,
 5783        position: PointUtf16,
 5784        cx: &mut Context<Self>,
 5785    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5786        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5787            let request = GetDeclarations { position };
 5788            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5789                return Task::ready(Ok(None));
 5790            }
 5791            let request_timeout = ProjectSettings::get_global(cx)
 5792                .global_lsp_settings
 5793                .get_request_timeout();
 5794            let request_task = upstream_client.request_lsp(
 5795                project_id,
 5796                None,
 5797                request_timeout,
 5798                cx.background_executor().clone(),
 5799                request.to_proto(project_id, buffer.read(cx)),
 5800            );
 5801            let buffer = buffer.clone();
 5802            cx.spawn(async move |weak_lsp_store, cx| {
 5803                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5804                    return Ok(None);
 5805                };
 5806                let Some(responses) = request_task.await? else {
 5807                    return Ok(None);
 5808                };
 5809                let actions = join_all(responses.payload.into_iter().map(|response| {
 5810                    GetDeclarations { position }.response_from_proto(
 5811                        response.response,
 5812                        lsp_store.clone(),
 5813                        buffer.clone(),
 5814                        cx.clone(),
 5815                    )
 5816                }))
 5817                .await;
 5818
 5819                Ok(Some(
 5820                    actions
 5821                        .into_iter()
 5822                        .collect::<Result<Vec<Vec<_>>>>()?
 5823                        .into_iter()
 5824                        .flatten()
 5825                        .dedup()
 5826                        .collect(),
 5827                ))
 5828            })
 5829        } else {
 5830            let declarations_task = self.request_multiple_lsp_locally(
 5831                buffer,
 5832                Some(position),
 5833                GetDeclarations { position },
 5834                cx,
 5835            );
 5836            cx.background_spawn(async move {
 5837                Ok(Some(
 5838                    declarations_task
 5839                        .await
 5840                        .into_iter()
 5841                        .flat_map(|(_, declarations)| declarations)
 5842                        .dedup()
 5843                        .collect(),
 5844                ))
 5845            })
 5846        }
 5847    }
 5848
 5849    pub fn type_definitions(
 5850        &mut self,
 5851        buffer: &Entity<Buffer>,
 5852        position: PointUtf16,
 5853        cx: &mut Context<Self>,
 5854    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5855        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5856            let request = GetTypeDefinitions { position };
 5857            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5858                return Task::ready(Ok(None));
 5859            }
 5860            let request_timeout = ProjectSettings::get_global(cx)
 5861                .global_lsp_settings
 5862                .get_request_timeout();
 5863            let request_task = upstream_client.request_lsp(
 5864                project_id,
 5865                None,
 5866                request_timeout,
 5867                cx.background_executor().clone(),
 5868                request.to_proto(project_id, buffer.read(cx)),
 5869            );
 5870            let buffer = buffer.clone();
 5871            cx.spawn(async move |weak_lsp_store, cx| {
 5872                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5873                    return Ok(None);
 5874                };
 5875                let Some(responses) = request_task.await? else {
 5876                    return Ok(None);
 5877                };
 5878                let actions = join_all(responses.payload.into_iter().map(|response| {
 5879                    GetTypeDefinitions { position }.response_from_proto(
 5880                        response.response,
 5881                        lsp_store.clone(),
 5882                        buffer.clone(),
 5883                        cx.clone(),
 5884                    )
 5885                }))
 5886                .await;
 5887
 5888                Ok(Some(
 5889                    actions
 5890                        .into_iter()
 5891                        .collect::<Result<Vec<Vec<_>>>>()?
 5892                        .into_iter()
 5893                        .flatten()
 5894                        .dedup()
 5895                        .collect(),
 5896                ))
 5897            })
 5898        } else {
 5899            let type_definitions_task = self.request_multiple_lsp_locally(
 5900                buffer,
 5901                Some(position),
 5902                GetTypeDefinitions { position },
 5903                cx,
 5904            );
 5905            cx.background_spawn(async move {
 5906                Ok(Some(
 5907                    type_definitions_task
 5908                        .await
 5909                        .into_iter()
 5910                        .flat_map(|(_, type_definitions)| type_definitions)
 5911                        .dedup()
 5912                        .collect(),
 5913                ))
 5914            })
 5915        }
 5916    }
 5917
 5918    pub fn implementations(
 5919        &mut self,
 5920        buffer: &Entity<Buffer>,
 5921        position: PointUtf16,
 5922        cx: &mut Context<Self>,
 5923    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5924        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5925            let request = GetImplementations { position };
 5926            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5927                return Task::ready(Ok(None));
 5928            }
 5929
 5930            let request_timeout = ProjectSettings::get_global(cx)
 5931                .global_lsp_settings
 5932                .get_request_timeout();
 5933            let request_task = upstream_client.request_lsp(
 5934                project_id,
 5935                None,
 5936                request_timeout,
 5937                cx.background_executor().clone(),
 5938                request.to_proto(project_id, buffer.read(cx)),
 5939            );
 5940            let buffer = buffer.clone();
 5941            cx.spawn(async move |weak_lsp_store, cx| {
 5942                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5943                    return Ok(None);
 5944                };
 5945                let Some(responses) = request_task.await? else {
 5946                    return Ok(None);
 5947                };
 5948                let actions = join_all(responses.payload.into_iter().map(|response| {
 5949                    GetImplementations { position }.response_from_proto(
 5950                        response.response,
 5951                        lsp_store.clone(),
 5952                        buffer.clone(),
 5953                        cx.clone(),
 5954                    )
 5955                }))
 5956                .await;
 5957
 5958                Ok(Some(
 5959                    actions
 5960                        .into_iter()
 5961                        .collect::<Result<Vec<Vec<_>>>>()?
 5962                        .into_iter()
 5963                        .flatten()
 5964                        .dedup()
 5965                        .collect(),
 5966                ))
 5967            })
 5968        } else {
 5969            let implementations_task = self.request_multiple_lsp_locally(
 5970                buffer,
 5971                Some(position),
 5972                GetImplementations { position },
 5973                cx,
 5974            );
 5975            cx.background_spawn(async move {
 5976                Ok(Some(
 5977                    implementations_task
 5978                        .await
 5979                        .into_iter()
 5980                        .flat_map(|(_, implementations)| implementations)
 5981                        .dedup()
 5982                        .collect(),
 5983                ))
 5984            })
 5985        }
 5986    }
 5987
 5988    pub fn references(
 5989        &mut self,
 5990        buffer: &Entity<Buffer>,
 5991        position: PointUtf16,
 5992        cx: &mut Context<Self>,
 5993    ) -> Task<Result<Option<Vec<Location>>>> {
 5994        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5995            let request = GetReferences { position };
 5996            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5997                return Task::ready(Ok(None));
 5998            }
 5999
 6000            let request_timeout = ProjectSettings::get_global(cx)
 6001                .global_lsp_settings
 6002                .get_request_timeout();
 6003            let request_task = upstream_client.request_lsp(
 6004                project_id,
 6005                None,
 6006                request_timeout,
 6007                cx.background_executor().clone(),
 6008                request.to_proto(project_id, buffer.read(cx)),
 6009            );
 6010            let buffer = buffer.clone();
 6011            cx.spawn(async move |weak_lsp_store, cx| {
 6012                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6013                    return Ok(None);
 6014                };
 6015                let Some(responses) = request_task.await? else {
 6016                    return Ok(None);
 6017                };
 6018
 6019                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6020                    GetReferences { position }.response_from_proto(
 6021                        lsp_response.response,
 6022                        lsp_store.clone(),
 6023                        buffer.clone(),
 6024                        cx.clone(),
 6025                    )
 6026                }))
 6027                .await
 6028                .into_iter()
 6029                .collect::<Result<Vec<Vec<_>>>>()?
 6030                .into_iter()
 6031                .flatten()
 6032                .dedup()
 6033                .collect();
 6034                Ok(Some(locations))
 6035            })
 6036        } else {
 6037            let references_task = self.request_multiple_lsp_locally(
 6038                buffer,
 6039                Some(position),
 6040                GetReferences { position },
 6041                cx,
 6042            );
 6043            cx.background_spawn(async move {
 6044                Ok(Some(
 6045                    references_task
 6046                        .await
 6047                        .into_iter()
 6048                        .flat_map(|(_, references)| references)
 6049                        .dedup()
 6050                        .collect(),
 6051                ))
 6052            })
 6053        }
 6054    }
 6055
 6056    pub fn code_actions(
 6057        &mut self,
 6058        buffer: &Entity<Buffer>,
 6059        range: Range<Anchor>,
 6060        kinds: Option<Vec<CodeActionKind>>,
 6061        cx: &mut Context<Self>,
 6062    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6063        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6064            let request = GetCodeActions {
 6065                range: range.clone(),
 6066                kinds: kinds.clone(),
 6067            };
 6068            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6069                return Task::ready(Ok(None));
 6070            }
 6071            let request_timeout = ProjectSettings::get_global(cx)
 6072                .global_lsp_settings
 6073                .get_request_timeout();
 6074            let request_task = upstream_client.request_lsp(
 6075                project_id,
 6076                None,
 6077                request_timeout,
 6078                cx.background_executor().clone(),
 6079                request.to_proto(project_id, buffer.read(cx)),
 6080            );
 6081            let buffer = buffer.clone();
 6082            cx.spawn(async move |weak_lsp_store, cx| {
 6083                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6084                    return Ok(None);
 6085                };
 6086                let Some(responses) = request_task.await? else {
 6087                    return Ok(None);
 6088                };
 6089                let actions = join_all(responses.payload.into_iter().map(|response| {
 6090                    GetCodeActions {
 6091                        range: range.clone(),
 6092                        kinds: kinds.clone(),
 6093                    }
 6094                    .response_from_proto(
 6095                        response.response,
 6096                        lsp_store.clone(),
 6097                        buffer.clone(),
 6098                        cx.clone(),
 6099                    )
 6100                }))
 6101                .await;
 6102
 6103                Ok(Some(
 6104                    actions
 6105                        .into_iter()
 6106                        .collect::<Result<Vec<Vec<_>>>>()?
 6107                        .into_iter()
 6108                        .flatten()
 6109                        .collect(),
 6110                ))
 6111            })
 6112        } else {
 6113            let all_actions_task = self.request_multiple_lsp_locally(
 6114                buffer,
 6115                Some(range.start),
 6116                GetCodeActions { range, kinds },
 6117                cx,
 6118            );
 6119            cx.background_spawn(async move {
 6120                Ok(Some(
 6121                    all_actions_task
 6122                        .await
 6123                        .into_iter()
 6124                        .flat_map(|(_, actions)| actions)
 6125                        .collect(),
 6126                ))
 6127            })
 6128        }
 6129    }
 6130
 6131    #[inline(never)]
 6132    pub fn completions(
 6133        &self,
 6134        buffer: &Entity<Buffer>,
 6135        position: PointUtf16,
 6136        context: CompletionContext,
 6137        cx: &mut Context<Self>,
 6138    ) -> Task<Result<Vec<CompletionResponse>>> {
 6139        let language_registry = self.languages.clone();
 6140
 6141        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6142            let snapshot = buffer.read(cx).snapshot();
 6143            let offset = position.to_offset(&snapshot);
 6144            let scope = snapshot.language_scope_at(offset);
 6145            let capable_lsps = self.all_capable_for_proto_request(
 6146                buffer,
 6147                |server_name, capabilities| {
 6148                    capabilities.completion_provider.is_some()
 6149                        && scope
 6150                            .as_ref()
 6151                            .map(|scope| scope.language_allowed(server_name))
 6152                            .unwrap_or(true)
 6153                },
 6154                cx,
 6155            );
 6156            if capable_lsps.is_empty() {
 6157                return Task::ready(Ok(Vec::new()));
 6158            }
 6159
 6160            let language = buffer.read(cx).language().cloned();
 6161
 6162            let buffer = buffer.clone();
 6163
 6164            cx.spawn(async move |this, cx| {
 6165                let requests = join_all(
 6166                    capable_lsps
 6167                        .into_iter()
 6168                        .map(|(id, server_name)| {
 6169                            let request = GetCompletions {
 6170                                position,
 6171                                context: context.clone(),
 6172                                server_id: Some(id),
 6173                            };
 6174                            let buffer = buffer.clone();
 6175                            let language = language.clone();
 6176                            let lsp_adapter = language.as_ref().and_then(|language| {
 6177                                let adapters = language_registry.lsp_adapters(&language.name());
 6178                                adapters
 6179                                    .iter()
 6180                                    .find(|adapter| adapter.name() == server_name)
 6181                                    .or_else(|| adapters.first())
 6182                                    .cloned()
 6183                            });
 6184                            let upstream_client = upstream_client.clone();
 6185                            let response = this
 6186                                .update(cx, |this, cx| {
 6187                                    this.send_lsp_proto_request(
 6188                                        buffer,
 6189                                        upstream_client,
 6190                                        project_id,
 6191                                        request,
 6192                                        cx,
 6193                                    )
 6194                                })
 6195                                .log_err();
 6196                            async move {
 6197                                let response = response?.await.log_err()?;
 6198
 6199                                let completions = populate_labels_for_completions(
 6200                                    response.completions,
 6201                                    language,
 6202                                    lsp_adapter,
 6203                                )
 6204                                .await;
 6205
 6206                                Some(CompletionResponse {
 6207                                    completions,
 6208                                    display_options: CompletionDisplayOptions::default(),
 6209                                    is_incomplete: response.is_incomplete,
 6210                                })
 6211                            }
 6212                        })
 6213                        .collect::<Vec<_>>(),
 6214                );
 6215                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6216            })
 6217        } else if let Some(local) = self.as_local() {
 6218            let snapshot = buffer.read(cx).snapshot();
 6219            let offset = position.to_offset(&snapshot);
 6220            let scope = snapshot.language_scope_at(offset);
 6221            let language = snapshot.language().cloned();
 6222            let completion_settings = language_settings(
 6223                language.as_ref().map(|language| language.name()),
 6224                buffer.read(cx).file(),
 6225                cx,
 6226            )
 6227            .completions
 6228            .clone();
 6229            if !completion_settings.lsp {
 6230                return Task::ready(Ok(Vec::new()));
 6231            }
 6232
 6233            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6234                local
 6235                    .language_servers_for_buffer(buffer, cx)
 6236                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6237                    .filter(|(adapter, _)| {
 6238                        scope
 6239                            .as_ref()
 6240                            .map(|scope| scope.language_allowed(&adapter.name))
 6241                            .unwrap_or(true)
 6242                    })
 6243                    .map(|(_, server)| server.server_id())
 6244                    .collect()
 6245            });
 6246
 6247            let buffer = buffer.clone();
 6248            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6249            let lsp_timeout = if lsp_timeout > 0 {
 6250                Some(Duration::from_millis(lsp_timeout))
 6251            } else {
 6252                None
 6253            };
 6254            cx.spawn(async move |this,  cx| {
 6255                let mut tasks = Vec::with_capacity(server_ids.len());
 6256                this.update(cx, |lsp_store, cx| {
 6257                    for server_id in server_ids {
 6258                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6259                        let lsp_timeout = lsp_timeout
 6260                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6261                        let mut timeout = cx.background_spawn(async move {
 6262                            match lsp_timeout {
 6263                                Some(lsp_timeout) => {
 6264                                    lsp_timeout.await;
 6265                                    true
 6266                                },
 6267                                None => false,
 6268                            }
 6269                        }).fuse();
 6270                        let mut lsp_request = lsp_store.request_lsp(
 6271                            buffer.clone(),
 6272                            LanguageServerToQuery::Other(server_id),
 6273                            GetCompletions {
 6274                                position,
 6275                                context: context.clone(),
 6276                                server_id: Some(server_id),
 6277                            },
 6278                            cx,
 6279                        ).fuse();
 6280                        let new_task = cx.background_spawn(async move {
 6281                            select_biased! {
 6282                                response = lsp_request => anyhow::Ok(Some(response?)),
 6283                                timeout_happened = timeout => {
 6284                                    if timeout_happened {
 6285                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6286                                        Ok(None)
 6287                                    } else {
 6288                                        let completions = lsp_request.await?;
 6289                                        Ok(Some(completions))
 6290                                    }
 6291                                },
 6292                            }
 6293                        });
 6294                        tasks.push((lsp_adapter, new_task));
 6295                    }
 6296                })?;
 6297
 6298                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6299                    let completion_response = task.await.ok()??;
 6300                    let completions = populate_labels_for_completions(
 6301                            completion_response.completions,
 6302                            language.clone(),
 6303                            lsp_adapter,
 6304                        )
 6305                        .await;
 6306                    Some(CompletionResponse {
 6307                        completions,
 6308                        display_options: CompletionDisplayOptions::default(),
 6309                        is_incomplete: completion_response.is_incomplete,
 6310                    })
 6311                });
 6312
 6313                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6314
 6315                Ok(responses.into_iter().flatten().collect())
 6316            })
 6317        } else {
 6318            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6319        }
 6320    }
 6321
 6322    pub fn resolve_completions(
 6323        &self,
 6324        buffer: Entity<Buffer>,
 6325        completion_indices: Vec<usize>,
 6326        completions: Rc<RefCell<Box<[Completion]>>>,
 6327        cx: &mut Context<Self>,
 6328    ) -> Task<Result<bool>> {
 6329        let client = self.upstream_client();
 6330        let buffer_id = buffer.read(cx).remote_id();
 6331        let buffer_snapshot = buffer.read(cx).snapshot();
 6332
 6333        if !self.check_if_capable_for_proto_request(
 6334            &buffer,
 6335            GetCompletions::can_resolve_completions,
 6336            cx,
 6337        ) {
 6338            return Task::ready(Ok(false));
 6339        }
 6340        cx.spawn(async move |lsp_store, cx| {
 6341            let request_timeout = cx.update(|app| {
 6342                ProjectSettings::get_global(app)
 6343                    .global_lsp_settings
 6344                    .get_request_timeout()
 6345            });
 6346
 6347            let mut did_resolve = false;
 6348            if let Some((client, project_id)) = client {
 6349                for completion_index in completion_indices {
 6350                    let server_id = {
 6351                        let completion = &completions.borrow()[completion_index];
 6352                        completion.source.server_id()
 6353                    };
 6354                    if let Some(server_id) = server_id {
 6355                        if Self::resolve_completion_remote(
 6356                            project_id,
 6357                            server_id,
 6358                            buffer_id,
 6359                            completions.clone(),
 6360                            completion_index,
 6361                            client.clone(),
 6362                        )
 6363                        .await
 6364                        .log_err()
 6365                        .is_some()
 6366                        {
 6367                            did_resolve = true;
 6368                        }
 6369                    } else {
 6370                        resolve_word_completion(
 6371                            &buffer_snapshot,
 6372                            &mut completions.borrow_mut()[completion_index],
 6373                        );
 6374                    }
 6375                }
 6376            } else {
 6377                for completion_index in completion_indices {
 6378                    let server_id = {
 6379                        let completion = &completions.borrow()[completion_index];
 6380                        completion.source.server_id()
 6381                    };
 6382                    if let Some(server_id) = server_id {
 6383                        let server_and_adapter = lsp_store
 6384                            .read_with(cx, |lsp_store, _| {
 6385                                let server = lsp_store.language_server_for_id(server_id)?;
 6386                                let adapter =
 6387                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6388                                Some((server, adapter))
 6389                            })
 6390                            .ok()
 6391                            .flatten();
 6392                        let Some((server, adapter)) = server_and_adapter else {
 6393                            continue;
 6394                        };
 6395
 6396                        let resolved = Self::resolve_completion_local(
 6397                            server,
 6398                            completions.clone(),
 6399                            completion_index,
 6400                            request_timeout,
 6401                        )
 6402                        .await
 6403                        .log_err()
 6404                        .is_some();
 6405                        if resolved {
 6406                            Self::regenerate_completion_labels(
 6407                                adapter,
 6408                                &buffer_snapshot,
 6409                                completions.clone(),
 6410                                completion_index,
 6411                            )
 6412                            .await
 6413                            .log_err();
 6414                            did_resolve = true;
 6415                        }
 6416                    } else {
 6417                        resolve_word_completion(
 6418                            &buffer_snapshot,
 6419                            &mut completions.borrow_mut()[completion_index],
 6420                        );
 6421                    }
 6422                }
 6423            }
 6424
 6425            Ok(did_resolve)
 6426        })
 6427    }
 6428
 6429    async fn resolve_completion_local(
 6430        server: Arc<lsp::LanguageServer>,
 6431        completions: Rc<RefCell<Box<[Completion]>>>,
 6432        completion_index: usize,
 6433        request_timeout: Duration,
 6434    ) -> Result<()> {
 6435        let server_id = server.server_id();
 6436        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6437            return Ok(());
 6438        }
 6439
 6440        let request = {
 6441            let completion = &completions.borrow()[completion_index];
 6442            match &completion.source {
 6443                CompletionSource::Lsp {
 6444                    lsp_completion,
 6445                    resolved,
 6446                    server_id: completion_server_id,
 6447                    ..
 6448                } => {
 6449                    if *resolved {
 6450                        return Ok(());
 6451                    }
 6452                    anyhow::ensure!(
 6453                        server_id == *completion_server_id,
 6454                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6455                    );
 6456                    server.request::<lsp::request::ResolveCompletionItem>(
 6457                        *lsp_completion.clone(),
 6458                        request_timeout,
 6459                    )
 6460                }
 6461                CompletionSource::BufferWord { .. }
 6462                | CompletionSource::Dap { .. }
 6463                | CompletionSource::Custom => {
 6464                    return Ok(());
 6465                }
 6466            }
 6467        };
 6468        let resolved_completion = request
 6469            .await
 6470            .into_response()
 6471            .context("resolve completion")?;
 6472
 6473        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6474        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6475
 6476        let mut completions = completions.borrow_mut();
 6477        let completion = &mut completions[completion_index];
 6478        if let CompletionSource::Lsp {
 6479            lsp_completion,
 6480            resolved,
 6481            server_id: completion_server_id,
 6482            ..
 6483        } = &mut completion.source
 6484        {
 6485            if *resolved {
 6486                return Ok(());
 6487            }
 6488            anyhow::ensure!(
 6489                server_id == *completion_server_id,
 6490                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6491            );
 6492            **lsp_completion = resolved_completion;
 6493            *resolved = true;
 6494        }
 6495        Ok(())
 6496    }
 6497
 6498    async fn regenerate_completion_labels(
 6499        adapter: Arc<CachedLspAdapter>,
 6500        snapshot: &BufferSnapshot,
 6501        completions: Rc<RefCell<Box<[Completion]>>>,
 6502        completion_index: usize,
 6503    ) -> Result<()> {
 6504        let completion_item = completions.borrow()[completion_index]
 6505            .source
 6506            .lsp_completion(true)
 6507            .map(Cow::into_owned);
 6508        if let Some(lsp_documentation) = completion_item
 6509            .as_ref()
 6510            .and_then(|completion_item| completion_item.documentation.clone())
 6511        {
 6512            let mut completions = completions.borrow_mut();
 6513            let completion = &mut completions[completion_index];
 6514            completion.documentation = Some(lsp_documentation.into());
 6515        } else {
 6516            let mut completions = completions.borrow_mut();
 6517            let completion = &mut completions[completion_index];
 6518            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6519        }
 6520
 6521        let mut new_label = match completion_item {
 6522            Some(completion_item) => {
 6523                // Some language servers always return `detail` lazily via resolve, regardless of
 6524                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6525                // See: https://github.com/yioneko/vtsls/issues/213
 6526                let language = snapshot.language();
 6527                match language {
 6528                    Some(language) => {
 6529                        adapter
 6530                            .labels_for_completions(
 6531                                std::slice::from_ref(&completion_item),
 6532                                language,
 6533                            )
 6534                            .await?
 6535                    }
 6536                    None => Vec::new(),
 6537                }
 6538                .pop()
 6539                .flatten()
 6540                .unwrap_or_else(|| {
 6541                    CodeLabel::fallback_for_completion(
 6542                        &completion_item,
 6543                        language.map(|language| language.as_ref()),
 6544                    )
 6545                })
 6546            }
 6547            None => CodeLabel::plain(
 6548                completions.borrow()[completion_index].new_text.clone(),
 6549                None,
 6550            ),
 6551        };
 6552        ensure_uniform_list_compatible_label(&mut new_label);
 6553
 6554        let mut completions = completions.borrow_mut();
 6555        let completion = &mut completions[completion_index];
 6556        if completion.label.filter_text() == new_label.filter_text() {
 6557            completion.label = new_label;
 6558        } else {
 6559            log::error!(
 6560                "Resolved completion changed display label from {} to {}. \
 6561                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6562                completion.label.text(),
 6563                new_label.text(),
 6564                completion.label.filter_text(),
 6565                new_label.filter_text()
 6566            );
 6567        }
 6568
 6569        Ok(())
 6570    }
 6571
 6572    async fn resolve_completion_remote(
 6573        project_id: u64,
 6574        server_id: LanguageServerId,
 6575        buffer_id: BufferId,
 6576        completions: Rc<RefCell<Box<[Completion]>>>,
 6577        completion_index: usize,
 6578        client: AnyProtoClient,
 6579    ) -> Result<()> {
 6580        let lsp_completion = {
 6581            let completion = &completions.borrow()[completion_index];
 6582            match &completion.source {
 6583                CompletionSource::Lsp {
 6584                    lsp_completion,
 6585                    resolved,
 6586                    server_id: completion_server_id,
 6587                    ..
 6588                } => {
 6589                    anyhow::ensure!(
 6590                        server_id == *completion_server_id,
 6591                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6592                    );
 6593                    if *resolved {
 6594                        return Ok(());
 6595                    }
 6596                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6597                }
 6598                CompletionSource::Custom
 6599                | CompletionSource::Dap { .. }
 6600                | CompletionSource::BufferWord { .. } => {
 6601                    return Ok(());
 6602                }
 6603            }
 6604        };
 6605        let request = proto::ResolveCompletionDocumentation {
 6606            project_id,
 6607            language_server_id: server_id.0 as u64,
 6608            lsp_completion,
 6609            buffer_id: buffer_id.into(),
 6610        };
 6611
 6612        let response = client
 6613            .request(request)
 6614            .await
 6615            .context("completion documentation resolve proto request")?;
 6616        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6617
 6618        let documentation = if response.documentation.is_empty() {
 6619            CompletionDocumentation::Undocumented
 6620        } else if response.documentation_is_markdown {
 6621            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6622        } else if response.documentation.lines().count() <= 1 {
 6623            CompletionDocumentation::SingleLine(response.documentation.into())
 6624        } else {
 6625            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6626        };
 6627
 6628        let mut completions = completions.borrow_mut();
 6629        let completion = &mut completions[completion_index];
 6630        completion.documentation = Some(documentation);
 6631        if let CompletionSource::Lsp {
 6632            insert_range,
 6633            lsp_completion,
 6634            resolved,
 6635            server_id: completion_server_id,
 6636            lsp_defaults: _,
 6637        } = &mut completion.source
 6638        {
 6639            let completion_insert_range = response
 6640                .old_insert_start
 6641                .and_then(deserialize_anchor)
 6642                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6643            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6644
 6645            if *resolved {
 6646                return Ok(());
 6647            }
 6648            anyhow::ensure!(
 6649                server_id == *completion_server_id,
 6650                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6651            );
 6652            **lsp_completion = resolved_lsp_completion;
 6653            *resolved = true;
 6654        }
 6655
 6656        let replace_range = response
 6657            .old_replace_start
 6658            .and_then(deserialize_anchor)
 6659            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6660        if let Some((old_replace_start, old_replace_end)) = replace_range
 6661            && !response.new_text.is_empty()
 6662        {
 6663            completion.new_text = response.new_text;
 6664            completion.replace_range = old_replace_start..old_replace_end;
 6665        }
 6666
 6667        Ok(())
 6668    }
 6669
 6670    pub fn apply_additional_edits_for_completion(
 6671        &self,
 6672        buffer_handle: Entity<Buffer>,
 6673        completions: Rc<RefCell<Box<[Completion]>>>,
 6674        completion_index: usize,
 6675        push_to_history: bool,
 6676        all_commit_ranges: Vec<Range<language::Anchor>>,
 6677        cx: &mut Context<Self>,
 6678    ) -> Task<Result<Option<Transaction>>> {
 6679        if let Some((client, project_id)) = self.upstream_client() {
 6680            let buffer = buffer_handle.read(cx);
 6681            let buffer_id = buffer.remote_id();
 6682            cx.spawn(async move |_, cx| {
 6683                let request = {
 6684                    let completion = completions.borrow()[completion_index].clone();
 6685                    proto::ApplyCompletionAdditionalEdits {
 6686                        project_id,
 6687                        buffer_id: buffer_id.into(),
 6688                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6689                            replace_range: completion.replace_range,
 6690                            new_text: completion.new_text,
 6691                            source: completion.source,
 6692                        })),
 6693                        all_commit_ranges: all_commit_ranges
 6694                            .iter()
 6695                            .cloned()
 6696                            .map(language::proto::serialize_anchor_range)
 6697                            .collect(),
 6698                    }
 6699                };
 6700
 6701                let Some(transaction) = client.request(request).await?.transaction else {
 6702                    return Ok(None);
 6703                };
 6704
 6705                let transaction = language::proto::deserialize_transaction(transaction)?;
 6706                buffer_handle
 6707                    .update(cx, |buffer, _| {
 6708                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6709                    })
 6710                    .await?;
 6711                if push_to_history {
 6712                    buffer_handle.update(cx, |buffer, _| {
 6713                        buffer.push_transaction(transaction.clone(), Instant::now());
 6714                        buffer.finalize_last_transaction();
 6715                    });
 6716                }
 6717                Ok(Some(transaction))
 6718            })
 6719        } else {
 6720            let request_timeout = ProjectSettings::get_global(cx)
 6721                .global_lsp_settings
 6722                .get_request_timeout();
 6723
 6724            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6725                let completion = &completions.borrow()[completion_index];
 6726                let server_id = completion.source.server_id()?;
 6727                Some(
 6728                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6729                        .1
 6730                        .clone(),
 6731                )
 6732            }) else {
 6733                return Task::ready(Ok(None));
 6734            };
 6735
 6736            cx.spawn(async move |this, cx| {
 6737                Self::resolve_completion_local(
 6738                    server.clone(),
 6739                    completions.clone(),
 6740                    completion_index,
 6741                    request_timeout,
 6742                )
 6743                .await
 6744                .context("resolving completion")?;
 6745                let completion = completions.borrow()[completion_index].clone();
 6746                let additional_text_edits = completion
 6747                    .source
 6748                    .lsp_completion(true)
 6749                    .as_ref()
 6750                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6751                if let Some(edits) = additional_text_edits {
 6752                    let edits = this
 6753                        .update(cx, |this, cx| {
 6754                            this.as_local_mut().unwrap().edits_from_lsp(
 6755                                &buffer_handle,
 6756                                edits,
 6757                                server.server_id(),
 6758                                None,
 6759                                cx,
 6760                            )
 6761                        })?
 6762                        .await?;
 6763
 6764                    buffer_handle.update(cx, |buffer, cx| {
 6765                        buffer.finalize_last_transaction();
 6766                        buffer.start_transaction();
 6767
 6768                        for (range, text) in edits {
 6769                            let primary = &completion.replace_range;
 6770
 6771                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6772                            // and the primary completion is just an insertion (empty range), then this is likely
 6773                            // an auto-import scenario and should not be considered overlapping
 6774                            // https://github.com/zed-industries/zed/issues/26136
 6775                            let is_file_start_auto_import = {
 6776                                let snapshot = buffer.snapshot();
 6777                                let primary_start_point = primary.start.to_point(&snapshot);
 6778                                let range_start_point = range.start.to_point(&snapshot);
 6779
 6780                                let result = primary_start_point.row == 0
 6781                                    && primary_start_point.column == 0
 6782                                    && range_start_point.row == 0
 6783                                    && range_start_point.column == 0;
 6784
 6785                                result
 6786                            };
 6787
 6788                            let has_overlap = if is_file_start_auto_import {
 6789                                false
 6790                            } else {
 6791                                all_commit_ranges.iter().any(|commit_range| {
 6792                                    let start_within =
 6793                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6794                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6795                                    let end_within =
 6796                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6797                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6798                                    start_within || end_within
 6799                                })
 6800                            };
 6801
 6802                            //Skip additional edits which overlap with the primary completion edit
 6803                            //https://github.com/zed-industries/zed/pull/1871
 6804                            if !has_overlap {
 6805                                buffer.edit([(range, text)], None, cx);
 6806                            }
 6807                        }
 6808
 6809                        let transaction = if buffer.end_transaction(cx).is_some() {
 6810                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6811                            if !push_to_history {
 6812                                buffer.forget_transaction(transaction.id);
 6813                            }
 6814                            Some(transaction)
 6815                        } else {
 6816                            None
 6817                        };
 6818                        Ok(transaction)
 6819                    })
 6820                } else {
 6821                    Ok(None)
 6822                }
 6823            })
 6824        }
 6825    }
 6826
 6827    pub fn pull_diagnostics(
 6828        &mut self,
 6829        buffer: Entity<Buffer>,
 6830        cx: &mut Context<Self>,
 6831    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6832        let buffer_id = buffer.read(cx).remote_id();
 6833
 6834        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6835            let mut suitable_capabilities = None;
 6836            // Are we capable for proto request?
 6837            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6838                &buffer,
 6839                |capabilities| {
 6840                    if let Some(caps) = &capabilities.diagnostic_provider {
 6841                        suitable_capabilities = Some(caps.clone());
 6842                        true
 6843                    } else {
 6844                        false
 6845                    }
 6846                },
 6847                cx,
 6848            );
 6849            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6850            let Some(dynamic_caps) = suitable_capabilities else {
 6851                return Task::ready(Ok(None));
 6852            };
 6853            assert!(any_server_has_diagnostics_provider);
 6854
 6855            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6856            let request = GetDocumentDiagnostics {
 6857                previous_result_id: None,
 6858                identifier,
 6859                registration_id: None,
 6860            };
 6861            let request_timeout = ProjectSettings::get_global(cx)
 6862                .global_lsp_settings
 6863                .get_request_timeout();
 6864            let request_task = client.request_lsp(
 6865                upstream_project_id,
 6866                None,
 6867                request_timeout,
 6868                cx.background_executor().clone(),
 6869                request.to_proto(upstream_project_id, buffer.read(cx)),
 6870            );
 6871            cx.background_spawn(async move {
 6872                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6873                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6874                // Do not attempt to further process the dummy responses here.
 6875                let _response = request_task.await?;
 6876                Ok(None)
 6877            })
 6878        } else {
 6879            let servers = buffer.update(cx, |buffer, cx| {
 6880                self.running_language_servers_for_local_buffer(buffer, cx)
 6881                    .map(|(_, server)| server.clone())
 6882                    .collect::<Vec<_>>()
 6883            });
 6884
 6885            let pull_diagnostics = servers
 6886                .into_iter()
 6887                .flat_map(|server| {
 6888                    let result = maybe!({
 6889                        let local = self.as_local()?;
 6890                        let server_id = server.server_id();
 6891                        let providers_with_identifiers = local
 6892                            .language_server_dynamic_registrations
 6893                            .get(&server_id)
 6894                            .into_iter()
 6895                            .flat_map(|registrations| registrations.diagnostics.clone())
 6896                            .collect::<Vec<_>>();
 6897                        Some(
 6898                            providers_with_identifiers
 6899                                .into_iter()
 6900                                .map(|(registration_id, dynamic_caps)| {
 6901                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6902                                    let registration_id = registration_id.map(SharedString::from);
 6903                                    let result_id = self.result_id_for_buffer_pull(
 6904                                        server_id,
 6905                                        buffer_id,
 6906                                        &registration_id,
 6907                                        cx,
 6908                                    );
 6909                                    self.request_lsp(
 6910                                        buffer.clone(),
 6911                                        LanguageServerToQuery::Other(server_id),
 6912                                        GetDocumentDiagnostics {
 6913                                            previous_result_id: result_id,
 6914                                            registration_id,
 6915                                            identifier,
 6916                                        },
 6917                                        cx,
 6918                                    )
 6919                                })
 6920                                .collect::<Vec<_>>(),
 6921                        )
 6922                    });
 6923
 6924                    result.unwrap_or_default()
 6925                })
 6926                .collect::<Vec<_>>();
 6927
 6928            cx.background_spawn(async move {
 6929                let mut responses = Vec::new();
 6930                for diagnostics in join_all(pull_diagnostics).await {
 6931                    responses.extend(diagnostics?);
 6932                }
 6933                Ok(Some(responses))
 6934            })
 6935        }
 6936    }
 6937
 6938    pub fn applicable_inlay_chunks(
 6939        &mut self,
 6940        buffer: &Entity<Buffer>,
 6941        ranges: &[Range<text::Anchor>],
 6942        cx: &mut Context<Self>,
 6943    ) -> Vec<Range<BufferRow>> {
 6944        let buffer_snapshot = buffer.read(cx).snapshot();
 6945        let ranges = ranges
 6946            .iter()
 6947            .map(|range| range.to_point(&buffer_snapshot))
 6948            .collect::<Vec<_>>();
 6949
 6950        self.latest_lsp_data(buffer, cx)
 6951            .inlay_hints
 6952            .applicable_chunks(ranges.as_slice())
 6953            .map(|chunk| chunk.row_range())
 6954            .collect()
 6955    }
 6956
 6957    pub fn invalidate_inlay_hints<'a>(
 6958        &'a mut self,
 6959        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6960    ) {
 6961        for buffer_id in for_buffers {
 6962            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6963                lsp_data.inlay_hints.clear();
 6964            }
 6965        }
 6966    }
 6967
 6968    pub fn inlay_hints(
 6969        &mut self,
 6970        invalidate: InvalidationStrategy,
 6971        buffer: Entity<Buffer>,
 6972        ranges: Vec<Range<text::Anchor>>,
 6973        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6974        cx: &mut Context<Self>,
 6975    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6976        let next_hint_id = self.next_hint_id.clone();
 6977        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6978        let query_version = lsp_data.buffer_version.clone();
 6979        let mut lsp_refresh_requested = false;
 6980        let for_server = if let InvalidationStrategy::RefreshRequested {
 6981            server_id,
 6982            request_id,
 6983        } = invalidate
 6984        {
 6985            let invalidated = lsp_data
 6986                .inlay_hints
 6987                .invalidate_for_server_refresh(server_id, request_id);
 6988            lsp_refresh_requested = invalidated;
 6989            Some(server_id)
 6990        } else {
 6991            None
 6992        };
 6993        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6994        let known_chunks = known_chunks
 6995            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6996            .map(|(_, known_chunks)| known_chunks)
 6997            .unwrap_or_default();
 6998
 6999        let buffer_snapshot = buffer.read(cx).snapshot();
 7000        let ranges = ranges
 7001            .iter()
 7002            .map(|range| range.to_point(&buffer_snapshot))
 7003            .collect::<Vec<_>>();
 7004
 7005        let mut hint_fetch_tasks = Vec::new();
 7006        let mut cached_inlay_hints = None;
 7007        let mut ranges_to_query = None;
 7008        let applicable_chunks = existing_inlay_hints
 7009            .applicable_chunks(ranges.as_slice())
 7010            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7011            .collect::<Vec<_>>();
 7012        if applicable_chunks.is_empty() {
 7013            return HashMap::default();
 7014        }
 7015
 7016        for row_chunk in applicable_chunks {
 7017            match (
 7018                existing_inlay_hints
 7019                    .cached_hints(&row_chunk)
 7020                    .filter(|_| !lsp_refresh_requested)
 7021                    .cloned(),
 7022                existing_inlay_hints
 7023                    .fetched_hints(&row_chunk)
 7024                    .as_ref()
 7025                    .filter(|_| !lsp_refresh_requested)
 7026                    .cloned(),
 7027            ) {
 7028                (None, None) => {
 7029                    let chunk_range = row_chunk.anchor_range();
 7030                    ranges_to_query
 7031                        .get_or_insert_with(Vec::new)
 7032                        .push((row_chunk, chunk_range));
 7033                }
 7034                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7035                (Some(cached_hints), None) => {
 7036                    for (server_id, cached_hints) in cached_hints {
 7037                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7038                            cached_inlay_hints
 7039                                .get_or_insert_with(HashMap::default)
 7040                                .entry(row_chunk.row_range())
 7041                                .or_insert_with(HashMap::default)
 7042                                .entry(server_id)
 7043                                .or_insert_with(Vec::new)
 7044                                .extend(cached_hints);
 7045                        }
 7046                    }
 7047                }
 7048                (Some(cached_hints), Some(fetched_hints)) => {
 7049                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7050                    for (server_id, cached_hints) in cached_hints {
 7051                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7052                            cached_inlay_hints
 7053                                .get_or_insert_with(HashMap::default)
 7054                                .entry(row_chunk.row_range())
 7055                                .or_insert_with(HashMap::default)
 7056                                .entry(server_id)
 7057                                .or_insert_with(Vec::new)
 7058                                .extend(cached_hints);
 7059                        }
 7060                    }
 7061                }
 7062            }
 7063        }
 7064
 7065        if hint_fetch_tasks.is_empty()
 7066            && ranges_to_query
 7067                .as_ref()
 7068                .is_none_or(|ranges| ranges.is_empty())
 7069            && let Some(cached_inlay_hints) = cached_inlay_hints
 7070        {
 7071            cached_inlay_hints
 7072                .into_iter()
 7073                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7074                .collect()
 7075        } else {
 7076            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7077                // When a server refresh was requested, other servers' cached hints
 7078                // are unaffected by the refresh and must be included in the result.
 7079                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7080                // removes all visible hints but only adds back the requesting
 7081                // server's new hints, permanently losing other servers' hints.
 7082                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7083                    lsp_data
 7084                        .inlay_hints
 7085                        .cached_hints(&chunk)
 7086                        .cloned()
 7087                        .unwrap_or_default()
 7088                } else {
 7089                    HashMap::default()
 7090                };
 7091
 7092                let next_hint_id = next_hint_id.clone();
 7093                let buffer = buffer.clone();
 7094                let query_version = query_version.clone();
 7095                let new_inlay_hints = cx
 7096                    .spawn(async move |lsp_store, cx| {
 7097                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7098                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7099                        })?;
 7100                        new_fetch_task
 7101                            .await
 7102                            .and_then(|new_hints_by_server| {
 7103                                lsp_store.update(cx, |lsp_store, cx| {
 7104                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7105                                    let update_cache = lsp_data.buffer_version == query_version;
 7106                                    if new_hints_by_server.is_empty() {
 7107                                        if update_cache {
 7108                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7109                                        }
 7110                                        other_servers_cached
 7111                                    } else {
 7112                                        let mut result = other_servers_cached;
 7113                                        for (server_id, new_hints) in new_hints_by_server {
 7114                                            let new_hints = new_hints
 7115                                                .into_iter()
 7116                                                .map(|new_hint| {
 7117                                                    (
 7118                                                        InlayId::Hint(next_hint_id.fetch_add(
 7119                                                            1,
 7120                                                            atomic::Ordering::AcqRel,
 7121                                                        )),
 7122                                                        new_hint,
 7123                                                    )
 7124                                                })
 7125                                                .collect::<Vec<_>>();
 7126                                            if update_cache {
 7127                                                lsp_data.inlay_hints.insert_new_hints(
 7128                                                    chunk,
 7129                                                    server_id,
 7130                                                    new_hints.clone(),
 7131                                                );
 7132                                            }
 7133                                            result.insert(server_id, new_hints);
 7134                                        }
 7135                                        result
 7136                                    }
 7137                                })
 7138                            })
 7139                            .map_err(Arc::new)
 7140                    })
 7141                    .shared();
 7142
 7143                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7144                *fetch_task = Some(new_inlay_hints.clone());
 7145                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7146            }
 7147
 7148            cached_inlay_hints
 7149                .unwrap_or_default()
 7150                .into_iter()
 7151                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7152                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7153                    (
 7154                        chunk.row_range(),
 7155                        cx.spawn(async move |_, _| {
 7156                            hints_fetch.await.map_err(|e| {
 7157                                if e.error_code() != ErrorCode::Internal {
 7158                                    anyhow!(e.error_code())
 7159                                } else {
 7160                                    anyhow!("{e:#}")
 7161                                }
 7162                            })
 7163                        }),
 7164                    )
 7165                }))
 7166                .collect()
 7167        }
 7168    }
 7169
 7170    fn fetch_inlay_hints(
 7171        &mut self,
 7172        for_server: Option<LanguageServerId>,
 7173        buffer: &Entity<Buffer>,
 7174        range: Range<Anchor>,
 7175        cx: &mut Context<Self>,
 7176    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7177        let request = InlayHints {
 7178            range: range.clone(),
 7179        };
 7180        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7181            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7182                return Task::ready(Ok(HashMap::default()));
 7183            }
 7184            let request_timeout = ProjectSettings::get_global(cx)
 7185                .global_lsp_settings
 7186                .get_request_timeout();
 7187            let request_task = upstream_client.request_lsp(
 7188                project_id,
 7189                for_server.map(|id| id.to_proto()),
 7190                request_timeout,
 7191                cx.background_executor().clone(),
 7192                request.to_proto(project_id, buffer.read(cx)),
 7193            );
 7194            let buffer = buffer.clone();
 7195            cx.spawn(async move |weak_lsp_store, cx| {
 7196                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7197                    return Ok(HashMap::default());
 7198                };
 7199                let Some(responses) = request_task.await? else {
 7200                    return Ok(HashMap::default());
 7201                };
 7202
 7203                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7204                    let lsp_store = lsp_store.clone();
 7205                    let buffer = buffer.clone();
 7206                    let cx = cx.clone();
 7207                    let request = request.clone();
 7208                    async move {
 7209                        (
 7210                            LanguageServerId::from_proto(response.server_id),
 7211                            request
 7212                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7213                                .await,
 7214                        )
 7215                    }
 7216                }))
 7217                .await;
 7218
 7219                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7220                let mut has_errors = false;
 7221                let inlay_hints = inlay_hints
 7222                    .into_iter()
 7223                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7224                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7225                        Err(e) => {
 7226                            has_errors = true;
 7227                            log::error!("{e:#}");
 7228                            None
 7229                        }
 7230                    })
 7231                    .map(|(server_id, mut new_hints)| {
 7232                        new_hints.retain(|hint| {
 7233                            hint.position.is_valid(&buffer_snapshot)
 7234                                && range.start.is_valid(&buffer_snapshot)
 7235                                && range.end.is_valid(&buffer_snapshot)
 7236                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7237                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7238                        });
 7239                        (server_id, new_hints)
 7240                    })
 7241                    .collect::<HashMap<_, _>>();
 7242                anyhow::ensure!(
 7243                    !has_errors || !inlay_hints.is_empty(),
 7244                    "Failed to fetch inlay hints"
 7245                );
 7246                Ok(inlay_hints)
 7247            })
 7248        } else {
 7249            let inlay_hints_task = match for_server {
 7250                Some(server_id) => {
 7251                    let server_task = self.request_lsp(
 7252                        buffer.clone(),
 7253                        LanguageServerToQuery::Other(server_id),
 7254                        request,
 7255                        cx,
 7256                    );
 7257                    cx.background_spawn(async move {
 7258                        let mut responses = Vec::new();
 7259                        match server_task.await {
 7260                            Ok(response) => responses.push((server_id, response)),
 7261                            // rust-analyzer likes to error with this when its still loading up
 7262                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7263                            Err(e) => log::error!(
 7264                                "Error handling response for inlay hints request: {e:#}"
 7265                            ),
 7266                        }
 7267                        responses
 7268                    })
 7269                }
 7270                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7271            };
 7272            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7273            cx.background_spawn(async move {
 7274                Ok(inlay_hints_task
 7275                    .await
 7276                    .into_iter()
 7277                    .map(|(server_id, mut new_hints)| {
 7278                        new_hints.retain(|hint| {
 7279                            hint.position.is_valid(&buffer_snapshot)
 7280                                && range.start.is_valid(&buffer_snapshot)
 7281                                && range.end.is_valid(&buffer_snapshot)
 7282                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7283                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7284                        });
 7285                        (server_id, new_hints)
 7286                    })
 7287                    .collect())
 7288            })
 7289        }
 7290    }
 7291
 7292    fn diagnostic_registration_exists(
 7293        &self,
 7294        server_id: LanguageServerId,
 7295        registration_id: &Option<SharedString>,
 7296    ) -> bool {
 7297        let Some(local) = self.as_local() else {
 7298            return false;
 7299        };
 7300        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7301        else {
 7302            return false;
 7303        };
 7304        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7305        registrations.diagnostics.contains_key(&registration_key)
 7306    }
 7307
 7308    pub fn pull_diagnostics_for_buffer(
 7309        &mut self,
 7310        buffer: Entity<Buffer>,
 7311        cx: &mut Context<Self>,
 7312    ) -> Task<anyhow::Result<()>> {
 7313        let diagnostics = self.pull_diagnostics(buffer, cx);
 7314        cx.spawn(async move |lsp_store, cx| {
 7315            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7316                return Ok(());
 7317            };
 7318            lsp_store.update(cx, |lsp_store, cx| {
 7319                if lsp_store.as_local().is_none() {
 7320                    return;
 7321                }
 7322
 7323                let mut unchanged_buffers = HashMap::default();
 7324                let server_diagnostics_updates = diagnostics
 7325                    .into_iter()
 7326                    .filter_map(|diagnostics_set| match diagnostics_set {
 7327                        LspPullDiagnostics::Response {
 7328                            server_id,
 7329                            uri,
 7330                            diagnostics,
 7331                            registration_id,
 7332                        } => Some((server_id, uri, diagnostics, registration_id)),
 7333                        LspPullDiagnostics::Default => None,
 7334                    })
 7335                    .filter(|(server_id, _, _, registration_id)| {
 7336                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7337                    })
 7338                    .fold(
 7339                        HashMap::default(),
 7340                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7341                            let (result_id, diagnostics) = match diagnostics {
 7342                                PulledDiagnostics::Unchanged { result_id } => {
 7343                                    unchanged_buffers
 7344                                        .entry(new_registration_id.clone())
 7345                                        .or_insert_with(HashSet::default)
 7346                                        .insert(uri.clone());
 7347                                    (Some(result_id), Vec::new())
 7348                                }
 7349                                PulledDiagnostics::Changed {
 7350                                    result_id,
 7351                                    diagnostics,
 7352                                } => (result_id, diagnostics),
 7353                            };
 7354                            let disk_based_sources = Cow::Owned(
 7355                                lsp_store
 7356                                    .language_server_adapter_for_id(server_id)
 7357                                    .as_ref()
 7358                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7359                                    .unwrap_or(&[])
 7360                                    .to_vec(),
 7361                            );
 7362                            acc.entry(server_id)
 7363                                .or_insert_with(HashMap::default)
 7364                                .entry(new_registration_id.clone())
 7365                                .or_insert_with(Vec::new)
 7366                                .push(DocumentDiagnosticsUpdate {
 7367                                    server_id,
 7368                                    diagnostics: lsp::PublishDiagnosticsParams {
 7369                                        uri,
 7370                                        diagnostics,
 7371                                        version: None,
 7372                                    },
 7373                                    result_id: result_id.map(SharedString::new),
 7374                                    disk_based_sources,
 7375                                    registration_id: new_registration_id,
 7376                                });
 7377                            acc
 7378                        },
 7379                    );
 7380
 7381                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7382                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7383                        lsp_store
 7384                            .merge_lsp_diagnostics(
 7385                                DiagnosticSourceKind::Pulled,
 7386                                diagnostic_updates,
 7387                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7388                                    DiagnosticSourceKind::Pulled => {
 7389                                        old_diagnostic.registration_id != registration_id
 7390                                            || unchanged_buffers
 7391                                                .get(&old_diagnostic.registration_id)
 7392                                                .is_some_and(|unchanged_buffers| {
 7393                                                    unchanged_buffers.contains(&document_uri)
 7394                                                })
 7395                                    }
 7396                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7397                                        true
 7398                                    }
 7399                                },
 7400                                cx,
 7401                            )
 7402                            .log_err();
 7403                    }
 7404                }
 7405            })
 7406        })
 7407    }
 7408
 7409    pub fn signature_help<T: ToPointUtf16>(
 7410        &mut self,
 7411        buffer: &Entity<Buffer>,
 7412        position: T,
 7413        cx: &mut Context<Self>,
 7414    ) -> Task<Option<Vec<SignatureHelp>>> {
 7415        let position = position.to_point_utf16(buffer.read(cx));
 7416
 7417        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7418            let request = GetSignatureHelp { position };
 7419            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7420                return Task::ready(None);
 7421            }
 7422            let request_timeout = ProjectSettings::get_global(cx)
 7423                .global_lsp_settings
 7424                .get_request_timeout();
 7425            let request_task = client.request_lsp(
 7426                upstream_project_id,
 7427                None,
 7428                request_timeout,
 7429                cx.background_executor().clone(),
 7430                request.to_proto(upstream_project_id, buffer.read(cx)),
 7431            );
 7432            let buffer = buffer.clone();
 7433            cx.spawn(async move |weak_lsp_store, cx| {
 7434                let lsp_store = weak_lsp_store.upgrade()?;
 7435                let signatures = join_all(
 7436                    request_task
 7437                        .await
 7438                        .log_err()
 7439                        .flatten()
 7440                        .map(|response| response.payload)
 7441                        .unwrap_or_default()
 7442                        .into_iter()
 7443                        .map(|response| {
 7444                            let response = GetSignatureHelp { position }.response_from_proto(
 7445                                response.response,
 7446                                lsp_store.clone(),
 7447                                buffer.clone(),
 7448                                cx.clone(),
 7449                            );
 7450                            async move { response.await.log_err().flatten() }
 7451                        }),
 7452                )
 7453                .await
 7454                .into_iter()
 7455                .flatten()
 7456                .collect();
 7457                Some(signatures)
 7458            })
 7459        } else {
 7460            let all_actions_task = self.request_multiple_lsp_locally(
 7461                buffer,
 7462                Some(position),
 7463                GetSignatureHelp { position },
 7464                cx,
 7465            );
 7466            cx.background_spawn(async move {
 7467                Some(
 7468                    all_actions_task
 7469                        .await
 7470                        .into_iter()
 7471                        .flat_map(|(_, actions)| actions)
 7472                        .collect::<Vec<_>>(),
 7473                )
 7474            })
 7475        }
 7476    }
 7477
 7478    pub fn hover(
 7479        &mut self,
 7480        buffer: &Entity<Buffer>,
 7481        position: PointUtf16,
 7482        cx: &mut Context<Self>,
 7483    ) -> Task<Option<Vec<Hover>>> {
 7484        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7485            let request = GetHover { position };
 7486            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7487                return Task::ready(None);
 7488            }
 7489            let request_timeout = ProjectSettings::get_global(cx)
 7490                .global_lsp_settings
 7491                .get_request_timeout();
 7492            let request_task = client.request_lsp(
 7493                upstream_project_id,
 7494                None,
 7495                request_timeout,
 7496                cx.background_executor().clone(),
 7497                request.to_proto(upstream_project_id, buffer.read(cx)),
 7498            );
 7499            let buffer = buffer.clone();
 7500            cx.spawn(async move |weak_lsp_store, cx| {
 7501                let lsp_store = weak_lsp_store.upgrade()?;
 7502                let hovers = join_all(
 7503                    request_task
 7504                        .await
 7505                        .log_err()
 7506                        .flatten()
 7507                        .map(|response| response.payload)
 7508                        .unwrap_or_default()
 7509                        .into_iter()
 7510                        .map(|response| {
 7511                            let response = GetHover { position }.response_from_proto(
 7512                                response.response,
 7513                                lsp_store.clone(),
 7514                                buffer.clone(),
 7515                                cx.clone(),
 7516                            );
 7517                            async move {
 7518                                response
 7519                                    .await
 7520                                    .log_err()
 7521                                    .flatten()
 7522                                    .and_then(remove_empty_hover_blocks)
 7523                            }
 7524                        }),
 7525                )
 7526                .await
 7527                .into_iter()
 7528                .flatten()
 7529                .collect();
 7530                Some(hovers)
 7531            })
 7532        } else {
 7533            let all_actions_task = self.request_multiple_lsp_locally(
 7534                buffer,
 7535                Some(position),
 7536                GetHover { position },
 7537                cx,
 7538            );
 7539            cx.background_spawn(async move {
 7540                Some(
 7541                    all_actions_task
 7542                        .await
 7543                        .into_iter()
 7544                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7545                        .collect::<Vec<Hover>>(),
 7546                )
 7547            })
 7548        }
 7549    }
 7550
 7551    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7552        let language_registry = self.languages.clone();
 7553
 7554        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7555            let request = upstream_client.request(proto::GetProjectSymbols {
 7556                project_id: *project_id,
 7557                query: query.to_string(),
 7558            });
 7559            cx.foreground_executor().spawn(async move {
 7560                let response = request.await?;
 7561                let mut symbols = Vec::new();
 7562                let core_symbols = response
 7563                    .symbols
 7564                    .into_iter()
 7565                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7566                    .collect::<Vec<_>>();
 7567                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7568                    .await;
 7569                Ok(symbols)
 7570            })
 7571        } else if let Some(local) = self.as_local() {
 7572            struct WorkspaceSymbolsResult {
 7573                server_id: LanguageServerId,
 7574                lsp_adapter: Arc<CachedLspAdapter>,
 7575                worktree: WeakEntity<Worktree>,
 7576                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7577            }
 7578
 7579            let mut requests = Vec::new();
 7580            let mut requested_servers = BTreeSet::new();
 7581            let request_timeout = ProjectSettings::get_global(cx)
 7582                .global_lsp_settings
 7583                .get_request_timeout();
 7584
 7585            for (seed, state) in local.language_server_ids.iter() {
 7586                let Some(worktree_handle) = self
 7587                    .worktree_store
 7588                    .read(cx)
 7589                    .worktree_for_id(seed.worktree_id, cx)
 7590                else {
 7591                    continue;
 7592                };
 7593
 7594                let worktree = worktree_handle.read(cx);
 7595                if !worktree.is_visible() {
 7596                    continue;
 7597                }
 7598
 7599                if !requested_servers.insert(state.id) {
 7600                    continue;
 7601                }
 7602
 7603                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7604                    Some(LanguageServerState::Running {
 7605                        adapter, server, ..
 7606                    }) => (adapter.clone(), server),
 7607
 7608                    _ => continue,
 7609                };
 7610
 7611                let supports_workspace_symbol_request =
 7612                    match server.capabilities().workspace_symbol_provider {
 7613                        Some(OneOf::Left(supported)) => supported,
 7614                        Some(OneOf::Right(_)) => true,
 7615                        None => false,
 7616                    };
 7617
 7618                if !supports_workspace_symbol_request {
 7619                    continue;
 7620                }
 7621
 7622                let worktree_handle = worktree_handle.clone();
 7623                let server_id = server.server_id();
 7624                requests.push(
 7625                    server
 7626                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7627                            lsp::WorkspaceSymbolParams {
 7628                                query: query.to_string(),
 7629                                ..Default::default()
 7630                            },
 7631                            request_timeout,
 7632                        )
 7633                        .map(move |response| {
 7634                            let lsp_symbols = response
 7635                                .into_response()
 7636                                .context("workspace symbols request")
 7637                                .log_err()
 7638                                .flatten()
 7639                                .map(|symbol_response| match symbol_response {
 7640                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7641                                        flat_responses
 7642                                            .into_iter()
 7643                                            .map(|lsp_symbol| {
 7644                                                (
 7645                                                    lsp_symbol.name,
 7646                                                    lsp_symbol.kind,
 7647                                                    lsp_symbol.location,
 7648                                                    lsp_symbol.container_name,
 7649                                                )
 7650                                            })
 7651                                            .collect::<Vec<_>>()
 7652                                    }
 7653                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7654                                        nested_responses
 7655                                            .into_iter()
 7656                                            .filter_map(|lsp_symbol| {
 7657                                                let location = match lsp_symbol.location {
 7658                                                    OneOf::Left(location) => location,
 7659                                                    OneOf::Right(_) => {
 7660                                                        log::error!(
 7661                                                            "Unexpected: client capabilities \
 7662                                                            forbid symbol resolutions in \
 7663                                                            workspace.symbol.resolveSupport"
 7664                                                        );
 7665                                                        return None;
 7666                                                    }
 7667                                                };
 7668                                                Some((
 7669                                                    lsp_symbol.name,
 7670                                                    lsp_symbol.kind,
 7671                                                    location,
 7672                                                    lsp_symbol.container_name,
 7673                                                ))
 7674                                            })
 7675                                            .collect::<Vec<_>>()
 7676                                    }
 7677                                })
 7678                                .unwrap_or_default();
 7679
 7680                            WorkspaceSymbolsResult {
 7681                                server_id,
 7682                                lsp_adapter,
 7683                                worktree: worktree_handle.downgrade(),
 7684                                lsp_symbols,
 7685                            }
 7686                        }),
 7687                );
 7688            }
 7689
 7690            cx.spawn(async move |this, cx| {
 7691                let responses = futures::future::join_all(requests).await;
 7692                let this = match this.upgrade() {
 7693                    Some(this) => this,
 7694                    None => return Ok(Vec::new()),
 7695                };
 7696
 7697                let mut symbols = Vec::new();
 7698                for result in responses {
 7699                    let core_symbols = this.update(cx, |this, cx| {
 7700                        result
 7701                            .lsp_symbols
 7702                            .into_iter()
 7703                            .filter_map(
 7704                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7705                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7706                                    let source_worktree = result.worktree.upgrade()?;
 7707                                    let source_worktree_id = source_worktree.read(cx).id();
 7708
 7709                                    let path = if let Some((tree, rel_path)) =
 7710                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7711                                    {
 7712                                        let worktree_id = tree.read(cx).id();
 7713                                        SymbolLocation::InProject(ProjectPath {
 7714                                            worktree_id,
 7715                                            path: rel_path,
 7716                                        })
 7717                                    } else {
 7718                                        SymbolLocation::OutsideProject {
 7719                                            signature: this.symbol_signature(&abs_path),
 7720                                            abs_path: abs_path.into(),
 7721                                        }
 7722                                    };
 7723
 7724                                    Some(CoreSymbol {
 7725                                        source_language_server_id: result.server_id,
 7726                                        language_server_name: result.lsp_adapter.name.clone(),
 7727                                        source_worktree_id,
 7728                                        path,
 7729                                        kind: symbol_kind,
 7730                                        name: collapse_newlines(&symbol_name, ""),
 7731                                        range: range_from_lsp(symbol_location.range),
 7732                                        container_name: container_name
 7733                                            .map(|c| collapse_newlines(&c, "")),
 7734                                    })
 7735                                },
 7736                            )
 7737                            .collect::<Vec<_>>()
 7738                    });
 7739
 7740                    populate_labels_for_symbols(
 7741                        core_symbols,
 7742                        &language_registry,
 7743                        Some(result.lsp_adapter),
 7744                        &mut symbols,
 7745                    )
 7746                    .await;
 7747                }
 7748
 7749                Ok(symbols)
 7750            })
 7751        } else {
 7752            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7753        }
 7754    }
 7755
 7756    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7757        let mut summary = DiagnosticSummary::default();
 7758        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7759            summary.error_count += path_summary.error_count;
 7760            summary.warning_count += path_summary.warning_count;
 7761        }
 7762        summary
 7763    }
 7764
 7765    /// Returns the diagnostic summary for a specific project path.
 7766    pub fn diagnostic_summary_for_path(
 7767        &self,
 7768        project_path: &ProjectPath,
 7769        _: &App,
 7770    ) -> DiagnosticSummary {
 7771        if let Some(summaries) = self
 7772            .diagnostic_summaries
 7773            .get(&project_path.worktree_id)
 7774            .and_then(|map| map.get(&project_path.path))
 7775        {
 7776            let (error_count, warning_count) = summaries.iter().fold(
 7777                (0, 0),
 7778                |(error_count, warning_count), (_language_server_id, summary)| {
 7779                    (
 7780                        error_count + summary.error_count,
 7781                        warning_count + summary.warning_count,
 7782                    )
 7783                },
 7784            );
 7785
 7786            DiagnosticSummary {
 7787                error_count,
 7788                warning_count,
 7789            }
 7790        } else {
 7791            DiagnosticSummary::default()
 7792        }
 7793    }
 7794
 7795    pub fn diagnostic_summaries<'a>(
 7796        &'a self,
 7797        include_ignored: bool,
 7798        cx: &'a App,
 7799    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7800        self.worktree_store
 7801            .read(cx)
 7802            .visible_worktrees(cx)
 7803            .filter_map(|worktree| {
 7804                let worktree = worktree.read(cx);
 7805                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7806            })
 7807            .flat_map(move |(worktree, summaries)| {
 7808                let worktree_id = worktree.id();
 7809                summaries
 7810                    .iter()
 7811                    .filter(move |(path, _)| {
 7812                        include_ignored
 7813                            || worktree
 7814                                .entry_for_path(path.as_ref())
 7815                                .is_some_and(|entry| !entry.is_ignored)
 7816                    })
 7817                    .flat_map(move |(path, summaries)| {
 7818                        summaries.iter().map(move |(server_id, summary)| {
 7819                            (
 7820                                ProjectPath {
 7821                                    worktree_id,
 7822                                    path: path.clone(),
 7823                                },
 7824                                *server_id,
 7825                                *summary,
 7826                            )
 7827                        })
 7828                    })
 7829            })
 7830    }
 7831
 7832    pub fn on_buffer_edited(
 7833        &mut self,
 7834        buffer: Entity<Buffer>,
 7835        cx: &mut Context<Self>,
 7836    ) -> Option<()> {
 7837        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7838            Some(
 7839                self.as_local()?
 7840                    .language_servers_for_buffer(buffer, cx)
 7841                    .map(|i| i.1.clone())
 7842                    .collect(),
 7843            )
 7844        })?;
 7845
 7846        let buffer = buffer.read(cx);
 7847        let file = File::from_dyn(buffer.file())?;
 7848        let abs_path = file.as_local()?.abs_path(cx);
 7849        let uri = lsp::Uri::from_file_path(&abs_path)
 7850            .ok()
 7851            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7852            .log_err()?;
 7853        let next_snapshot = buffer.text_snapshot();
 7854        for language_server in language_servers {
 7855            let language_server = language_server.clone();
 7856
 7857            let buffer_snapshots = self
 7858                .as_local_mut()?
 7859                .buffer_snapshots
 7860                .get_mut(&buffer.remote_id())
 7861                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7862            let previous_snapshot = buffer_snapshots.last()?;
 7863
 7864            let build_incremental_change = || {
 7865                buffer
 7866                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7867                        previous_snapshot.snapshot.version(),
 7868                    )
 7869                    .map(|edit| {
 7870                        let edit_start = edit.new.start.0;
 7871                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7872                        let new_text = next_snapshot
 7873                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7874                            .collect();
 7875                        lsp::TextDocumentContentChangeEvent {
 7876                            range: Some(lsp::Range::new(
 7877                                point_to_lsp(edit_start),
 7878                                point_to_lsp(edit_end),
 7879                            )),
 7880                            range_length: None,
 7881                            text: new_text,
 7882                        }
 7883                    })
 7884                    .collect()
 7885            };
 7886
 7887            let document_sync_kind = language_server
 7888                .capabilities()
 7889                .text_document_sync
 7890                .as_ref()
 7891                .and_then(|sync| match sync {
 7892                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7893                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7894                });
 7895
 7896            let content_changes: Vec<_> = match document_sync_kind {
 7897                Some(lsp::TextDocumentSyncKind::FULL) => {
 7898                    vec![lsp::TextDocumentContentChangeEvent {
 7899                        range: None,
 7900                        range_length: None,
 7901                        text: next_snapshot.text(),
 7902                    }]
 7903                }
 7904                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7905                _ => {
 7906                    #[cfg(any(test, feature = "test-support"))]
 7907                    {
 7908                        build_incremental_change()
 7909                    }
 7910
 7911                    #[cfg(not(any(test, feature = "test-support")))]
 7912                    {
 7913                        continue;
 7914                    }
 7915                }
 7916            };
 7917
 7918            let next_version = previous_snapshot.version + 1;
 7919            buffer_snapshots.push(LspBufferSnapshot {
 7920                version: next_version,
 7921                snapshot: next_snapshot.clone(),
 7922            });
 7923
 7924            language_server
 7925                .notify::<lsp::notification::DidChangeTextDocument>(
 7926                    lsp::DidChangeTextDocumentParams {
 7927                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7928                            uri.clone(),
 7929                            next_version,
 7930                        ),
 7931                        content_changes,
 7932                    },
 7933                )
 7934                .ok();
 7935            self.pull_workspace_diagnostics(language_server.server_id());
 7936        }
 7937
 7938        None
 7939    }
 7940
 7941    pub fn on_buffer_saved(
 7942        &mut self,
 7943        buffer: Entity<Buffer>,
 7944        cx: &mut Context<Self>,
 7945    ) -> Option<()> {
 7946        let file = File::from_dyn(buffer.read(cx).file())?;
 7947        let worktree_id = file.worktree_id(cx);
 7948        let abs_path = file.as_local()?.abs_path(cx);
 7949        let text_document = lsp::TextDocumentIdentifier {
 7950            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7951        };
 7952        let local = self.as_local()?;
 7953
 7954        for server in local.language_servers_for_worktree(worktree_id) {
 7955            if let Some(include_text) = include_text(server.as_ref()) {
 7956                let text = if include_text {
 7957                    Some(buffer.read(cx).text())
 7958                } else {
 7959                    None
 7960                };
 7961                server
 7962                    .notify::<lsp::notification::DidSaveTextDocument>(
 7963                        lsp::DidSaveTextDocumentParams {
 7964                            text_document: text_document.clone(),
 7965                            text,
 7966                        },
 7967                    )
 7968                    .ok();
 7969            }
 7970        }
 7971
 7972        let language_servers = buffer.update(cx, |buffer, cx| {
 7973            local.language_server_ids_for_buffer(buffer, cx)
 7974        });
 7975        for language_server_id in language_servers {
 7976            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7977        }
 7978
 7979        None
 7980    }
 7981
 7982    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7983        maybe!(async move {
 7984            let mut refreshed_servers = HashSet::default();
 7985            let servers = lsp_store
 7986                .update(cx, |lsp_store, cx| {
 7987                    let local = lsp_store.as_local()?;
 7988
 7989                    let servers = local
 7990                        .language_server_ids
 7991                        .iter()
 7992                        .filter_map(|(seed, state)| {
 7993                            let worktree = lsp_store
 7994                                .worktree_store
 7995                                .read(cx)
 7996                                .worktree_for_id(seed.worktree_id, cx);
 7997                            let delegate: Arc<dyn LspAdapterDelegate> =
 7998                                worktree.map(|worktree| {
 7999                                    LocalLspAdapterDelegate::new(
 8000                                        local.languages.clone(),
 8001                                        &local.environment,
 8002                                        cx.weak_entity(),
 8003                                        &worktree,
 8004                                        local.http_client.clone(),
 8005                                        local.fs.clone(),
 8006                                        cx,
 8007                                    )
 8008                                })?;
 8009                            let server_id = state.id;
 8010
 8011                            let states = local.language_servers.get(&server_id)?;
 8012
 8013                            match states {
 8014                                LanguageServerState::Starting { .. } => None,
 8015                                LanguageServerState::Running {
 8016                                    adapter, server, ..
 8017                                } => {
 8018                                    let adapter = adapter.clone();
 8019                                    let server = server.clone();
 8020                                    refreshed_servers.insert(server.name());
 8021                                    let toolchain = seed.toolchain.clone();
 8022                                    Some(cx.spawn(async move |_, cx| {
 8023                                        let settings =
 8024                                            LocalLspStore::workspace_configuration_for_adapter(
 8025                                                adapter.adapter.clone(),
 8026                                                &delegate,
 8027                                                toolchain,
 8028                                                None,
 8029                                                cx,
 8030                                            )
 8031                                            .await
 8032                                            .ok()?;
 8033                                        server
 8034                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8035                                                lsp::DidChangeConfigurationParams { settings },
 8036                                            )
 8037                                            .ok()?;
 8038                                        Some(())
 8039                                    }))
 8040                                }
 8041                            }
 8042                        })
 8043                        .collect::<Vec<_>>();
 8044
 8045                    Some(servers)
 8046                })
 8047                .ok()
 8048                .flatten()?;
 8049
 8050            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8051            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8052            // to stop and unregister its language server wrapper.
 8053            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8054            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8055            let _: Vec<Option<()>> = join_all(servers).await;
 8056
 8057            Some(())
 8058        })
 8059        .await;
 8060    }
 8061
 8062    fn maintain_workspace_config(
 8063        external_refresh_requests: watch::Receiver<()>,
 8064        cx: &mut Context<Self>,
 8065    ) -> Task<Result<()>> {
 8066        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8067        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8068
 8069        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8070            *settings_changed_tx.borrow_mut() = ();
 8071        });
 8072
 8073        let mut joint_future =
 8074            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8075        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8076        // - 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).
 8077        // - 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.
 8078        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8079        // - 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,
 8080        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8081        cx.spawn(async move |this, cx| {
 8082            while let Some(()) = joint_future.next().await {
 8083                this.update(cx, |this, cx| {
 8084                    this.refresh_server_tree(cx);
 8085                })
 8086                .ok();
 8087
 8088                Self::refresh_workspace_configurations(&this, cx).await;
 8089            }
 8090
 8091            drop(settings_observation);
 8092            anyhow::Ok(())
 8093        })
 8094    }
 8095
 8096    pub fn running_language_servers_for_local_buffer<'a>(
 8097        &'a self,
 8098        buffer: &Buffer,
 8099        cx: &mut App,
 8100    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8101        let local = self.as_local();
 8102        let language_server_ids = local
 8103            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8104            .unwrap_or_default();
 8105
 8106        language_server_ids
 8107            .into_iter()
 8108            .filter_map(
 8109                move |server_id| match local?.language_servers.get(&server_id)? {
 8110                    LanguageServerState::Running {
 8111                        adapter, server, ..
 8112                    } => Some((adapter, server)),
 8113                    _ => None,
 8114                },
 8115            )
 8116    }
 8117
 8118    pub fn language_servers_for_local_buffer(
 8119        &self,
 8120        buffer: &Buffer,
 8121        cx: &mut App,
 8122    ) -> Vec<LanguageServerId> {
 8123        let local = self.as_local();
 8124        local
 8125            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8126            .unwrap_or_default()
 8127    }
 8128
 8129    pub fn language_server_for_local_buffer<'a>(
 8130        &'a self,
 8131        buffer: &'a Buffer,
 8132        server_id: LanguageServerId,
 8133        cx: &'a mut App,
 8134    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8135        self.as_local()?
 8136            .language_servers_for_buffer(buffer, cx)
 8137            .find(|(_, s)| s.server_id() == server_id)
 8138    }
 8139
 8140    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8141        self.diagnostic_summaries.remove(&id_to_remove);
 8142        if let Some(local) = self.as_local_mut() {
 8143            let to_remove = local.remove_worktree(id_to_remove, cx);
 8144            for server in to_remove {
 8145                self.language_server_statuses.remove(&server);
 8146            }
 8147        }
 8148    }
 8149
 8150    pub fn shared(
 8151        &mut self,
 8152        project_id: u64,
 8153        downstream_client: AnyProtoClient,
 8154        _: &mut Context<Self>,
 8155    ) {
 8156        self.downstream_client = Some((downstream_client.clone(), project_id));
 8157
 8158        for (server_id, status) in &self.language_server_statuses {
 8159            if let Some(server) = self.language_server_for_id(*server_id) {
 8160                downstream_client
 8161                    .send(proto::StartLanguageServer {
 8162                        project_id,
 8163                        server: Some(proto::LanguageServer {
 8164                            id: server_id.to_proto(),
 8165                            name: status.name.to_string(),
 8166                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8167                        }),
 8168                        capabilities: serde_json::to_string(&server.capabilities())
 8169                            .expect("serializing server LSP capabilities"),
 8170                    })
 8171                    .log_err();
 8172            }
 8173        }
 8174    }
 8175
 8176    pub fn disconnected_from_host(&mut self) {
 8177        self.downstream_client.take();
 8178    }
 8179
 8180    pub fn disconnected_from_ssh_remote(&mut self) {
 8181        if let LspStoreMode::Remote(RemoteLspStore {
 8182            upstream_client, ..
 8183        }) = &mut self.mode
 8184        {
 8185            upstream_client.take();
 8186        }
 8187    }
 8188
 8189    pub(crate) fn set_language_server_statuses_from_proto(
 8190        &mut self,
 8191        project: WeakEntity<Project>,
 8192        language_servers: Vec<proto::LanguageServer>,
 8193        server_capabilities: Vec<String>,
 8194        cx: &mut Context<Self>,
 8195    ) {
 8196        let lsp_logs = cx
 8197            .try_global::<GlobalLogStore>()
 8198            .map(|lsp_store| lsp_store.0.clone());
 8199
 8200        self.language_server_statuses = language_servers
 8201            .into_iter()
 8202            .zip(server_capabilities)
 8203            .map(|(server, server_capabilities)| {
 8204                let server_id = LanguageServerId(server.id as usize);
 8205                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8206                    self.lsp_server_capabilities
 8207                        .insert(server_id, server_capabilities);
 8208                }
 8209
 8210                let name = LanguageServerName::from_proto(server.name);
 8211                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8212
 8213                if let Some(lsp_logs) = &lsp_logs {
 8214                    lsp_logs.update(cx, |lsp_logs, cx| {
 8215                        lsp_logs.add_language_server(
 8216                            // Only remote clients get their language servers set from proto
 8217                            LanguageServerKind::Remote {
 8218                                project: project.clone(),
 8219                            },
 8220                            server_id,
 8221                            Some(name.clone()),
 8222                            worktree,
 8223                            None,
 8224                            cx,
 8225                        );
 8226                    });
 8227                }
 8228
 8229                (
 8230                    server_id,
 8231                    LanguageServerStatus {
 8232                        name,
 8233                        server_version: None,
 8234                        server_readable_version: None,
 8235                        pending_work: Default::default(),
 8236                        has_pending_diagnostic_updates: false,
 8237                        progress_tokens: Default::default(),
 8238                        worktree,
 8239                        binary: None,
 8240                        configuration: None,
 8241                        workspace_folders: BTreeSet::new(),
 8242                        process_id: None,
 8243                    },
 8244                )
 8245            })
 8246            .collect();
 8247    }
 8248
 8249    #[cfg(feature = "test-support")]
 8250    pub fn update_diagnostic_entries(
 8251        &mut self,
 8252        server_id: LanguageServerId,
 8253        abs_path: PathBuf,
 8254        result_id: Option<SharedString>,
 8255        version: Option<i32>,
 8256        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8257        cx: &mut Context<Self>,
 8258    ) -> anyhow::Result<()> {
 8259        self.merge_diagnostic_entries(
 8260            vec![DocumentDiagnosticsUpdate {
 8261                diagnostics: DocumentDiagnostics {
 8262                    diagnostics,
 8263                    document_abs_path: abs_path,
 8264                    version,
 8265                },
 8266                result_id,
 8267                server_id,
 8268                disk_based_sources: Cow::Borrowed(&[]),
 8269                registration_id: None,
 8270            }],
 8271            |_, _, _| false,
 8272            cx,
 8273        )?;
 8274        Ok(())
 8275    }
 8276
 8277    pub fn merge_diagnostic_entries<'a>(
 8278        &mut self,
 8279        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8280        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8281        cx: &mut Context<Self>,
 8282    ) -> anyhow::Result<()> {
 8283        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8284        let mut updated_diagnostics_paths = HashMap::default();
 8285        for mut update in diagnostic_updates {
 8286            let abs_path = &update.diagnostics.document_abs_path;
 8287            let server_id = update.server_id;
 8288            let Some((worktree, relative_path)) =
 8289                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8290            else {
 8291                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8292                return Ok(());
 8293            };
 8294
 8295            let worktree_id = worktree.read(cx).id();
 8296            let project_path = ProjectPath {
 8297                worktree_id,
 8298                path: relative_path,
 8299            };
 8300
 8301            let document_uri = lsp::Uri::from_file_path(abs_path)
 8302                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8303            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8304                let snapshot = buffer_handle.read(cx).snapshot();
 8305                let buffer = buffer_handle.read(cx);
 8306                let reused_diagnostics = buffer
 8307                    .buffer_diagnostics(Some(server_id))
 8308                    .iter()
 8309                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8310                    .map(|v| {
 8311                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8312                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8313                        DiagnosticEntry {
 8314                            range: start..end,
 8315                            diagnostic: v.diagnostic.clone(),
 8316                        }
 8317                    })
 8318                    .collect::<Vec<_>>();
 8319
 8320                self.as_local_mut()
 8321                    .context("cannot merge diagnostics on a remote LspStore")?
 8322                    .update_buffer_diagnostics(
 8323                        &buffer_handle,
 8324                        server_id,
 8325                        Some(update.registration_id),
 8326                        update.result_id,
 8327                        update.diagnostics.version,
 8328                        update.diagnostics.diagnostics.clone(),
 8329                        reused_diagnostics.clone(),
 8330                        cx,
 8331                    )?;
 8332
 8333                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8334            } else if let Some(local) = self.as_local() {
 8335                let reused_diagnostics = local
 8336                    .diagnostics
 8337                    .get(&worktree_id)
 8338                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8339                    .and_then(|diagnostics_by_server_id| {
 8340                        diagnostics_by_server_id
 8341                            .binary_search_by_key(&server_id, |e| e.0)
 8342                            .ok()
 8343                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8344                    })
 8345                    .into_iter()
 8346                    .flatten()
 8347                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8348
 8349                update
 8350                    .diagnostics
 8351                    .diagnostics
 8352                    .extend(reused_diagnostics.cloned());
 8353            }
 8354
 8355            let updated = worktree.update(cx, |worktree, cx| {
 8356                self.update_worktree_diagnostics(
 8357                    worktree.id(),
 8358                    server_id,
 8359                    project_path.path.clone(),
 8360                    update.diagnostics.diagnostics,
 8361                    cx,
 8362                )
 8363            })?;
 8364            match updated {
 8365                ControlFlow::Continue(new_summary) => {
 8366                    if let Some((project_id, new_summary)) = new_summary {
 8367                        match &mut diagnostics_summary {
 8368                            Some(diagnostics_summary) => {
 8369                                diagnostics_summary
 8370                                    .more_summaries
 8371                                    .push(proto::DiagnosticSummary {
 8372                                        path: project_path.path.as_ref().to_proto(),
 8373                                        language_server_id: server_id.0 as u64,
 8374                                        error_count: new_summary.error_count,
 8375                                        warning_count: new_summary.warning_count,
 8376                                    })
 8377                            }
 8378                            None => {
 8379                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8380                                    project_id,
 8381                                    worktree_id: worktree_id.to_proto(),
 8382                                    summary: Some(proto::DiagnosticSummary {
 8383                                        path: project_path.path.as_ref().to_proto(),
 8384                                        language_server_id: server_id.0 as u64,
 8385                                        error_count: new_summary.error_count,
 8386                                        warning_count: new_summary.warning_count,
 8387                                    }),
 8388                                    more_summaries: Vec::new(),
 8389                                })
 8390                            }
 8391                        }
 8392                    }
 8393                    updated_diagnostics_paths
 8394                        .entry(server_id)
 8395                        .or_insert_with(Vec::new)
 8396                        .push(project_path);
 8397                }
 8398                ControlFlow::Break(()) => {}
 8399            }
 8400        }
 8401
 8402        if let Some((diagnostics_summary, (downstream_client, _))) =
 8403            diagnostics_summary.zip(self.downstream_client.as_ref())
 8404        {
 8405            downstream_client.send(diagnostics_summary).log_err();
 8406        }
 8407        for (server_id, paths) in updated_diagnostics_paths {
 8408            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8409        }
 8410        Ok(())
 8411    }
 8412
 8413    fn update_worktree_diagnostics(
 8414        &mut self,
 8415        worktree_id: WorktreeId,
 8416        server_id: LanguageServerId,
 8417        path_in_worktree: Arc<RelPath>,
 8418        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8419        _: &mut Context<Worktree>,
 8420    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8421        let local = match &mut self.mode {
 8422            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8423            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8424        };
 8425
 8426        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8427        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8428        let summaries_by_server_id = summaries_for_tree
 8429            .entry(path_in_worktree.clone())
 8430            .or_default();
 8431
 8432        let old_summary = summaries_by_server_id
 8433            .remove(&server_id)
 8434            .unwrap_or_default();
 8435
 8436        let new_summary = DiagnosticSummary::new(&diagnostics);
 8437        if diagnostics.is_empty() {
 8438            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8439            {
 8440                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8441                    diagnostics_by_server_id.remove(ix);
 8442                }
 8443                if diagnostics_by_server_id.is_empty() {
 8444                    diagnostics_for_tree.remove(&path_in_worktree);
 8445                }
 8446            }
 8447        } else {
 8448            summaries_by_server_id.insert(server_id, new_summary);
 8449            let diagnostics_by_server_id = diagnostics_for_tree
 8450                .entry(path_in_worktree.clone())
 8451                .or_default();
 8452            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8453                Ok(ix) => {
 8454                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8455                }
 8456                Err(ix) => {
 8457                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8458                }
 8459            }
 8460        }
 8461
 8462        if !old_summary.is_empty() || !new_summary.is_empty() {
 8463            if let Some((_, project_id)) = &self.downstream_client {
 8464                Ok(ControlFlow::Continue(Some((
 8465                    *project_id,
 8466                    proto::DiagnosticSummary {
 8467                        path: path_in_worktree.to_proto(),
 8468                        language_server_id: server_id.0 as u64,
 8469                        error_count: new_summary.error_count as u32,
 8470                        warning_count: new_summary.warning_count as u32,
 8471                    },
 8472                ))))
 8473            } else {
 8474                Ok(ControlFlow::Continue(None))
 8475            }
 8476        } else {
 8477            Ok(ControlFlow::Break(()))
 8478        }
 8479    }
 8480
 8481    pub fn open_buffer_for_symbol(
 8482        &mut self,
 8483        symbol: &Symbol,
 8484        cx: &mut Context<Self>,
 8485    ) -> Task<Result<Entity<Buffer>>> {
 8486        if let Some((client, project_id)) = self.upstream_client() {
 8487            let request = client.request(proto::OpenBufferForSymbol {
 8488                project_id,
 8489                symbol: Some(Self::serialize_symbol(symbol)),
 8490            });
 8491            cx.spawn(async move |this, cx| {
 8492                let response = request.await?;
 8493                let buffer_id = BufferId::new(response.buffer_id)?;
 8494                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8495                    .await
 8496            })
 8497        } else if let Some(local) = self.as_local() {
 8498            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8499                seed.worktree_id == symbol.source_worktree_id
 8500                    && state.id == symbol.source_language_server_id
 8501                    && symbol.language_server_name == seed.name
 8502            });
 8503            if !is_valid {
 8504                return Task::ready(Err(anyhow!(
 8505                    "language server for worktree and language not found"
 8506                )));
 8507            };
 8508
 8509            let symbol_abs_path = match &symbol.path {
 8510                SymbolLocation::InProject(project_path) => self
 8511                    .worktree_store
 8512                    .read(cx)
 8513                    .absolutize(&project_path, cx)
 8514                    .context("no such worktree"),
 8515                SymbolLocation::OutsideProject {
 8516                    abs_path,
 8517                    signature: _,
 8518                } => Ok(abs_path.to_path_buf()),
 8519            };
 8520            let symbol_abs_path = match symbol_abs_path {
 8521                Ok(abs_path) => abs_path,
 8522                Err(err) => return Task::ready(Err(err)),
 8523            };
 8524            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8525                uri
 8526            } else {
 8527                return Task::ready(Err(anyhow!("invalid symbol path")));
 8528            };
 8529
 8530            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8531        } else {
 8532            Task::ready(Err(anyhow!("no upstream client or local store")))
 8533        }
 8534    }
 8535
 8536    pub(crate) fn open_local_buffer_via_lsp(
 8537        &mut self,
 8538        abs_path: lsp::Uri,
 8539        language_server_id: LanguageServerId,
 8540        cx: &mut Context<Self>,
 8541    ) -> Task<Result<Entity<Buffer>>> {
 8542        let path_style = self.worktree_store.read(cx).path_style();
 8543        cx.spawn(async move |lsp_store, cx| {
 8544            // Escape percent-encoded string.
 8545            let current_scheme = abs_path.scheme().to_owned();
 8546            // Uri is immutable, so we can't modify the scheme
 8547
 8548            let abs_path = abs_path
 8549                .to_file_path_ext(path_style)
 8550                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8551            let p = abs_path.clone();
 8552            let yarn_worktree = lsp_store
 8553                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8554                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8555                        cx.spawn(async move |this, cx| {
 8556                            let t = this
 8557                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8558                                .ok()?;
 8559                            t.await
 8560                        })
 8561                    }),
 8562                    None => Task::ready(None),
 8563                })?
 8564                .await;
 8565            let (worktree_root_target, known_relative_path) =
 8566                if let Some((zip_root, relative_path)) = yarn_worktree {
 8567                    (zip_root, Some(relative_path))
 8568                } else {
 8569                    (Arc::<Path>::from(abs_path.as_path()), None)
 8570                };
 8571            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8572                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8573                    worktree_store.find_worktree(&worktree_root_target, cx)
 8574                })
 8575            })?;
 8576            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8577                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8578                (result.0, relative_path, None)
 8579            } else {
 8580                let worktree = lsp_store
 8581                    .update(cx, |lsp_store, cx| {
 8582                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8583                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8584                        })
 8585                    })?
 8586                    .await?;
 8587                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8588                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8589                    lsp_store
 8590                        .update(cx, |lsp_store, cx| {
 8591                            if let Some(local) = lsp_store.as_local_mut() {
 8592                                local.register_language_server_for_invisible_worktree(
 8593                                    &worktree,
 8594                                    language_server_id,
 8595                                    cx,
 8596                                )
 8597                            }
 8598                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8599                                Some(status) => status.worktree,
 8600                                None => None,
 8601                            }
 8602                        })
 8603                        .ok()
 8604                        .flatten()
 8605                        .zip(Some(worktree_root.clone()))
 8606                } else {
 8607                    None
 8608                };
 8609                let relative_path = if let Some(known_path) = known_relative_path {
 8610                    known_path
 8611                } else {
 8612                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8613                        .into_arc()
 8614                };
 8615                (worktree, relative_path, source_ws)
 8616            };
 8617            let project_path = ProjectPath {
 8618                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8619                path: relative_path,
 8620            };
 8621            let buffer = lsp_store
 8622                .update(cx, |lsp_store, cx| {
 8623                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8624                        buffer_store.open_buffer(project_path, cx)
 8625                    })
 8626                })?
 8627                .await?;
 8628            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8629            if let Some((source_ws, worktree_root)) = source_ws {
 8630                buffer.update(cx, |buffer, cx| {
 8631                    let settings = WorktreeSettings::get(
 8632                        Some(
 8633                            (&ProjectPath {
 8634                                worktree_id: source_ws,
 8635                                path: Arc::from(RelPath::empty()),
 8636                            })
 8637                                .into(),
 8638                        ),
 8639                        cx,
 8640                    );
 8641                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8642                    if is_read_only {
 8643                        buffer.set_capability(Capability::ReadOnly, cx);
 8644                    }
 8645                });
 8646            }
 8647            Ok(buffer)
 8648        })
 8649    }
 8650
 8651    fn local_lsp_servers_for_buffer(
 8652        &self,
 8653        buffer: &Entity<Buffer>,
 8654        cx: &mut Context<Self>,
 8655    ) -> Vec<LanguageServerId> {
 8656        let Some(local) = self.as_local() else {
 8657            return Vec::new();
 8658        };
 8659
 8660        let snapshot = buffer.read(cx).snapshot();
 8661
 8662        buffer.update(cx, |buffer, cx| {
 8663            local
 8664                .language_servers_for_buffer(buffer, cx)
 8665                .map(|(_, server)| server.server_id())
 8666                .filter(|server_id| {
 8667                    self.as_local().is_none_or(|local| {
 8668                        local
 8669                            .buffers_opened_in_servers
 8670                            .get(&snapshot.remote_id())
 8671                            .is_some_and(|servers| servers.contains(server_id))
 8672                    })
 8673                })
 8674                .collect()
 8675        })
 8676    }
 8677
 8678    fn request_multiple_lsp_locally<P, R>(
 8679        &mut self,
 8680        buffer: &Entity<Buffer>,
 8681        position: Option<P>,
 8682        request: R,
 8683        cx: &mut Context<Self>,
 8684    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8685    where
 8686        P: ToOffset,
 8687        R: LspCommand + Clone,
 8688        <R::LspRequest as lsp::request::Request>::Result: Send,
 8689        <R::LspRequest as lsp::request::Request>::Params: Send,
 8690    {
 8691        let Some(local) = self.as_local() else {
 8692            return Task::ready(Vec::new());
 8693        };
 8694
 8695        let snapshot = buffer.read(cx).snapshot();
 8696        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8697
 8698        let server_ids = buffer.update(cx, |buffer, cx| {
 8699            local
 8700                .language_servers_for_buffer(buffer, cx)
 8701                .filter(|(adapter, _)| {
 8702                    scope
 8703                        .as_ref()
 8704                        .map(|scope| scope.language_allowed(&adapter.name))
 8705                        .unwrap_or(true)
 8706                })
 8707                .map(|(_, server)| server.server_id())
 8708                .filter(|server_id| {
 8709                    self.as_local().is_none_or(|local| {
 8710                        local
 8711                            .buffers_opened_in_servers
 8712                            .get(&snapshot.remote_id())
 8713                            .is_some_and(|servers| servers.contains(server_id))
 8714                    })
 8715                })
 8716                .collect::<Vec<_>>()
 8717        });
 8718
 8719        let mut response_results = server_ids
 8720            .into_iter()
 8721            .map(|server_id| {
 8722                let task = self.request_lsp(
 8723                    buffer.clone(),
 8724                    LanguageServerToQuery::Other(server_id),
 8725                    request.clone(),
 8726                    cx,
 8727                );
 8728                async move { (server_id, task.await) }
 8729            })
 8730            .collect::<FuturesUnordered<_>>();
 8731
 8732        cx.background_spawn(async move {
 8733            let mut responses = Vec::with_capacity(response_results.len());
 8734            while let Some((server_id, response_result)) = response_results.next().await {
 8735                match response_result {
 8736                    Ok(response) => responses.push((server_id, response)),
 8737                    // rust-analyzer likes to error with this when its still loading up
 8738                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8739                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8740                }
 8741            }
 8742            responses
 8743        })
 8744    }
 8745
 8746    async fn handle_lsp_get_completions(
 8747        this: Entity<Self>,
 8748        envelope: TypedEnvelope<proto::GetCompletions>,
 8749        mut cx: AsyncApp,
 8750    ) -> Result<proto::GetCompletionsResponse> {
 8751        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8752
 8753        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8754        let buffer_handle = this.update(&mut cx, |this, cx| {
 8755            this.buffer_store.read(cx).get_existing(buffer_id)
 8756        })?;
 8757        let request = GetCompletions::from_proto(
 8758            envelope.payload,
 8759            this.clone(),
 8760            buffer_handle.clone(),
 8761            cx.clone(),
 8762        )
 8763        .await?;
 8764
 8765        let server_to_query = match request.server_id {
 8766            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8767            None => LanguageServerToQuery::FirstCapable,
 8768        };
 8769
 8770        let response = this
 8771            .update(&mut cx, |this, cx| {
 8772                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8773            })
 8774            .await?;
 8775        this.update(&mut cx, |this, cx| {
 8776            Ok(GetCompletions::response_to_proto(
 8777                response,
 8778                this,
 8779                sender_id,
 8780                &buffer_handle.read(cx).version(),
 8781                cx,
 8782            ))
 8783        })
 8784    }
 8785
 8786    async fn handle_lsp_command<T: LspCommand>(
 8787        this: Entity<Self>,
 8788        envelope: TypedEnvelope<T::ProtoRequest>,
 8789        mut cx: AsyncApp,
 8790    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8791    where
 8792        <T::LspRequest as lsp::request::Request>::Params: Send,
 8793        <T::LspRequest as lsp::request::Request>::Result: Send,
 8794    {
 8795        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8796        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8797        let buffer_handle = this.update(&mut cx, |this, cx| {
 8798            this.buffer_store.read(cx).get_existing(buffer_id)
 8799        })?;
 8800        let request = T::from_proto(
 8801            envelope.payload,
 8802            this.clone(),
 8803            buffer_handle.clone(),
 8804            cx.clone(),
 8805        )
 8806        .await?;
 8807        let response = this
 8808            .update(&mut cx, |this, cx| {
 8809                this.request_lsp(
 8810                    buffer_handle.clone(),
 8811                    LanguageServerToQuery::FirstCapable,
 8812                    request,
 8813                    cx,
 8814                )
 8815            })
 8816            .await?;
 8817        this.update(&mut cx, |this, cx| {
 8818            Ok(T::response_to_proto(
 8819                response,
 8820                this,
 8821                sender_id,
 8822                &buffer_handle.read(cx).version(),
 8823                cx,
 8824            ))
 8825        })
 8826    }
 8827
 8828    async fn handle_lsp_query(
 8829        lsp_store: Entity<Self>,
 8830        envelope: TypedEnvelope<proto::LspQuery>,
 8831        mut cx: AsyncApp,
 8832    ) -> Result<proto::Ack> {
 8833        use proto::lsp_query::Request;
 8834        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8835        let lsp_query = envelope.payload;
 8836        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8837        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8838        match lsp_query.request.context("invalid LSP query request")? {
 8839            Request::GetReferences(get_references) => {
 8840                let position = get_references.position.clone().and_then(deserialize_anchor);
 8841                Self::query_lsp_locally::<GetReferences>(
 8842                    lsp_store,
 8843                    server_id,
 8844                    sender_id,
 8845                    lsp_request_id,
 8846                    get_references,
 8847                    position,
 8848                    &mut cx,
 8849                )
 8850                .await?;
 8851            }
 8852            Request::GetDocumentColor(get_document_color) => {
 8853                Self::query_lsp_locally::<GetDocumentColor>(
 8854                    lsp_store,
 8855                    server_id,
 8856                    sender_id,
 8857                    lsp_request_id,
 8858                    get_document_color,
 8859                    None,
 8860                    &mut cx,
 8861                )
 8862                .await?;
 8863            }
 8864            Request::GetFoldingRanges(get_folding_ranges) => {
 8865                Self::query_lsp_locally::<GetFoldingRanges>(
 8866                    lsp_store,
 8867                    server_id,
 8868                    sender_id,
 8869                    lsp_request_id,
 8870                    get_folding_ranges,
 8871                    None,
 8872                    &mut cx,
 8873                )
 8874                .await?;
 8875            }
 8876            Request::GetDocumentSymbols(get_document_symbols) => {
 8877                Self::query_lsp_locally::<GetDocumentSymbols>(
 8878                    lsp_store,
 8879                    server_id,
 8880                    sender_id,
 8881                    lsp_request_id,
 8882                    get_document_symbols,
 8883                    None,
 8884                    &mut cx,
 8885                )
 8886                .await?;
 8887            }
 8888            Request::GetHover(get_hover) => {
 8889                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8890                Self::query_lsp_locally::<GetHover>(
 8891                    lsp_store,
 8892                    server_id,
 8893                    sender_id,
 8894                    lsp_request_id,
 8895                    get_hover,
 8896                    position,
 8897                    &mut cx,
 8898                )
 8899                .await?;
 8900            }
 8901            Request::GetCodeActions(get_code_actions) => {
 8902                Self::query_lsp_locally::<GetCodeActions>(
 8903                    lsp_store,
 8904                    server_id,
 8905                    sender_id,
 8906                    lsp_request_id,
 8907                    get_code_actions,
 8908                    None,
 8909                    &mut cx,
 8910                )
 8911                .await?;
 8912            }
 8913            Request::GetSignatureHelp(get_signature_help) => {
 8914                let position = get_signature_help
 8915                    .position
 8916                    .clone()
 8917                    .and_then(deserialize_anchor);
 8918                Self::query_lsp_locally::<GetSignatureHelp>(
 8919                    lsp_store,
 8920                    server_id,
 8921                    sender_id,
 8922                    lsp_request_id,
 8923                    get_signature_help,
 8924                    position,
 8925                    &mut cx,
 8926                )
 8927                .await?;
 8928            }
 8929            Request::GetCodeLens(get_code_lens) => {
 8930                Self::query_lsp_locally::<GetCodeLens>(
 8931                    lsp_store,
 8932                    server_id,
 8933                    sender_id,
 8934                    lsp_request_id,
 8935                    get_code_lens,
 8936                    None,
 8937                    &mut cx,
 8938                )
 8939                .await?;
 8940            }
 8941            Request::GetDefinition(get_definition) => {
 8942                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8943                Self::query_lsp_locally::<GetDefinitions>(
 8944                    lsp_store,
 8945                    server_id,
 8946                    sender_id,
 8947                    lsp_request_id,
 8948                    get_definition,
 8949                    position,
 8950                    &mut cx,
 8951                )
 8952                .await?;
 8953            }
 8954            Request::GetDeclaration(get_declaration) => {
 8955                let position = get_declaration
 8956                    .position
 8957                    .clone()
 8958                    .and_then(deserialize_anchor);
 8959                Self::query_lsp_locally::<GetDeclarations>(
 8960                    lsp_store,
 8961                    server_id,
 8962                    sender_id,
 8963                    lsp_request_id,
 8964                    get_declaration,
 8965                    position,
 8966                    &mut cx,
 8967                )
 8968                .await?;
 8969            }
 8970            Request::GetTypeDefinition(get_type_definition) => {
 8971                let position = get_type_definition
 8972                    .position
 8973                    .clone()
 8974                    .and_then(deserialize_anchor);
 8975                Self::query_lsp_locally::<GetTypeDefinitions>(
 8976                    lsp_store,
 8977                    server_id,
 8978                    sender_id,
 8979                    lsp_request_id,
 8980                    get_type_definition,
 8981                    position,
 8982                    &mut cx,
 8983                )
 8984                .await?;
 8985            }
 8986            Request::GetImplementation(get_implementation) => {
 8987                let position = get_implementation
 8988                    .position
 8989                    .clone()
 8990                    .and_then(deserialize_anchor);
 8991                Self::query_lsp_locally::<GetImplementations>(
 8992                    lsp_store,
 8993                    server_id,
 8994                    sender_id,
 8995                    lsp_request_id,
 8996                    get_implementation,
 8997                    position,
 8998                    &mut cx,
 8999                )
 9000                .await?;
 9001            }
 9002            Request::InlayHints(inlay_hints) => {
 9003                let query_start = inlay_hints
 9004                    .start
 9005                    .clone()
 9006                    .and_then(deserialize_anchor)
 9007                    .context("invalid inlay hints range start")?;
 9008                let query_end = inlay_hints
 9009                    .end
 9010                    .clone()
 9011                    .and_then(deserialize_anchor)
 9012                    .context("invalid inlay hints range end")?;
 9013                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9014                    &lsp_store,
 9015                    server_id,
 9016                    lsp_request_id,
 9017                    &inlay_hints,
 9018                    query_start..query_end,
 9019                    &mut cx,
 9020                )
 9021                .await
 9022                .context("preparing inlay hints request")?;
 9023                Self::query_lsp_locally::<InlayHints>(
 9024                    lsp_store,
 9025                    server_id,
 9026                    sender_id,
 9027                    lsp_request_id,
 9028                    inlay_hints,
 9029                    None,
 9030                    &mut cx,
 9031                )
 9032                .await
 9033                .context("querying for inlay hints")?
 9034            }
 9035            //////////////////////////////
 9036            // Below are LSP queries that need to fetch more data,
 9037            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9038            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9039                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9040                    &lsp_store,
 9041                    &get_document_diagnostics,
 9042                    &mut cx,
 9043                )
 9044                .await?;
 9045                lsp_store.update(&mut cx, |lsp_store, cx| {
 9046                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9047                    let key = LspKey {
 9048                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9049                        server_queried: server_id,
 9050                    };
 9051                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9052                    ) {
 9053                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9054                            lsp_requests.clear();
 9055                        };
 9056                    }
 9057
 9058                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9059                        lsp_request_id,
 9060                        cx.spawn(async move |lsp_store, cx| {
 9061                            let diagnostics_pull = lsp_store
 9062                                .update(cx, |lsp_store, cx| {
 9063                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9064                                })
 9065                                .ok();
 9066                            if let Some(diagnostics_pull) = diagnostics_pull {
 9067                                match diagnostics_pull.await {
 9068                                    Ok(()) => {}
 9069                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9070                                };
 9071                            }
 9072                        }),
 9073                    );
 9074                });
 9075            }
 9076            Request::SemanticTokens(semantic_tokens) => {
 9077                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9078                    &lsp_store,
 9079                    &semantic_tokens,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9084                lsp_store.update(&mut cx, |lsp_store, cx| {
 9085                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9086                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9087                        let key = LspKey {
 9088                            request_type: TypeId::of::<SemanticTokensFull>(),
 9089                            server_queried: server_id,
 9090                        };
 9091                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9092                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9093                                lsp_requests.clear();
 9094                            };
 9095                        }
 9096
 9097                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9098                            lsp_request_id,
 9099                            cx.spawn(async move |lsp_store, cx| {
 9100                                let tokens_fetch = lsp_store
 9101                                    .update(cx, |lsp_store, cx| {
 9102                                        lsp_store
 9103                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9104                                    })
 9105                                    .ok();
 9106                                if let Some(tokens_fetch) = tokens_fetch {
 9107                                    let new_tokens = tokens_fetch.await;
 9108                                    if let Some(new_tokens) = new_tokens {
 9109                                        lsp_store
 9110                                            .update(cx, |lsp_store, cx| {
 9111                                                let response = new_tokens
 9112                                                    .into_iter()
 9113                                                    .map(|(server_id, response)| {
 9114                                                        (
 9115                                                            server_id.to_proto(),
 9116                                                            SemanticTokensFull::response_to_proto(
 9117                                                                response,
 9118                                                                lsp_store,
 9119                                                                sender_id,
 9120                                                                &buffer_version,
 9121                                                                cx,
 9122                                                            ),
 9123                                                        )
 9124                                                    })
 9125                                                    .collect::<HashMap<_, _>>();
 9126                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9127                                                    project_id,
 9128                                                    lsp_request_id,
 9129                                                    response,
 9130                                                ) {
 9131                                                    Ok(()) => {}
 9132                                                    Err(e) => {
 9133                                                        log::error!(
 9134                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9135                                                        )
 9136                                                    }
 9137                                                }
 9138                                            })
 9139                                            .ok();
 9140                                    }
 9141                                }
 9142                            }),
 9143                        );
 9144                    }
 9145                });
 9146            }
 9147        }
 9148        Ok(proto::Ack {})
 9149    }
 9150
 9151    async fn handle_lsp_query_response(
 9152        lsp_store: Entity<Self>,
 9153        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9154        cx: AsyncApp,
 9155    ) -> Result<()> {
 9156        lsp_store.read_with(&cx, |lsp_store, _| {
 9157            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9158                upstream_client.handle_lsp_response(envelope.clone());
 9159            }
 9160        });
 9161        Ok(())
 9162    }
 9163
 9164    async fn handle_apply_code_action(
 9165        this: Entity<Self>,
 9166        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9167        mut cx: AsyncApp,
 9168    ) -> Result<proto::ApplyCodeActionResponse> {
 9169        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9170        let action =
 9171            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9172        let apply_code_action = this.update(&mut cx, |this, cx| {
 9173            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9174            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9175            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9176        })?;
 9177
 9178        let project_transaction = apply_code_action.await?;
 9179        let project_transaction = this.update(&mut cx, |this, cx| {
 9180            this.buffer_store.update(cx, |buffer_store, cx| {
 9181                buffer_store.serialize_project_transaction_for_peer(
 9182                    project_transaction,
 9183                    sender_id,
 9184                    cx,
 9185                )
 9186            })
 9187        });
 9188        Ok(proto::ApplyCodeActionResponse {
 9189            transaction: Some(project_transaction),
 9190        })
 9191    }
 9192
 9193    async fn handle_register_buffer_with_language_servers(
 9194        this: Entity<Self>,
 9195        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9196        mut cx: AsyncApp,
 9197    ) -> Result<proto::Ack> {
 9198        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9199        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9200        this.update(&mut cx, |this, cx| {
 9201            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9202                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9203                    project_id: upstream_project_id,
 9204                    buffer_id: buffer_id.to_proto(),
 9205                    only_servers: envelope.payload.only_servers,
 9206                });
 9207            }
 9208
 9209            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9210                anyhow::bail!("buffer is not open");
 9211            };
 9212
 9213            let handle = this.register_buffer_with_language_servers(
 9214                &buffer,
 9215                envelope
 9216                    .payload
 9217                    .only_servers
 9218                    .into_iter()
 9219                    .filter_map(|selector| {
 9220                        Some(match selector.selector? {
 9221                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9222                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9223                            }
 9224                            proto::language_server_selector::Selector::Name(name) => {
 9225                                LanguageServerSelector::Name(LanguageServerName(
 9226                                    SharedString::from(name),
 9227                                ))
 9228                            }
 9229                        })
 9230                    })
 9231                    .collect(),
 9232                false,
 9233                cx,
 9234            );
 9235            // Pull diagnostics for the buffer even if it was already registered.
 9236            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9237            // but it's unclear if we need it.
 9238            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9239                .detach();
 9240            this.buffer_store().update(cx, |buffer_store, _| {
 9241                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9242            });
 9243
 9244            Ok(())
 9245        })?;
 9246        Ok(proto::Ack {})
 9247    }
 9248
 9249    async fn handle_rename_project_entry(
 9250        this: Entity<Self>,
 9251        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9252        mut cx: AsyncApp,
 9253    ) -> Result<proto::ProjectEntryResponse> {
 9254        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9255        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9256        let new_path =
 9257            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9258
 9259        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9260            .update(&mut cx, |this, cx| {
 9261                let (worktree, entry) = this
 9262                    .worktree_store
 9263                    .read(cx)
 9264                    .worktree_and_entry_for_id(entry_id, cx)?;
 9265                let new_worktree = this
 9266                    .worktree_store
 9267                    .read(cx)
 9268                    .worktree_for_id(new_worktree_id, cx)?;
 9269                Some((
 9270                    this.worktree_store.clone(),
 9271                    worktree,
 9272                    new_worktree,
 9273                    entry.clone(),
 9274                ))
 9275            })
 9276            .context("worktree not found")?;
 9277        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9278            (worktree.absolutize(&old_entry.path), worktree.id())
 9279        });
 9280        let new_abs_path =
 9281            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9282
 9283        let _transaction = Self::will_rename_entry(
 9284            this.downgrade(),
 9285            old_worktree_id,
 9286            &old_abs_path,
 9287            &new_abs_path,
 9288            old_entry.is_dir(),
 9289            cx.clone(),
 9290        )
 9291        .await;
 9292        let response = WorktreeStore::handle_rename_project_entry(
 9293            worktree_store,
 9294            envelope.payload,
 9295            cx.clone(),
 9296        )
 9297        .await;
 9298        this.read_with(&cx, |this, _| {
 9299            this.did_rename_entry(
 9300                old_worktree_id,
 9301                &old_abs_path,
 9302                &new_abs_path,
 9303                old_entry.is_dir(),
 9304            );
 9305        });
 9306        response
 9307    }
 9308
 9309    async fn handle_update_diagnostic_summary(
 9310        this: Entity<Self>,
 9311        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9312        mut cx: AsyncApp,
 9313    ) -> Result<()> {
 9314        this.update(&mut cx, |lsp_store, cx| {
 9315            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9316            let mut updated_diagnostics_paths = HashMap::default();
 9317            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9318            for message_summary in envelope
 9319                .payload
 9320                .summary
 9321                .into_iter()
 9322                .chain(envelope.payload.more_summaries)
 9323            {
 9324                let project_path = ProjectPath {
 9325                    worktree_id,
 9326                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9327                };
 9328                let path = project_path.path.clone();
 9329                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9330                let summary = DiagnosticSummary {
 9331                    error_count: message_summary.error_count as usize,
 9332                    warning_count: message_summary.warning_count as usize,
 9333                };
 9334
 9335                if summary.is_empty() {
 9336                    if let Some(worktree_summaries) =
 9337                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9338                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9339                    {
 9340                        summaries.remove(&server_id);
 9341                        if summaries.is_empty() {
 9342                            worktree_summaries.remove(&path);
 9343                        }
 9344                    }
 9345                } else {
 9346                    lsp_store
 9347                        .diagnostic_summaries
 9348                        .entry(worktree_id)
 9349                        .or_default()
 9350                        .entry(path)
 9351                        .or_default()
 9352                        .insert(server_id, summary);
 9353                }
 9354
 9355                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9356                    match &mut diagnostics_summary {
 9357                        Some(diagnostics_summary) => {
 9358                            diagnostics_summary
 9359                                .more_summaries
 9360                                .push(proto::DiagnosticSummary {
 9361                                    path: project_path.path.as_ref().to_proto(),
 9362                                    language_server_id: server_id.0 as u64,
 9363                                    error_count: summary.error_count as u32,
 9364                                    warning_count: summary.warning_count as u32,
 9365                                })
 9366                        }
 9367                        None => {
 9368                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9369                                project_id: *project_id,
 9370                                worktree_id: worktree_id.to_proto(),
 9371                                summary: Some(proto::DiagnosticSummary {
 9372                                    path: project_path.path.as_ref().to_proto(),
 9373                                    language_server_id: server_id.0 as u64,
 9374                                    error_count: summary.error_count as u32,
 9375                                    warning_count: summary.warning_count as u32,
 9376                                }),
 9377                                more_summaries: Vec::new(),
 9378                            })
 9379                        }
 9380                    }
 9381                }
 9382                updated_diagnostics_paths
 9383                    .entry(server_id)
 9384                    .or_insert_with(Vec::new)
 9385                    .push(project_path);
 9386            }
 9387
 9388            if let Some((diagnostics_summary, (downstream_client, _))) =
 9389                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9390            {
 9391                downstream_client.send(diagnostics_summary).log_err();
 9392            }
 9393            for (server_id, paths) in updated_diagnostics_paths {
 9394                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9395            }
 9396            Ok(())
 9397        })
 9398    }
 9399
 9400    async fn handle_start_language_server(
 9401        lsp_store: Entity<Self>,
 9402        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9403        mut cx: AsyncApp,
 9404    ) -> Result<()> {
 9405        let server = envelope.payload.server.context("invalid server")?;
 9406        let server_capabilities =
 9407            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9408                .with_context(|| {
 9409                    format!(
 9410                        "incorrect server capabilities {}",
 9411                        envelope.payload.capabilities
 9412                    )
 9413                })?;
 9414        lsp_store.update(&mut cx, |lsp_store, cx| {
 9415            let server_id = LanguageServerId(server.id as usize);
 9416            let server_name = LanguageServerName::from_proto(server.name.clone());
 9417            lsp_store
 9418                .lsp_server_capabilities
 9419                .insert(server_id, server_capabilities);
 9420            lsp_store.language_server_statuses.insert(
 9421                server_id,
 9422                LanguageServerStatus {
 9423                    name: server_name.clone(),
 9424                    server_version: None,
 9425                    server_readable_version: None,
 9426                    pending_work: Default::default(),
 9427                    has_pending_diagnostic_updates: false,
 9428                    progress_tokens: Default::default(),
 9429                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9430                    binary: None,
 9431                    configuration: None,
 9432                    workspace_folders: BTreeSet::new(),
 9433                    process_id: None,
 9434                },
 9435            );
 9436            cx.emit(LspStoreEvent::LanguageServerAdded(
 9437                server_id,
 9438                server_name,
 9439                server.worktree_id.map(WorktreeId::from_proto),
 9440            ));
 9441            cx.notify();
 9442        });
 9443        Ok(())
 9444    }
 9445
 9446    async fn handle_update_language_server(
 9447        lsp_store: Entity<Self>,
 9448        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9449        mut cx: AsyncApp,
 9450    ) -> Result<()> {
 9451        lsp_store.update(&mut cx, |lsp_store, cx| {
 9452            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9453
 9454            match envelope.payload.variant.context("invalid variant")? {
 9455                proto::update_language_server::Variant::WorkStart(payload) => {
 9456                    lsp_store.on_lsp_work_start(
 9457                        language_server_id,
 9458                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9459                            .context("invalid progress token value")?,
 9460                        LanguageServerProgress {
 9461                            title: payload.title,
 9462                            is_disk_based_diagnostics_progress: false,
 9463                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9464                            message: payload.message,
 9465                            percentage: payload.percentage.map(|p| p as usize),
 9466                            last_update_at: cx.background_executor().now(),
 9467                        },
 9468                        cx,
 9469                    );
 9470                }
 9471                proto::update_language_server::Variant::WorkProgress(payload) => {
 9472                    lsp_store.on_lsp_work_progress(
 9473                        language_server_id,
 9474                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9475                            .context("invalid progress token value")?,
 9476                        LanguageServerProgress {
 9477                            title: None,
 9478                            is_disk_based_diagnostics_progress: false,
 9479                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9480                            message: payload.message,
 9481                            percentage: payload.percentage.map(|p| p as usize),
 9482                            last_update_at: cx.background_executor().now(),
 9483                        },
 9484                        cx,
 9485                    );
 9486                }
 9487
 9488                proto::update_language_server::Variant::WorkEnd(payload) => {
 9489                    lsp_store.on_lsp_work_end(
 9490                        language_server_id,
 9491                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9492                            .context("invalid progress token value")?,
 9493                        cx,
 9494                    );
 9495                }
 9496
 9497                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9498                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9499                }
 9500
 9501                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9502                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9503                }
 9504
 9505                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9506                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9507                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9508                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9509                        language_server_id,
 9510                        name: envelope
 9511                            .payload
 9512                            .server_name
 9513                            .map(SharedString::new)
 9514                            .map(LanguageServerName),
 9515                        message: non_lsp,
 9516                    });
 9517                }
 9518            }
 9519
 9520            Ok(())
 9521        })
 9522    }
 9523
 9524    async fn handle_language_server_log(
 9525        this: Entity<Self>,
 9526        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9527        mut cx: AsyncApp,
 9528    ) -> Result<()> {
 9529        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9530        let log_type = envelope
 9531            .payload
 9532            .log_type
 9533            .map(LanguageServerLogType::from_proto)
 9534            .context("invalid language server log type")?;
 9535
 9536        let message = envelope.payload.message;
 9537
 9538        this.update(&mut cx, |_, cx| {
 9539            cx.emit(LspStoreEvent::LanguageServerLog(
 9540                language_server_id,
 9541                log_type,
 9542                message,
 9543            ));
 9544        });
 9545        Ok(())
 9546    }
 9547
 9548    async fn handle_lsp_ext_cancel_flycheck(
 9549        lsp_store: Entity<Self>,
 9550        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9551        cx: AsyncApp,
 9552    ) -> Result<proto::Ack> {
 9553        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9554        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9555            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9556                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9557            } else {
 9558                None
 9559            }
 9560        });
 9561        if let Some(task) = task {
 9562            task.context("handling lsp ext cancel flycheck")?;
 9563        }
 9564
 9565        Ok(proto::Ack {})
 9566    }
 9567
 9568    async fn handle_lsp_ext_run_flycheck(
 9569        lsp_store: Entity<Self>,
 9570        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9571        mut cx: AsyncApp,
 9572    ) -> Result<proto::Ack> {
 9573        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9574        lsp_store.update(&mut cx, |lsp_store, cx| {
 9575            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9576                let text_document = if envelope.payload.current_file_only {
 9577                    let buffer_id = envelope
 9578                        .payload
 9579                        .buffer_id
 9580                        .map(|id| BufferId::new(id))
 9581                        .transpose()?;
 9582                    buffer_id
 9583                        .and_then(|buffer_id| {
 9584                            lsp_store
 9585                                .buffer_store()
 9586                                .read(cx)
 9587                                .get(buffer_id)
 9588                                .and_then(|buffer| {
 9589                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9590                                })
 9591                                .map(|path| make_text_document_identifier(&path))
 9592                        })
 9593                        .transpose()?
 9594                } else {
 9595                    None
 9596                };
 9597                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9598                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9599                )?;
 9600            }
 9601            anyhow::Ok(())
 9602        })?;
 9603
 9604        Ok(proto::Ack {})
 9605    }
 9606
 9607    async fn handle_lsp_ext_clear_flycheck(
 9608        lsp_store: Entity<Self>,
 9609        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9610        cx: AsyncApp,
 9611    ) -> Result<proto::Ack> {
 9612        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9613        lsp_store.read_with(&cx, |lsp_store, _| {
 9614            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9615                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9616            } else {
 9617                None
 9618            }
 9619        });
 9620
 9621        Ok(proto::Ack {})
 9622    }
 9623
 9624    pub fn disk_based_diagnostics_started(
 9625        &mut self,
 9626        language_server_id: LanguageServerId,
 9627        cx: &mut Context<Self>,
 9628    ) {
 9629        if let Some(language_server_status) =
 9630            self.language_server_statuses.get_mut(&language_server_id)
 9631        {
 9632            language_server_status.has_pending_diagnostic_updates = true;
 9633        }
 9634
 9635        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9636        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9637            language_server_id,
 9638            name: self
 9639                .language_server_adapter_for_id(language_server_id)
 9640                .map(|adapter| adapter.name()),
 9641            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9642                Default::default(),
 9643            ),
 9644        })
 9645    }
 9646
 9647    pub fn disk_based_diagnostics_finished(
 9648        &mut self,
 9649        language_server_id: LanguageServerId,
 9650        cx: &mut Context<Self>,
 9651    ) {
 9652        if let Some(language_server_status) =
 9653            self.language_server_statuses.get_mut(&language_server_id)
 9654        {
 9655            language_server_status.has_pending_diagnostic_updates = false;
 9656        }
 9657
 9658        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9659        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9660            language_server_id,
 9661            name: self
 9662                .language_server_adapter_for_id(language_server_id)
 9663                .map(|adapter| adapter.name()),
 9664            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9665                Default::default(),
 9666            ),
 9667        })
 9668    }
 9669
 9670    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9671    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9672    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9673    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9674    // the language server might take some time to publish diagnostics.
 9675    fn simulate_disk_based_diagnostics_events_if_needed(
 9676        &mut self,
 9677        language_server_id: LanguageServerId,
 9678        cx: &mut Context<Self>,
 9679    ) {
 9680        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9681
 9682        let Some(LanguageServerState::Running {
 9683            simulate_disk_based_diagnostics_completion,
 9684            adapter,
 9685            ..
 9686        }) = self
 9687            .as_local_mut()
 9688            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9689        else {
 9690            return;
 9691        };
 9692
 9693        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9694            return;
 9695        }
 9696
 9697        let prev_task =
 9698            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9699                cx.background_executor()
 9700                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9701                    .await;
 9702
 9703                this.update(cx, |this, cx| {
 9704                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9705
 9706                    if let Some(LanguageServerState::Running {
 9707                        simulate_disk_based_diagnostics_completion,
 9708                        ..
 9709                    }) = this.as_local_mut().and_then(|local_store| {
 9710                        local_store.language_servers.get_mut(&language_server_id)
 9711                    }) {
 9712                        *simulate_disk_based_diagnostics_completion = None;
 9713                    }
 9714                })
 9715                .ok();
 9716            }));
 9717
 9718        if prev_task.is_none() {
 9719            self.disk_based_diagnostics_started(language_server_id, cx);
 9720        }
 9721    }
 9722
 9723    pub fn language_server_statuses(
 9724        &self,
 9725    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9726        self.language_server_statuses
 9727            .iter()
 9728            .map(|(key, value)| (*key, value))
 9729    }
 9730
 9731    pub(super) fn did_rename_entry(
 9732        &self,
 9733        worktree_id: WorktreeId,
 9734        old_path: &Path,
 9735        new_path: &Path,
 9736        is_dir: bool,
 9737    ) {
 9738        maybe!({
 9739            let local_store = self.as_local()?;
 9740
 9741            let old_uri = lsp::Uri::from_file_path(old_path)
 9742                .ok()
 9743                .map(|uri| uri.to_string())?;
 9744            let new_uri = lsp::Uri::from_file_path(new_path)
 9745                .ok()
 9746                .map(|uri| uri.to_string())?;
 9747
 9748            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9749                let Some(filter) = local_store
 9750                    .language_server_paths_watched_for_rename
 9751                    .get(&language_server.server_id())
 9752                else {
 9753                    continue;
 9754                };
 9755
 9756                if filter.should_send_did_rename(&old_uri, is_dir) {
 9757                    language_server
 9758                        .notify::<DidRenameFiles>(RenameFilesParams {
 9759                            files: vec![FileRename {
 9760                                old_uri: old_uri.clone(),
 9761                                new_uri: new_uri.clone(),
 9762                            }],
 9763                        })
 9764                        .ok();
 9765                }
 9766            }
 9767            Some(())
 9768        });
 9769    }
 9770
 9771    pub(super) fn will_rename_entry(
 9772        this: WeakEntity<Self>,
 9773        worktree_id: WorktreeId,
 9774        old_path: &Path,
 9775        new_path: &Path,
 9776        is_dir: bool,
 9777        cx: AsyncApp,
 9778    ) -> Task<ProjectTransaction> {
 9779        let old_uri = lsp::Uri::from_file_path(old_path)
 9780            .ok()
 9781            .map(|uri| uri.to_string());
 9782        let new_uri = lsp::Uri::from_file_path(new_path)
 9783            .ok()
 9784            .map(|uri| uri.to_string());
 9785        cx.spawn(async move |cx| {
 9786            let mut tasks = vec![];
 9787            this.update(cx, |this, cx| {
 9788                let local_store = this.as_local()?;
 9789                let old_uri = old_uri?;
 9790                let new_uri = new_uri?;
 9791                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9792                    let Some(filter) = local_store
 9793                        .language_server_paths_watched_for_rename
 9794                        .get(&language_server.server_id())
 9795                    else {
 9796                        continue;
 9797                    };
 9798
 9799                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9800                        continue;
 9801                    }
 9802                    let request_timeout = ProjectSettings::get_global(cx)
 9803                        .global_lsp_settings
 9804                        .get_request_timeout();
 9805
 9806                    let apply_edit = cx.spawn({
 9807                        let old_uri = old_uri.clone();
 9808                        let new_uri = new_uri.clone();
 9809                        let language_server = language_server.clone();
 9810                        async move |this, cx| {
 9811                            let edit = language_server
 9812                                .request::<WillRenameFiles>(
 9813                                    RenameFilesParams {
 9814                                        files: vec![FileRename { old_uri, new_uri }],
 9815                                    },
 9816                                    request_timeout,
 9817                                )
 9818                                .await
 9819                                .into_response()
 9820                                .context("will rename files")
 9821                                .log_err()
 9822                                .flatten()?;
 9823
 9824                            LocalLspStore::deserialize_workspace_edit(
 9825                                this.upgrade()?,
 9826                                edit,
 9827                                false,
 9828                                language_server.clone(),
 9829                                cx,
 9830                            )
 9831                            .await
 9832                            .ok()
 9833                        }
 9834                    });
 9835                    tasks.push(apply_edit);
 9836                }
 9837                Some(())
 9838            })
 9839            .ok()
 9840            .flatten();
 9841            let mut merged_transaction = ProjectTransaction::default();
 9842            for task in tasks {
 9843                // Await on tasks sequentially so that the order of application of edits is deterministic
 9844                // (at least with regards to the order of registration of language servers)
 9845                if let Some(transaction) = task.await {
 9846                    for (buffer, buffer_transaction) in transaction.0 {
 9847                        merged_transaction.0.insert(buffer, buffer_transaction);
 9848                    }
 9849                }
 9850            }
 9851            merged_transaction
 9852        })
 9853    }
 9854
 9855    fn lsp_notify_abs_paths_changed(
 9856        &mut self,
 9857        server_id: LanguageServerId,
 9858        changes: Vec<PathEvent>,
 9859    ) {
 9860        maybe!({
 9861            let server = self.language_server_for_id(server_id)?;
 9862            let changes = changes
 9863                .into_iter()
 9864                .filter_map(|event| {
 9865                    let typ = match event.kind? {
 9866                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9867                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9868                        PathEventKind::Changed | PathEventKind::Rescan => {
 9869                            lsp::FileChangeType::CHANGED
 9870                        }
 9871                    };
 9872                    Some(lsp::FileEvent {
 9873                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9874                        typ,
 9875                    })
 9876                })
 9877                .collect::<Vec<_>>();
 9878            if !changes.is_empty() {
 9879                server
 9880                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9881                        lsp::DidChangeWatchedFilesParams { changes },
 9882                    )
 9883                    .ok();
 9884            }
 9885            Some(())
 9886        });
 9887    }
 9888
 9889    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9890        self.as_local()?.language_server_for_id(id)
 9891    }
 9892
 9893    fn on_lsp_progress(
 9894        &mut self,
 9895        progress_params: lsp::ProgressParams,
 9896        language_server_id: LanguageServerId,
 9897        disk_based_diagnostics_progress_token: Option<String>,
 9898        cx: &mut Context<Self>,
 9899    ) {
 9900        match progress_params.value {
 9901            lsp::ProgressParamsValue::WorkDone(progress) => {
 9902                self.handle_work_done_progress(
 9903                    progress,
 9904                    language_server_id,
 9905                    disk_based_diagnostics_progress_token,
 9906                    ProgressToken::from_lsp(progress_params.token),
 9907                    cx,
 9908                );
 9909            }
 9910            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9911                let registration_id = match progress_params.token {
 9912                    lsp::NumberOrString::Number(_) => None,
 9913                    lsp::NumberOrString::String(token) => token
 9914                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9915                        .map(|(_, id)| id.to_owned()),
 9916                };
 9917                if let Some(LanguageServerState::Running {
 9918                    workspace_diagnostics_refresh_tasks,
 9919                    ..
 9920                }) = self
 9921                    .as_local_mut()
 9922                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9923                    && let Some(workspace_diagnostics) =
 9924                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
 9925                {
 9926                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9927                    self.apply_workspace_diagnostic_report(
 9928                        language_server_id,
 9929                        report,
 9930                        registration_id.map(SharedString::from),
 9931                        cx,
 9932                    )
 9933                }
 9934            }
 9935        }
 9936    }
 9937
 9938    fn handle_work_done_progress(
 9939        &mut self,
 9940        progress: lsp::WorkDoneProgress,
 9941        language_server_id: LanguageServerId,
 9942        disk_based_diagnostics_progress_token: Option<String>,
 9943        token: ProgressToken,
 9944        cx: &mut Context<Self>,
 9945    ) {
 9946        let language_server_status =
 9947            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9948                status
 9949            } else {
 9950                return;
 9951            };
 9952
 9953        if !language_server_status.progress_tokens.contains(&token) {
 9954            return;
 9955        }
 9956
 9957        let is_disk_based_diagnostics_progress =
 9958            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9959                (&disk_based_diagnostics_progress_token, &token)
 9960            {
 9961                token.starts_with(disk_based_token)
 9962            } else {
 9963                false
 9964            };
 9965
 9966        match progress {
 9967            lsp::WorkDoneProgress::Begin(report) => {
 9968                if is_disk_based_diagnostics_progress {
 9969                    self.disk_based_diagnostics_started(language_server_id, cx);
 9970                }
 9971                self.on_lsp_work_start(
 9972                    language_server_id,
 9973                    token.clone(),
 9974                    LanguageServerProgress {
 9975                        title: Some(report.title),
 9976                        is_disk_based_diagnostics_progress,
 9977                        is_cancellable: report.cancellable.unwrap_or(false),
 9978                        message: report.message.clone(),
 9979                        percentage: report.percentage.map(|p| p as usize),
 9980                        last_update_at: cx.background_executor().now(),
 9981                    },
 9982                    cx,
 9983                );
 9984            }
 9985            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9986                language_server_id,
 9987                token,
 9988                LanguageServerProgress {
 9989                    title: None,
 9990                    is_disk_based_diagnostics_progress,
 9991                    is_cancellable: report.cancellable.unwrap_or(false),
 9992                    message: report.message,
 9993                    percentage: report.percentage.map(|p| p as usize),
 9994                    last_update_at: cx.background_executor().now(),
 9995                },
 9996                cx,
 9997            ),
 9998            lsp::WorkDoneProgress::End(_) => {
 9999                language_server_status.progress_tokens.remove(&token);
10000                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10001                if is_disk_based_diagnostics_progress {
10002                    self.disk_based_diagnostics_finished(language_server_id, cx);
10003                }
10004            }
10005        }
10006    }
10007
10008    fn on_lsp_work_start(
10009        &mut self,
10010        language_server_id: LanguageServerId,
10011        token: ProgressToken,
10012        progress: LanguageServerProgress,
10013        cx: &mut Context<Self>,
10014    ) {
10015        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10016            status.pending_work.insert(token.clone(), progress.clone());
10017            cx.notify();
10018        }
10019        cx.emit(LspStoreEvent::LanguageServerUpdate {
10020            language_server_id,
10021            name: self
10022                .language_server_adapter_for_id(language_server_id)
10023                .map(|adapter| adapter.name()),
10024            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10025                token: Some(token.to_proto()),
10026                title: progress.title,
10027                message: progress.message,
10028                percentage: progress.percentage.map(|p| p as u32),
10029                is_cancellable: Some(progress.is_cancellable),
10030            }),
10031        })
10032    }
10033
10034    fn on_lsp_work_progress(
10035        &mut self,
10036        language_server_id: LanguageServerId,
10037        token: ProgressToken,
10038        progress: LanguageServerProgress,
10039        cx: &mut Context<Self>,
10040    ) {
10041        let mut did_update = false;
10042        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10043            match status.pending_work.entry(token.clone()) {
10044                btree_map::Entry::Vacant(entry) => {
10045                    entry.insert(progress.clone());
10046                    did_update = true;
10047                }
10048                btree_map::Entry::Occupied(mut entry) => {
10049                    let entry = entry.get_mut();
10050                    if (progress.last_update_at - entry.last_update_at)
10051                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10052                    {
10053                        entry.last_update_at = progress.last_update_at;
10054                        if progress.message.is_some() {
10055                            entry.message = progress.message.clone();
10056                        }
10057                        if progress.percentage.is_some() {
10058                            entry.percentage = progress.percentage;
10059                        }
10060                        if progress.is_cancellable != entry.is_cancellable {
10061                            entry.is_cancellable = progress.is_cancellable;
10062                        }
10063                        did_update = true;
10064                    }
10065                }
10066            }
10067        }
10068
10069        if did_update {
10070            cx.emit(LspStoreEvent::LanguageServerUpdate {
10071                language_server_id,
10072                name: self
10073                    .language_server_adapter_for_id(language_server_id)
10074                    .map(|adapter| adapter.name()),
10075                message: proto::update_language_server::Variant::WorkProgress(
10076                    proto::LspWorkProgress {
10077                        token: Some(token.to_proto()),
10078                        message: progress.message,
10079                        percentage: progress.percentage.map(|p| p as u32),
10080                        is_cancellable: Some(progress.is_cancellable),
10081                    },
10082                ),
10083            })
10084        }
10085    }
10086
10087    fn on_lsp_work_end(
10088        &mut self,
10089        language_server_id: LanguageServerId,
10090        token: ProgressToken,
10091        cx: &mut Context<Self>,
10092    ) {
10093        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10094            if let Some(work) = status.pending_work.remove(&token)
10095                && !work.is_disk_based_diagnostics_progress
10096            {
10097                cx.emit(LspStoreEvent::RefreshInlayHints {
10098                    server_id: language_server_id,
10099                    request_id: None,
10100                });
10101            }
10102            cx.notify();
10103        }
10104
10105        cx.emit(LspStoreEvent::LanguageServerUpdate {
10106            language_server_id,
10107            name: self
10108                .language_server_adapter_for_id(language_server_id)
10109                .map(|adapter| adapter.name()),
10110            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10111                token: Some(token.to_proto()),
10112            }),
10113        })
10114    }
10115
10116    pub async fn handle_resolve_completion_documentation(
10117        this: Entity<Self>,
10118        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10119        mut cx: AsyncApp,
10120    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10121        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10122
10123        let completion = this
10124            .read_with(&cx, |this, cx| {
10125                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10126                let server = this
10127                    .language_server_for_id(id)
10128                    .with_context(|| format!("No language server {id}"))?;
10129
10130                let request_timeout = ProjectSettings::get_global(cx)
10131                    .global_lsp_settings
10132                    .get_request_timeout();
10133
10134                anyhow::Ok(cx.background_spawn(async move {
10135                    let can_resolve = server
10136                        .capabilities()
10137                        .completion_provider
10138                        .as_ref()
10139                        .and_then(|options| options.resolve_provider)
10140                        .unwrap_or(false);
10141                    if can_resolve {
10142                        server
10143                            .request::<lsp::request::ResolveCompletionItem>(
10144                                lsp_completion,
10145                                request_timeout,
10146                            )
10147                            .await
10148                            .into_response()
10149                            .context("resolve completion item")
10150                    } else {
10151                        anyhow::Ok(lsp_completion)
10152                    }
10153                }))
10154            })?
10155            .await?;
10156
10157        let mut documentation_is_markdown = false;
10158        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10159        let documentation = match completion.documentation {
10160            Some(lsp::Documentation::String(text)) => text,
10161
10162            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10163                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10164                value
10165            }
10166
10167            _ => String::new(),
10168        };
10169
10170        // If we have a new buffer_id, that means we're talking to a new client
10171        // and want to check for new text_edits in the completion too.
10172        let mut old_replace_start = None;
10173        let mut old_replace_end = None;
10174        let mut old_insert_start = None;
10175        let mut old_insert_end = None;
10176        let mut new_text = String::default();
10177        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10178            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10179                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10180                anyhow::Ok(buffer.read(cx).snapshot())
10181            })?;
10182
10183            if let Some(text_edit) = completion.text_edit.as_ref() {
10184                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10185
10186                if let Some(mut edit) = edit {
10187                    LineEnding::normalize(&mut edit.new_text);
10188
10189                    new_text = edit.new_text;
10190                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10191                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10192                    if let Some(insert_range) = edit.insert_range {
10193                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10194                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10195                    }
10196                }
10197            }
10198        }
10199
10200        Ok(proto::ResolveCompletionDocumentationResponse {
10201            documentation,
10202            documentation_is_markdown,
10203            old_replace_start,
10204            old_replace_end,
10205            new_text,
10206            lsp_completion,
10207            old_insert_start,
10208            old_insert_end,
10209        })
10210    }
10211
10212    async fn handle_on_type_formatting(
10213        this: Entity<Self>,
10214        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10215        mut cx: AsyncApp,
10216    ) -> Result<proto::OnTypeFormattingResponse> {
10217        let on_type_formatting = this.update(&mut cx, |this, cx| {
10218            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10219            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10220            let position = envelope
10221                .payload
10222                .position
10223                .and_then(deserialize_anchor)
10224                .context("invalid position")?;
10225            anyhow::Ok(this.apply_on_type_formatting(
10226                buffer,
10227                position,
10228                envelope.payload.trigger.clone(),
10229                cx,
10230            ))
10231        })?;
10232
10233        let transaction = on_type_formatting
10234            .await?
10235            .as_ref()
10236            .map(language::proto::serialize_transaction);
10237        Ok(proto::OnTypeFormattingResponse { transaction })
10238    }
10239
10240    async fn handle_pull_workspace_diagnostics(
10241        lsp_store: Entity<Self>,
10242        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10243        mut cx: AsyncApp,
10244    ) -> Result<proto::Ack> {
10245        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10246        lsp_store.update(&mut cx, |lsp_store, _| {
10247            lsp_store.pull_workspace_diagnostics(server_id);
10248        });
10249        Ok(proto::Ack {})
10250    }
10251
10252    async fn handle_open_buffer_for_symbol(
10253        this: Entity<Self>,
10254        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10255        mut cx: AsyncApp,
10256    ) -> Result<proto::OpenBufferForSymbolResponse> {
10257        let peer_id = envelope.original_sender_id().unwrap_or_default();
10258        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10259        let symbol = Self::deserialize_symbol(symbol)?;
10260        this.read_with(&cx, |this, _| {
10261            if let SymbolLocation::OutsideProject {
10262                abs_path,
10263                signature,
10264            } = &symbol.path
10265            {
10266                let new_signature = this.symbol_signature(&abs_path);
10267                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10268            }
10269            Ok(())
10270        })?;
10271        let buffer = this
10272            .update(&mut cx, |this, cx| {
10273                this.open_buffer_for_symbol(
10274                    &Symbol {
10275                        language_server_name: symbol.language_server_name,
10276                        source_worktree_id: symbol.source_worktree_id,
10277                        source_language_server_id: symbol.source_language_server_id,
10278                        path: symbol.path,
10279                        name: symbol.name,
10280                        kind: symbol.kind,
10281                        range: symbol.range,
10282                        label: CodeLabel::default(),
10283                        container_name: symbol.container_name,
10284                    },
10285                    cx,
10286                )
10287            })
10288            .await?;
10289
10290        this.update(&mut cx, |this, cx| {
10291            let is_private = buffer
10292                .read(cx)
10293                .file()
10294                .map(|f| f.is_private())
10295                .unwrap_or_default();
10296            if is_private {
10297                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10298            } else {
10299                this.buffer_store
10300                    .update(cx, |buffer_store, cx| {
10301                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10302                    })
10303                    .detach_and_log_err(cx);
10304                let buffer_id = buffer.read(cx).remote_id().to_proto();
10305                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10306            }
10307        })
10308    }
10309
10310    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10311        let mut hasher = Sha256::new();
10312        hasher.update(abs_path.to_string_lossy().as_bytes());
10313        hasher.update(self.nonce.to_be_bytes());
10314        hasher.finalize().as_slice().try_into().unwrap()
10315    }
10316
10317    pub async fn handle_get_project_symbols(
10318        this: Entity<Self>,
10319        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10320        mut cx: AsyncApp,
10321    ) -> Result<proto::GetProjectSymbolsResponse> {
10322        let symbols = this
10323            .update(&mut cx, |this, cx| {
10324                this.symbols(&envelope.payload.query, cx)
10325            })
10326            .await?;
10327
10328        Ok(proto::GetProjectSymbolsResponse {
10329            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10330        })
10331    }
10332
10333    pub async fn handle_restart_language_servers(
10334        this: Entity<Self>,
10335        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10336        mut cx: AsyncApp,
10337    ) -> Result<proto::Ack> {
10338        this.update(&mut cx, |lsp_store, cx| {
10339            let buffers =
10340                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10341            lsp_store.restart_language_servers_for_buffers(
10342                buffers,
10343                envelope
10344                    .payload
10345                    .only_servers
10346                    .into_iter()
10347                    .filter_map(|selector| {
10348                        Some(match selector.selector? {
10349                            proto::language_server_selector::Selector::ServerId(server_id) => {
10350                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10351                            }
10352                            proto::language_server_selector::Selector::Name(name) => {
10353                                LanguageServerSelector::Name(LanguageServerName(
10354                                    SharedString::from(name),
10355                                ))
10356                            }
10357                        })
10358                    })
10359                    .collect(),
10360                cx,
10361            );
10362        });
10363
10364        Ok(proto::Ack {})
10365    }
10366
10367    pub async fn handle_stop_language_servers(
10368        lsp_store: Entity<Self>,
10369        envelope: TypedEnvelope<proto::StopLanguageServers>,
10370        mut cx: AsyncApp,
10371    ) -> Result<proto::Ack> {
10372        lsp_store.update(&mut cx, |lsp_store, cx| {
10373            if envelope.payload.all
10374                && envelope.payload.also_servers.is_empty()
10375                && envelope.payload.buffer_ids.is_empty()
10376            {
10377                lsp_store.stop_all_language_servers(cx);
10378            } else {
10379                let buffers =
10380                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10381                lsp_store
10382                    .stop_language_servers_for_buffers(
10383                        buffers,
10384                        envelope
10385                            .payload
10386                            .also_servers
10387                            .into_iter()
10388                            .filter_map(|selector| {
10389                                Some(match selector.selector? {
10390                                    proto::language_server_selector::Selector::ServerId(
10391                                        server_id,
10392                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10393                                        server_id,
10394                                    )),
10395                                    proto::language_server_selector::Selector::Name(name) => {
10396                                        LanguageServerSelector::Name(LanguageServerName(
10397                                            SharedString::from(name),
10398                                        ))
10399                                    }
10400                                })
10401                            })
10402                            .collect(),
10403                        cx,
10404                    )
10405                    .detach_and_log_err(cx);
10406            }
10407        });
10408
10409        Ok(proto::Ack {})
10410    }
10411
10412    pub async fn handle_cancel_language_server_work(
10413        lsp_store: Entity<Self>,
10414        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10415        mut cx: AsyncApp,
10416    ) -> Result<proto::Ack> {
10417        lsp_store.update(&mut cx, |lsp_store, cx| {
10418            if let Some(work) = envelope.payload.work {
10419                match work {
10420                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10421                        let buffers =
10422                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10423                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10424                    }
10425                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10426                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10427                        let token = work
10428                            .token
10429                            .map(|token| {
10430                                ProgressToken::from_proto(token)
10431                                    .context("invalid work progress token")
10432                            })
10433                            .transpose()?;
10434                        lsp_store.cancel_language_server_work(server_id, token, cx);
10435                    }
10436                }
10437            }
10438            anyhow::Ok(())
10439        })?;
10440
10441        Ok(proto::Ack {})
10442    }
10443
10444    fn buffer_ids_to_buffers(
10445        &mut self,
10446        buffer_ids: impl Iterator<Item = u64>,
10447        cx: &mut Context<Self>,
10448    ) -> Vec<Entity<Buffer>> {
10449        buffer_ids
10450            .into_iter()
10451            .flat_map(|buffer_id| {
10452                self.buffer_store
10453                    .read(cx)
10454                    .get(BufferId::new(buffer_id).log_err()?)
10455            })
10456            .collect::<Vec<_>>()
10457    }
10458
10459    async fn handle_apply_additional_edits_for_completion(
10460        this: Entity<Self>,
10461        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10462        mut cx: AsyncApp,
10463    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10464        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10465            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10466            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10467            let completion = Self::deserialize_completion(
10468                envelope.payload.completion.context("invalid completion")?,
10469            )?;
10470            let all_commit_ranges = envelope
10471                .payload
10472                .all_commit_ranges
10473                .into_iter()
10474                .map(language::proto::deserialize_anchor_range)
10475                .collect::<Result<Vec<_>, _>>()?;
10476            anyhow::Ok((buffer, completion, all_commit_ranges))
10477        })?;
10478
10479        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10480            this.apply_additional_edits_for_completion(
10481                buffer,
10482                Rc::new(RefCell::new(Box::new([Completion {
10483                    replace_range: completion.replace_range,
10484                    new_text: completion.new_text,
10485                    source: completion.source,
10486                    documentation: None,
10487                    label: CodeLabel::default(),
10488                    match_start: None,
10489                    snippet_deduplication_key: None,
10490                    insert_text_mode: None,
10491                    icon_path: None,
10492                    confirm: None,
10493                }]))),
10494                0,
10495                false,
10496                all_commit_ranges,
10497                cx,
10498            )
10499        });
10500
10501        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10502            transaction: apply_additional_edits
10503                .await?
10504                .as_ref()
10505                .map(language::proto::serialize_transaction),
10506        })
10507    }
10508
10509    pub fn last_formatting_failure(&self) -> Option<&str> {
10510        self.last_formatting_failure.as_deref()
10511    }
10512
10513    pub fn reset_last_formatting_failure(&mut self) {
10514        self.last_formatting_failure = None;
10515    }
10516
10517    pub fn environment_for_buffer(
10518        &self,
10519        buffer: &Entity<Buffer>,
10520        cx: &mut Context<Self>,
10521    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10522        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10523            environment.update(cx, |env, cx| {
10524                env.buffer_environment(buffer, &self.worktree_store, cx)
10525            })
10526        } else {
10527            Task::ready(None).shared()
10528        }
10529    }
10530
10531    pub fn format(
10532        &mut self,
10533        buffers: HashSet<Entity<Buffer>>,
10534        target: LspFormatTarget,
10535        push_to_history: bool,
10536        trigger: FormatTrigger,
10537        cx: &mut Context<Self>,
10538    ) -> Task<anyhow::Result<ProjectTransaction>> {
10539        let logger = zlog::scoped!("format");
10540        if self.as_local().is_some() {
10541            zlog::trace!(logger => "Formatting locally");
10542            let logger = zlog::scoped!(logger => "local");
10543            let buffers = buffers
10544                .into_iter()
10545                .map(|buffer_handle| {
10546                    let buffer = buffer_handle.read(cx);
10547                    let buffer_abs_path = File::from_dyn(buffer.file())
10548                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10549
10550                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10551                })
10552                .collect::<Vec<_>>();
10553
10554            cx.spawn(async move |lsp_store, cx| {
10555                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10556
10557                for (handle, abs_path, id) in buffers {
10558                    let env = lsp_store
10559                        .update(cx, |lsp_store, cx| {
10560                            lsp_store.environment_for_buffer(&handle, cx)
10561                        })?
10562                        .await;
10563
10564                    let ranges = match &target {
10565                        LspFormatTarget::Buffers => None,
10566                        LspFormatTarget::Ranges(ranges) => {
10567                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10568                        }
10569                    };
10570
10571                    formattable_buffers.push(FormattableBuffer {
10572                        handle,
10573                        abs_path,
10574                        env,
10575                        ranges,
10576                    });
10577                }
10578                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10579
10580                let format_timer = zlog::time!(logger => "Formatting buffers");
10581                let result = LocalLspStore::format_locally(
10582                    lsp_store.clone(),
10583                    formattable_buffers,
10584                    push_to_history,
10585                    trigger,
10586                    logger,
10587                    cx,
10588                )
10589                .await;
10590                format_timer.end();
10591
10592                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10593
10594                lsp_store.update(cx, |lsp_store, _| {
10595                    lsp_store.update_last_formatting_failure(&result);
10596                })?;
10597
10598                result
10599            })
10600        } else if let Some((client, project_id)) = self.upstream_client() {
10601            zlog::trace!(logger => "Formatting remotely");
10602            let logger = zlog::scoped!(logger => "remote");
10603
10604            let buffer_ranges = match &target {
10605                LspFormatTarget::Buffers => Vec::new(),
10606                LspFormatTarget::Ranges(ranges) => ranges
10607                    .iter()
10608                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10609                        buffer_id: buffer_id.to_proto(),
10610                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10611                    })
10612                    .collect(),
10613            };
10614
10615            let buffer_store = self.buffer_store();
10616            cx.spawn(async move |lsp_store, cx| {
10617                zlog::trace!(logger => "Sending remote format request");
10618                let request_timer = zlog::time!(logger => "remote format request");
10619                let result = client
10620                    .request(proto::FormatBuffers {
10621                        project_id,
10622                        trigger: trigger as i32,
10623                        buffer_ids: buffers
10624                            .iter()
10625                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10626                            .collect(),
10627                        buffer_ranges,
10628                    })
10629                    .await
10630                    .and_then(|result| result.transaction.context("missing transaction"));
10631                request_timer.end();
10632
10633                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10634
10635                lsp_store.update(cx, |lsp_store, _| {
10636                    lsp_store.update_last_formatting_failure(&result);
10637                })?;
10638
10639                let transaction_response = result?;
10640                let _timer = zlog::time!(logger => "deserializing project transaction");
10641                buffer_store
10642                    .update(cx, |buffer_store, cx| {
10643                        buffer_store.deserialize_project_transaction(
10644                            transaction_response,
10645                            push_to_history,
10646                            cx,
10647                        )
10648                    })
10649                    .await
10650            })
10651        } else {
10652            zlog::trace!(logger => "Not formatting");
10653            Task::ready(Ok(ProjectTransaction::default()))
10654        }
10655    }
10656
10657    async fn handle_format_buffers(
10658        this: Entity<Self>,
10659        envelope: TypedEnvelope<proto::FormatBuffers>,
10660        mut cx: AsyncApp,
10661    ) -> Result<proto::FormatBuffersResponse> {
10662        let sender_id = envelope.original_sender_id().unwrap_or_default();
10663        let format = this.update(&mut cx, |this, cx| {
10664            let mut buffers = HashSet::default();
10665            for buffer_id in &envelope.payload.buffer_ids {
10666                let buffer_id = BufferId::new(*buffer_id)?;
10667                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10668            }
10669
10670            let target = if envelope.payload.buffer_ranges.is_empty() {
10671                LspFormatTarget::Buffers
10672            } else {
10673                let mut ranges_map = BTreeMap::new();
10674                for buffer_range in &envelope.payload.buffer_ranges {
10675                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10676                    let ranges: Result<Vec<_>> = buffer_range
10677                        .ranges
10678                        .iter()
10679                        .map(|range| {
10680                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10681                        })
10682                        .collect();
10683                    ranges_map.insert(buffer_id, ranges?);
10684                }
10685                LspFormatTarget::Ranges(ranges_map)
10686            };
10687
10688            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10689            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10690        })?;
10691
10692        let project_transaction = format.await?;
10693        let project_transaction = this.update(&mut cx, |this, cx| {
10694            this.buffer_store.update(cx, |buffer_store, cx| {
10695                buffer_store.serialize_project_transaction_for_peer(
10696                    project_transaction,
10697                    sender_id,
10698                    cx,
10699                )
10700            })
10701        });
10702        Ok(proto::FormatBuffersResponse {
10703            transaction: Some(project_transaction),
10704        })
10705    }
10706
10707    async fn handle_apply_code_action_kind(
10708        this: Entity<Self>,
10709        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10710        mut cx: AsyncApp,
10711    ) -> Result<proto::ApplyCodeActionKindResponse> {
10712        let sender_id = envelope.original_sender_id().unwrap_or_default();
10713        let format = this.update(&mut cx, |this, cx| {
10714            let mut buffers = HashSet::default();
10715            for buffer_id in &envelope.payload.buffer_ids {
10716                let buffer_id = BufferId::new(*buffer_id)?;
10717                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10718            }
10719            let kind = match envelope.payload.kind.as_str() {
10720                "" => CodeActionKind::EMPTY,
10721                "quickfix" => CodeActionKind::QUICKFIX,
10722                "refactor" => CodeActionKind::REFACTOR,
10723                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10724                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10725                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10726                "source" => CodeActionKind::SOURCE,
10727                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10728                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10729                _ => anyhow::bail!(
10730                    "Invalid code action kind {}",
10731                    envelope.payload.kind.as_str()
10732                ),
10733            };
10734            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10735        })?;
10736
10737        let project_transaction = format.await?;
10738        let project_transaction = this.update(&mut cx, |this, cx| {
10739            this.buffer_store.update(cx, |buffer_store, cx| {
10740                buffer_store.serialize_project_transaction_for_peer(
10741                    project_transaction,
10742                    sender_id,
10743                    cx,
10744                )
10745            })
10746        });
10747        Ok(proto::ApplyCodeActionKindResponse {
10748            transaction: Some(project_transaction),
10749        })
10750    }
10751
10752    async fn shutdown_language_server(
10753        server_state: Option<LanguageServerState>,
10754        name: LanguageServerName,
10755        cx: &mut AsyncApp,
10756    ) {
10757        let server = match server_state {
10758            Some(LanguageServerState::Starting { startup, .. }) => {
10759                let mut timer = cx
10760                    .background_executor()
10761                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10762                    .fuse();
10763
10764                select! {
10765                    server = startup.fuse() => server,
10766                    () = timer => {
10767                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10768                        None
10769                    },
10770                }
10771            }
10772
10773            Some(LanguageServerState::Running { server, .. }) => Some(server),
10774
10775            None => None,
10776        };
10777
10778        let Some(server) = server else { return };
10779        if let Some(shutdown) = server.shutdown() {
10780            shutdown.await;
10781        }
10782    }
10783
10784    // Returns a list of all of the worktrees which no longer have a language server and the root path
10785    // for the stopped server
10786    fn stop_local_language_server(
10787        &mut self,
10788        server_id: LanguageServerId,
10789        cx: &mut Context<Self>,
10790    ) -> Task<()> {
10791        let local = match &mut self.mode {
10792            LspStoreMode::Local(local) => local,
10793            _ => {
10794                return Task::ready(());
10795            }
10796        };
10797
10798        // Remove this server ID from all entries in the given worktree.
10799        local
10800            .language_server_ids
10801            .retain(|_, state| state.id != server_id);
10802        self.buffer_store.update(cx, |buffer_store, cx| {
10803            for buffer in buffer_store.buffers() {
10804                buffer.update(cx, |buffer, cx| {
10805                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10806                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10807                });
10808            }
10809        });
10810
10811        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10812            summaries.retain(|path, summaries_by_server_id| {
10813                if summaries_by_server_id.remove(&server_id).is_some() {
10814                    if let Some((client, project_id)) = self.downstream_client.clone() {
10815                        client
10816                            .send(proto::UpdateDiagnosticSummary {
10817                                project_id,
10818                                worktree_id: worktree_id.to_proto(),
10819                                summary: Some(proto::DiagnosticSummary {
10820                                    path: path.as_ref().to_proto(),
10821                                    language_server_id: server_id.0 as u64,
10822                                    error_count: 0,
10823                                    warning_count: 0,
10824                                }),
10825                                more_summaries: Vec::new(),
10826                            })
10827                            .log_err();
10828                    }
10829                    !summaries_by_server_id.is_empty()
10830                } else {
10831                    true
10832                }
10833            });
10834        }
10835
10836        let local = self.as_local_mut().unwrap();
10837        for diagnostics in local.diagnostics.values_mut() {
10838            diagnostics.retain(|_, diagnostics_by_server_id| {
10839                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10840                    diagnostics_by_server_id.remove(ix);
10841                    !diagnostics_by_server_id.is_empty()
10842                } else {
10843                    true
10844                }
10845            });
10846        }
10847        local.language_server_watched_paths.remove(&server_id);
10848
10849        let server_state = local.language_servers.remove(&server_id);
10850        self.cleanup_lsp_data(server_id);
10851        let name = self
10852            .language_server_statuses
10853            .remove(&server_id)
10854            .map(|status| status.name)
10855            .or_else(|| {
10856                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10857                    Some(adapter.name())
10858                } else {
10859                    None
10860                }
10861            });
10862
10863        if let Some(name) = name {
10864            log::info!("stopping language server {name}");
10865            self.languages
10866                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10867            cx.notify();
10868
10869            return cx.spawn(async move |lsp_store, cx| {
10870                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10871                lsp_store
10872                    .update(cx, |lsp_store, cx| {
10873                        lsp_store
10874                            .languages
10875                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10876                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10877                        cx.notify();
10878                    })
10879                    .ok();
10880            });
10881        }
10882
10883        if server_state.is_some() {
10884            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10885        }
10886        Task::ready(())
10887    }
10888
10889    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10890        self.shutdown_all_language_servers(cx).detach();
10891    }
10892
10893    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
10894        if let Some((client, project_id)) = self.upstream_client() {
10895            let request = client.request(proto::StopLanguageServers {
10896                project_id,
10897                buffer_ids: Vec::new(),
10898                also_servers: Vec::new(),
10899                all: true,
10900            });
10901            cx.background_spawn(async move {
10902                request.await.ok();
10903            })
10904        } else {
10905            let Some(local) = self.as_local_mut() else {
10906                return Task::ready(());
10907            };
10908            let language_servers_to_stop = local
10909                .language_server_ids
10910                .values()
10911                .map(|state| state.id)
10912                .collect();
10913            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10914            let tasks = language_servers_to_stop
10915                .into_iter()
10916                .map(|server| self.stop_local_language_server(server, cx))
10917                .collect::<Vec<_>>();
10918            cx.background_spawn(async move {
10919                futures::future::join_all(tasks).await;
10920            })
10921        }
10922    }
10923
10924    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
10925        let buffers = self.buffer_store.read(cx).buffers().collect();
10926        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
10927    }
10928
10929    pub fn restart_language_servers_for_buffers(
10930        &mut self,
10931        buffers: Vec<Entity<Buffer>>,
10932        only_restart_servers: HashSet<LanguageServerSelector>,
10933        cx: &mut Context<Self>,
10934    ) {
10935        if let Some((client, project_id)) = self.upstream_client() {
10936            let request = client.request(proto::RestartLanguageServers {
10937                project_id,
10938                buffer_ids: buffers
10939                    .into_iter()
10940                    .map(|b| b.read(cx).remote_id().to_proto())
10941                    .collect(),
10942                only_servers: only_restart_servers
10943                    .into_iter()
10944                    .map(|selector| {
10945                        let selector = match selector {
10946                            LanguageServerSelector::Id(language_server_id) => {
10947                                proto::language_server_selector::Selector::ServerId(
10948                                    language_server_id.to_proto(),
10949                                )
10950                            }
10951                            LanguageServerSelector::Name(language_server_name) => {
10952                                proto::language_server_selector::Selector::Name(
10953                                    language_server_name.to_string(),
10954                                )
10955                            }
10956                        };
10957                        proto::LanguageServerSelector {
10958                            selector: Some(selector),
10959                        }
10960                    })
10961                    .collect(),
10962                all: false,
10963            });
10964            cx.background_spawn(request).detach_and_log_err(cx);
10965        } else {
10966            let stop_task = if only_restart_servers.is_empty() {
10967                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10968            } else {
10969                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10970            };
10971            cx.spawn(async move |lsp_store, cx| {
10972                stop_task.await;
10973                lsp_store.update(cx, |lsp_store, cx| {
10974                    for buffer in buffers {
10975                        lsp_store.register_buffer_with_language_servers(
10976                            &buffer,
10977                            only_restart_servers.clone(),
10978                            true,
10979                            cx,
10980                        );
10981                    }
10982                })
10983            })
10984            .detach();
10985        }
10986    }
10987
10988    pub fn stop_language_servers_for_buffers(
10989        &mut self,
10990        buffers: Vec<Entity<Buffer>>,
10991        also_stop_servers: HashSet<LanguageServerSelector>,
10992        cx: &mut Context<Self>,
10993    ) -> Task<Result<()>> {
10994        if let Some((client, project_id)) = self.upstream_client() {
10995            let request = client.request(proto::StopLanguageServers {
10996                project_id,
10997                buffer_ids: buffers
10998                    .into_iter()
10999                    .map(|b| b.read(cx).remote_id().to_proto())
11000                    .collect(),
11001                also_servers: also_stop_servers
11002                    .into_iter()
11003                    .map(|selector| {
11004                        let selector = match selector {
11005                            LanguageServerSelector::Id(language_server_id) => {
11006                                proto::language_server_selector::Selector::ServerId(
11007                                    language_server_id.to_proto(),
11008                                )
11009                            }
11010                            LanguageServerSelector::Name(language_server_name) => {
11011                                proto::language_server_selector::Selector::Name(
11012                                    language_server_name.to_string(),
11013                                )
11014                            }
11015                        };
11016                        proto::LanguageServerSelector {
11017                            selector: Some(selector),
11018                        }
11019                    })
11020                    .collect(),
11021                all: false,
11022            });
11023            cx.background_spawn(async move {
11024                let _ = request.await?;
11025                Ok(())
11026            })
11027        } else {
11028            let task =
11029                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11030            cx.background_spawn(async move {
11031                task.await;
11032                Ok(())
11033            })
11034        }
11035    }
11036
11037    fn stop_local_language_servers_for_buffers(
11038        &mut self,
11039        buffers: &[Entity<Buffer>],
11040        also_stop_servers: HashSet<LanguageServerSelector>,
11041        cx: &mut Context<Self>,
11042    ) -> Task<()> {
11043        let Some(local) = self.as_local_mut() else {
11044            return Task::ready(());
11045        };
11046        let mut language_server_names_to_stop = BTreeSet::default();
11047        let mut language_servers_to_stop = also_stop_servers
11048            .into_iter()
11049            .flat_map(|selector| match selector {
11050                LanguageServerSelector::Id(id) => Some(id),
11051                LanguageServerSelector::Name(name) => {
11052                    language_server_names_to_stop.insert(name);
11053                    None
11054                }
11055            })
11056            .collect::<BTreeSet<_>>();
11057
11058        let mut covered_worktrees = HashSet::default();
11059        for buffer in buffers {
11060            buffer.update(cx, |buffer, cx| {
11061                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11062                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11063                    && covered_worktrees.insert(worktree_id)
11064                {
11065                    language_server_names_to_stop.retain(|name| {
11066                        let old_ids_count = language_servers_to_stop.len();
11067                        let all_language_servers_with_this_name = local
11068                            .language_server_ids
11069                            .iter()
11070                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11071                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11072                        old_ids_count == language_servers_to_stop.len()
11073                    });
11074                }
11075            });
11076        }
11077        for name in language_server_names_to_stop {
11078            language_servers_to_stop.extend(
11079                local
11080                    .language_server_ids
11081                    .iter()
11082                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11083            );
11084        }
11085
11086        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11087        let tasks = language_servers_to_stop
11088            .into_iter()
11089            .map(|server| self.stop_local_language_server(server, cx))
11090            .collect::<Vec<_>>();
11091
11092        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11093    }
11094
11095    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11096        let (worktree, relative_path) =
11097            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11098
11099        let project_path = ProjectPath {
11100            worktree_id: worktree.read(cx).id(),
11101            path: relative_path,
11102        };
11103
11104        Some(
11105            self.buffer_store()
11106                .read(cx)
11107                .get_by_path(&project_path)?
11108                .read(cx),
11109        )
11110    }
11111
11112    #[cfg(any(test, feature = "test-support"))]
11113    pub fn update_diagnostics(
11114        &mut self,
11115        server_id: LanguageServerId,
11116        diagnostics: lsp::PublishDiagnosticsParams,
11117        result_id: Option<SharedString>,
11118        source_kind: DiagnosticSourceKind,
11119        disk_based_sources: &[String],
11120        cx: &mut Context<Self>,
11121    ) -> Result<()> {
11122        self.merge_lsp_diagnostics(
11123            source_kind,
11124            vec![DocumentDiagnosticsUpdate {
11125                diagnostics,
11126                result_id,
11127                server_id,
11128                disk_based_sources: Cow::Borrowed(disk_based_sources),
11129                registration_id: None,
11130            }],
11131            |_, _, _| false,
11132            cx,
11133        )
11134    }
11135
11136    pub fn merge_lsp_diagnostics(
11137        &mut self,
11138        source_kind: DiagnosticSourceKind,
11139        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11140        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11141        cx: &mut Context<Self>,
11142    ) -> Result<()> {
11143        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11144        let updates = lsp_diagnostics
11145            .into_iter()
11146            .filter_map(|update| {
11147                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11148                Some(DocumentDiagnosticsUpdate {
11149                    diagnostics: self.lsp_to_document_diagnostics(
11150                        abs_path,
11151                        source_kind,
11152                        update.server_id,
11153                        update.diagnostics,
11154                        &update.disk_based_sources,
11155                        update.registration_id.clone(),
11156                    ),
11157                    result_id: update.result_id,
11158                    server_id: update.server_id,
11159                    disk_based_sources: update.disk_based_sources,
11160                    registration_id: update.registration_id,
11161                })
11162            })
11163            .collect();
11164        self.merge_diagnostic_entries(updates, merge, cx)?;
11165        Ok(())
11166    }
11167
11168    fn lsp_to_document_diagnostics(
11169        &mut self,
11170        document_abs_path: PathBuf,
11171        source_kind: DiagnosticSourceKind,
11172        server_id: LanguageServerId,
11173        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11174        disk_based_sources: &[String],
11175        registration_id: Option<SharedString>,
11176    ) -> DocumentDiagnostics {
11177        let mut diagnostics = Vec::default();
11178        let mut primary_diagnostic_group_ids = HashMap::default();
11179        let mut sources_by_group_id = HashMap::default();
11180        let mut supporting_diagnostics = HashMap::default();
11181
11182        let adapter = self.language_server_adapter_for_id(server_id);
11183
11184        // Ensure that primary diagnostics are always the most severe
11185        lsp_diagnostics
11186            .diagnostics
11187            .sort_by_key(|item| item.severity);
11188
11189        for diagnostic in &lsp_diagnostics.diagnostics {
11190            let source = diagnostic.source.as_ref();
11191            let range = range_from_lsp(diagnostic.range);
11192            let is_supporting = diagnostic
11193                .related_information
11194                .as_ref()
11195                .is_some_and(|infos| {
11196                    infos.iter().any(|info| {
11197                        primary_diagnostic_group_ids.contains_key(&(
11198                            source,
11199                            diagnostic.code.clone(),
11200                            range_from_lsp(info.location.range),
11201                        ))
11202                    })
11203                });
11204
11205            let is_unnecessary = diagnostic
11206                .tags
11207                .as_ref()
11208                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11209
11210            let underline = self
11211                .language_server_adapter_for_id(server_id)
11212                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11213
11214            if is_supporting {
11215                supporting_diagnostics.insert(
11216                    (source, diagnostic.code.clone(), range),
11217                    (diagnostic.severity, is_unnecessary),
11218                );
11219            } else {
11220                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11221                let is_disk_based =
11222                    source.is_some_and(|source| disk_based_sources.contains(source));
11223
11224                sources_by_group_id.insert(group_id, source);
11225                primary_diagnostic_group_ids
11226                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11227
11228                diagnostics.push(DiagnosticEntry {
11229                    range,
11230                    diagnostic: Diagnostic {
11231                        source: diagnostic.source.clone(),
11232                        source_kind,
11233                        code: diagnostic.code.clone(),
11234                        code_description: diagnostic
11235                            .code_description
11236                            .as_ref()
11237                            .and_then(|d| d.href.clone()),
11238                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11239                        markdown: adapter.as_ref().and_then(|adapter| {
11240                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11241                        }),
11242                        message: diagnostic.message.trim().to_string(),
11243                        group_id,
11244                        is_primary: true,
11245                        is_disk_based,
11246                        is_unnecessary,
11247                        underline,
11248                        data: diagnostic.data.clone(),
11249                        registration_id: registration_id.clone(),
11250                    },
11251                });
11252                if let Some(infos) = &diagnostic.related_information {
11253                    for info in infos {
11254                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11255                            let range = range_from_lsp(info.location.range);
11256                            diagnostics.push(DiagnosticEntry {
11257                                range,
11258                                diagnostic: Diagnostic {
11259                                    source: diagnostic.source.clone(),
11260                                    source_kind,
11261                                    code: diagnostic.code.clone(),
11262                                    code_description: diagnostic
11263                                        .code_description
11264                                        .as_ref()
11265                                        .and_then(|d| d.href.clone()),
11266                                    severity: DiagnosticSeverity::INFORMATION,
11267                                    markdown: adapter.as_ref().and_then(|adapter| {
11268                                        adapter.diagnostic_message_to_markdown(&info.message)
11269                                    }),
11270                                    message: info.message.trim().to_string(),
11271                                    group_id,
11272                                    is_primary: false,
11273                                    is_disk_based,
11274                                    is_unnecessary: false,
11275                                    underline,
11276                                    data: diagnostic.data.clone(),
11277                                    registration_id: registration_id.clone(),
11278                                },
11279                            });
11280                        }
11281                    }
11282                }
11283            }
11284        }
11285
11286        for entry in &mut diagnostics {
11287            let diagnostic = &mut entry.diagnostic;
11288            if !diagnostic.is_primary {
11289                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11290                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11291                    source,
11292                    diagnostic.code.clone(),
11293                    entry.range.clone(),
11294                )) {
11295                    if let Some(severity) = severity {
11296                        diagnostic.severity = severity;
11297                    }
11298                    diagnostic.is_unnecessary = is_unnecessary;
11299                }
11300            }
11301        }
11302
11303        DocumentDiagnostics {
11304            diagnostics,
11305            document_abs_path,
11306            version: lsp_diagnostics.version,
11307        }
11308    }
11309
11310    fn insert_newly_running_language_server(
11311        &mut self,
11312        adapter: Arc<CachedLspAdapter>,
11313        language_server: Arc<LanguageServer>,
11314        server_id: LanguageServerId,
11315        key: LanguageServerSeed,
11316        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11317        cx: &mut Context<Self>,
11318    ) {
11319        let Some(local) = self.as_local_mut() else {
11320            return;
11321        };
11322        // If the language server for this key doesn't match the server id, don't store the
11323        // server. Which will cause it to be dropped, killing the process
11324        if local
11325            .language_server_ids
11326            .get(&key)
11327            .map(|state| state.id != server_id)
11328            .unwrap_or(false)
11329        {
11330            return;
11331        }
11332
11333        // Update language_servers collection with Running variant of LanguageServerState
11334        // indicating that the server is up and running and ready
11335        let workspace_folders = workspace_folders.lock().clone();
11336        language_server.set_workspace_folders(workspace_folders);
11337
11338        let workspace_diagnostics_refresh_tasks = language_server
11339            .capabilities()
11340            .diagnostic_provider
11341            .and_then(|provider| {
11342                local
11343                    .language_server_dynamic_registrations
11344                    .entry(server_id)
11345                    .or_default()
11346                    .diagnostics
11347                    .entry(None)
11348                    .or_insert(provider.clone());
11349                let workspace_refresher =
11350                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11351
11352                Some((None, workspace_refresher))
11353            })
11354            .into_iter()
11355            .collect();
11356        local.language_servers.insert(
11357            server_id,
11358            LanguageServerState::Running {
11359                workspace_diagnostics_refresh_tasks,
11360                adapter: adapter.clone(),
11361                server: language_server.clone(),
11362                simulate_disk_based_diagnostics_completion: None,
11363            },
11364        );
11365        local
11366            .languages
11367            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11368        if let Some(file_ops_caps) = language_server
11369            .capabilities()
11370            .workspace
11371            .as_ref()
11372            .and_then(|ws| ws.file_operations.as_ref())
11373        {
11374            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11375            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11376            if did_rename_caps.or(will_rename_caps).is_some() {
11377                let watcher = RenamePathsWatchedForServer::default()
11378                    .with_did_rename_patterns(did_rename_caps)
11379                    .with_will_rename_patterns(will_rename_caps);
11380                local
11381                    .language_server_paths_watched_for_rename
11382                    .insert(server_id, watcher);
11383            }
11384        }
11385
11386        self.language_server_statuses.insert(
11387            server_id,
11388            LanguageServerStatus {
11389                name: language_server.name(),
11390                server_version: language_server.version(),
11391                server_readable_version: language_server.readable_version(),
11392                pending_work: Default::default(),
11393                has_pending_diagnostic_updates: false,
11394                progress_tokens: Default::default(),
11395                worktree: Some(key.worktree_id),
11396                binary: Some(language_server.binary().clone()),
11397                configuration: Some(language_server.configuration().clone()),
11398                workspace_folders: language_server.workspace_folders(),
11399                process_id: language_server.process_id(),
11400            },
11401        );
11402
11403        cx.emit(LspStoreEvent::LanguageServerAdded(
11404            server_id,
11405            language_server.name(),
11406            Some(key.worktree_id),
11407        ));
11408
11409        let server_capabilities = language_server.capabilities();
11410        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11411            downstream_client
11412                .send(proto::StartLanguageServer {
11413                    project_id: *project_id,
11414                    server: Some(proto::LanguageServer {
11415                        id: server_id.to_proto(),
11416                        name: language_server.name().to_string(),
11417                        worktree_id: Some(key.worktree_id.to_proto()),
11418                    }),
11419                    capabilities: serde_json::to_string(&server_capabilities)
11420                        .expect("serializing server LSP capabilities"),
11421                })
11422                .log_err();
11423        }
11424        self.lsp_server_capabilities
11425            .insert(server_id, server_capabilities);
11426
11427        // Tell the language server about every open buffer in the worktree that matches the language.
11428        // Also check for buffers in worktrees that reused this server
11429        let mut worktrees_using_server = vec![key.worktree_id];
11430        if let Some(local) = self.as_local() {
11431            // Find all worktrees that have this server in their language server tree
11432            for (worktree_id, servers) in &local.lsp_tree.instances {
11433                if *worktree_id != key.worktree_id {
11434                    for server_map in servers.roots.values() {
11435                        if server_map
11436                            .values()
11437                            .any(|(node, _)| node.id() == Some(server_id))
11438                        {
11439                            worktrees_using_server.push(*worktree_id);
11440                        }
11441                    }
11442                }
11443            }
11444        }
11445
11446        let mut buffer_paths_registered = Vec::new();
11447        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11448            let mut lsp_adapters = HashMap::default();
11449            for buffer_handle in buffer_store.buffers() {
11450                let buffer = buffer_handle.read(cx);
11451                let file = match File::from_dyn(buffer.file()) {
11452                    Some(file) => file,
11453                    None => continue,
11454                };
11455                let language = match buffer.language() {
11456                    Some(language) => language,
11457                    None => continue,
11458                };
11459
11460                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11461                    || !lsp_adapters
11462                        .entry(language.name())
11463                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11464                        .iter()
11465                        .any(|a| a.name == key.name)
11466                {
11467                    continue;
11468                }
11469                // didOpen
11470                let file = match file.as_local() {
11471                    Some(file) => file,
11472                    None => continue,
11473                };
11474
11475                let local = self.as_local_mut().unwrap();
11476
11477                let buffer_id = buffer.remote_id();
11478                if local.registered_buffers.contains_key(&buffer_id) {
11479                    let abs_path = file.abs_path(cx);
11480                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11481                        Ok(uri) => uri,
11482                        Err(()) => {
11483                            log::error!("failed to convert path to URI: {:?}", abs_path);
11484                            continue;
11485                        }
11486                    };
11487
11488                    let versions = local
11489                        .buffer_snapshots
11490                        .entry(buffer_id)
11491                        .or_default()
11492                        .entry(server_id)
11493                        .and_modify(|_| {
11494                            assert!(
11495                            false,
11496                            "There should not be an existing snapshot for a newly inserted buffer"
11497                        )
11498                        })
11499                        .or_insert_with(|| {
11500                            vec![LspBufferSnapshot {
11501                                version: 0,
11502                                snapshot: buffer.text_snapshot(),
11503                            }]
11504                        });
11505
11506                    let snapshot = versions.last().unwrap();
11507                    let version = snapshot.version;
11508                    let initial_snapshot = &snapshot.snapshot;
11509                    language_server.register_buffer(
11510                        uri,
11511                        adapter.language_id(&language.name()),
11512                        version,
11513                        initial_snapshot.text(),
11514                    );
11515                    buffer_paths_registered.push((buffer_id, abs_path));
11516                    local
11517                        .buffers_opened_in_servers
11518                        .entry(buffer_id)
11519                        .or_default()
11520                        .insert(server_id);
11521                }
11522                buffer_handle.update(cx, |buffer, cx| {
11523                    buffer.set_completion_triggers(
11524                        server_id,
11525                        language_server
11526                            .capabilities()
11527                            .completion_provider
11528                            .as_ref()
11529                            .and_then(|provider| {
11530                                provider
11531                                    .trigger_characters
11532                                    .as_ref()
11533                                    .map(|characters| characters.iter().cloned().collect())
11534                            })
11535                            .unwrap_or_default(),
11536                        cx,
11537                    )
11538                });
11539            }
11540        });
11541
11542        for (buffer_id, abs_path) in buffer_paths_registered {
11543            cx.emit(LspStoreEvent::LanguageServerUpdate {
11544                language_server_id: server_id,
11545                name: Some(adapter.name()),
11546                message: proto::update_language_server::Variant::RegisteredForBuffer(
11547                    proto::RegisteredForBuffer {
11548                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11549                        buffer_id: buffer_id.to_proto(),
11550                    },
11551                ),
11552            });
11553        }
11554
11555        cx.notify();
11556    }
11557
11558    pub fn language_servers_running_disk_based_diagnostics(
11559        &self,
11560    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11561        self.language_server_statuses
11562            .iter()
11563            .filter_map(|(id, status)| {
11564                if status.has_pending_diagnostic_updates {
11565                    Some(*id)
11566                } else {
11567                    None
11568                }
11569            })
11570    }
11571
11572    pub(crate) fn cancel_language_server_work_for_buffers(
11573        &mut self,
11574        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11575        cx: &mut Context<Self>,
11576    ) {
11577        if let Some((client, project_id)) = self.upstream_client() {
11578            let request = client.request(proto::CancelLanguageServerWork {
11579                project_id,
11580                work: Some(proto::cancel_language_server_work::Work::Buffers(
11581                    proto::cancel_language_server_work::Buffers {
11582                        buffer_ids: buffers
11583                            .into_iter()
11584                            .map(|b| b.read(cx).remote_id().to_proto())
11585                            .collect(),
11586                    },
11587                )),
11588            });
11589            cx.background_spawn(request).detach_and_log_err(cx);
11590        } else if let Some(local) = self.as_local() {
11591            let servers = buffers
11592                .into_iter()
11593                .flat_map(|buffer| {
11594                    buffer.update(cx, |buffer, cx| {
11595                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11596                    })
11597                })
11598                .collect::<HashSet<_>>();
11599            for server_id in servers {
11600                self.cancel_language_server_work(server_id, None, cx);
11601            }
11602        }
11603    }
11604
11605    pub(crate) fn cancel_language_server_work(
11606        &mut self,
11607        server_id: LanguageServerId,
11608        token_to_cancel: Option<ProgressToken>,
11609        cx: &mut Context<Self>,
11610    ) {
11611        if let Some(local) = self.as_local() {
11612            let status = self.language_server_statuses.get(&server_id);
11613            let server = local.language_servers.get(&server_id);
11614            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11615            {
11616                for (token, progress) in &status.pending_work {
11617                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11618                        && token != token_to_cancel
11619                    {
11620                        continue;
11621                    }
11622                    if progress.is_cancellable {
11623                        server
11624                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11625                                WorkDoneProgressCancelParams {
11626                                    token: token.to_lsp(),
11627                                },
11628                            )
11629                            .ok();
11630                    }
11631                }
11632            }
11633        } else if let Some((client, project_id)) = self.upstream_client() {
11634            let request = client.request(proto::CancelLanguageServerWork {
11635                project_id,
11636                work: Some(
11637                    proto::cancel_language_server_work::Work::LanguageServerWork(
11638                        proto::cancel_language_server_work::LanguageServerWork {
11639                            language_server_id: server_id.to_proto(),
11640                            token: token_to_cancel.map(|token| token.to_proto()),
11641                        },
11642                    ),
11643                ),
11644            });
11645            cx.background_spawn(request).detach_and_log_err(cx);
11646        }
11647    }
11648
11649    fn register_supplementary_language_server(
11650        &mut self,
11651        id: LanguageServerId,
11652        name: LanguageServerName,
11653        server: Arc<LanguageServer>,
11654        cx: &mut Context<Self>,
11655    ) {
11656        if let Some(local) = self.as_local_mut() {
11657            local
11658                .supplementary_language_servers
11659                .insert(id, (name.clone(), server));
11660            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11661        }
11662    }
11663
11664    fn unregister_supplementary_language_server(
11665        &mut self,
11666        id: LanguageServerId,
11667        cx: &mut Context<Self>,
11668    ) {
11669        if let Some(local) = self.as_local_mut() {
11670            local.supplementary_language_servers.remove(&id);
11671            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11672        }
11673    }
11674
11675    pub(crate) fn supplementary_language_servers(
11676        &self,
11677    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11678        self.as_local().into_iter().flat_map(|local| {
11679            local
11680                .supplementary_language_servers
11681                .iter()
11682                .map(|(id, (name, _))| (*id, name.clone()))
11683        })
11684    }
11685
11686    pub fn language_server_adapter_for_id(
11687        &self,
11688        id: LanguageServerId,
11689    ) -> Option<Arc<CachedLspAdapter>> {
11690        self.as_local()
11691            .and_then(|local| local.language_servers.get(&id))
11692            .and_then(|language_server_state| match language_server_state {
11693                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11694                _ => None,
11695            })
11696    }
11697
11698    pub(super) fn update_local_worktree_language_servers(
11699        &mut self,
11700        worktree_handle: &Entity<Worktree>,
11701        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11702        cx: &mut Context<Self>,
11703    ) {
11704        if changes.is_empty() {
11705            return;
11706        }
11707
11708        let Some(local) = self.as_local() else { return };
11709
11710        local.prettier_store.update(cx, |prettier_store, cx| {
11711            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11712        });
11713
11714        let worktree_id = worktree_handle.read(cx).id();
11715        let mut language_server_ids = local
11716            .language_server_ids
11717            .iter()
11718            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11719            .collect::<Vec<_>>();
11720        language_server_ids.sort();
11721        language_server_ids.dedup();
11722
11723        // let abs_path = worktree_handle.read(cx).abs_path();
11724        for server_id in &language_server_ids {
11725            if let Some(LanguageServerState::Running { server, .. }) =
11726                local.language_servers.get(server_id)
11727                && let Some(watched_paths) = local
11728                    .language_server_watched_paths
11729                    .get(server_id)
11730                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11731            {
11732                let params = lsp::DidChangeWatchedFilesParams {
11733                    changes: changes
11734                        .iter()
11735                        .filter_map(|(path, _, change)| {
11736                            if !watched_paths.is_match(path.as_std_path()) {
11737                                return None;
11738                            }
11739                            let typ = match change {
11740                                PathChange::Loaded => return None,
11741                                PathChange::Added => lsp::FileChangeType::CREATED,
11742                                PathChange::Removed => lsp::FileChangeType::DELETED,
11743                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11744                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11745                            };
11746                            let uri = lsp::Uri::from_file_path(
11747                                worktree_handle.read(cx).absolutize(&path),
11748                            )
11749                            .ok()?;
11750                            Some(lsp::FileEvent { uri, typ })
11751                        })
11752                        .collect(),
11753                };
11754                if !params.changes.is_empty() {
11755                    server
11756                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11757                        .ok();
11758                }
11759            }
11760        }
11761        for (path, _, _) in changes {
11762            if let Some(file_name) = path.file_name()
11763                && local.watched_manifest_filenames.contains(file_name)
11764            {
11765                self.request_workspace_config_refresh();
11766                break;
11767            }
11768        }
11769    }
11770
11771    pub fn wait_for_remote_buffer(
11772        &mut self,
11773        id: BufferId,
11774        cx: &mut Context<Self>,
11775    ) -> Task<Result<Entity<Buffer>>> {
11776        self.buffer_store.update(cx, |buffer_store, cx| {
11777            buffer_store.wait_for_remote_buffer(id, cx)
11778        })
11779    }
11780
11781    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11782        let mut result = proto::Symbol {
11783            language_server_name: symbol.language_server_name.0.to_string(),
11784            source_worktree_id: symbol.source_worktree_id.to_proto(),
11785            language_server_id: symbol.source_language_server_id.to_proto(),
11786            name: symbol.name.clone(),
11787            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11788            start: Some(proto::PointUtf16 {
11789                row: symbol.range.start.0.row,
11790                column: symbol.range.start.0.column,
11791            }),
11792            end: Some(proto::PointUtf16 {
11793                row: symbol.range.end.0.row,
11794                column: symbol.range.end.0.column,
11795            }),
11796            worktree_id: Default::default(),
11797            path: Default::default(),
11798            signature: Default::default(),
11799            container_name: symbol.container_name.clone(),
11800        };
11801        match &symbol.path {
11802            SymbolLocation::InProject(path) => {
11803                result.worktree_id = path.worktree_id.to_proto();
11804                result.path = path.path.to_proto();
11805            }
11806            SymbolLocation::OutsideProject {
11807                abs_path,
11808                signature,
11809            } => {
11810                result.path = abs_path.to_string_lossy().into_owned();
11811                result.signature = signature.to_vec();
11812            }
11813        }
11814        result
11815    }
11816
11817    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11818        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11819        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11820        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11821
11822        let path = if serialized_symbol.signature.is_empty() {
11823            SymbolLocation::InProject(ProjectPath {
11824                worktree_id,
11825                path: RelPath::from_proto(&serialized_symbol.path)
11826                    .context("invalid symbol path")?,
11827            })
11828        } else {
11829            SymbolLocation::OutsideProject {
11830                abs_path: Path::new(&serialized_symbol.path).into(),
11831                signature: serialized_symbol
11832                    .signature
11833                    .try_into()
11834                    .map_err(|_| anyhow!("invalid signature"))?,
11835            }
11836        };
11837
11838        let start = serialized_symbol.start.context("invalid start")?;
11839        let end = serialized_symbol.end.context("invalid end")?;
11840        Ok(CoreSymbol {
11841            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11842            source_worktree_id,
11843            source_language_server_id: LanguageServerId::from_proto(
11844                serialized_symbol.language_server_id,
11845            ),
11846            path,
11847            name: serialized_symbol.name,
11848            range: Unclipped(PointUtf16::new(start.row, start.column))
11849                ..Unclipped(PointUtf16::new(end.row, end.column)),
11850            kind,
11851            container_name: serialized_symbol.container_name,
11852        })
11853    }
11854
11855    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11856        let mut serialized_completion = proto::Completion {
11857            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11858            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11859            new_text: completion.new_text.clone(),
11860            ..proto::Completion::default()
11861        };
11862        match &completion.source {
11863            CompletionSource::Lsp {
11864                insert_range,
11865                server_id,
11866                lsp_completion,
11867                lsp_defaults,
11868                resolved,
11869            } => {
11870                let (old_insert_start, old_insert_end) = insert_range
11871                    .as_ref()
11872                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11873                    .unzip();
11874
11875                serialized_completion.old_insert_start = old_insert_start;
11876                serialized_completion.old_insert_end = old_insert_end;
11877                serialized_completion.source = proto::completion::Source::Lsp as i32;
11878                serialized_completion.server_id = server_id.0 as u64;
11879                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11880                serialized_completion.lsp_defaults = lsp_defaults
11881                    .as_deref()
11882                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11883                serialized_completion.resolved = *resolved;
11884            }
11885            CompletionSource::BufferWord {
11886                word_range,
11887                resolved,
11888            } => {
11889                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11890                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11891                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11892                serialized_completion.resolved = *resolved;
11893            }
11894            CompletionSource::Custom => {
11895                serialized_completion.source = proto::completion::Source::Custom as i32;
11896                serialized_completion.resolved = true;
11897            }
11898            CompletionSource::Dap { sort_text } => {
11899                serialized_completion.source = proto::completion::Source::Dap as i32;
11900                serialized_completion.sort_text = Some(sort_text.clone());
11901            }
11902        }
11903
11904        serialized_completion
11905    }
11906
11907    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11908        let old_replace_start = completion
11909            .old_replace_start
11910            .and_then(deserialize_anchor)
11911            .context("invalid old start")?;
11912        let old_replace_end = completion
11913            .old_replace_end
11914            .and_then(deserialize_anchor)
11915            .context("invalid old end")?;
11916        let insert_range = {
11917            match completion.old_insert_start.zip(completion.old_insert_end) {
11918                Some((start, end)) => {
11919                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11920                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11921                    Some(start..end)
11922                }
11923                None => None,
11924            }
11925        };
11926        Ok(CoreCompletion {
11927            replace_range: old_replace_start..old_replace_end,
11928            new_text: completion.new_text,
11929            source: match proto::completion::Source::from_i32(completion.source) {
11930                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11931                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11932                    insert_range,
11933                    server_id: LanguageServerId::from_proto(completion.server_id),
11934                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11935                    lsp_defaults: completion
11936                        .lsp_defaults
11937                        .as_deref()
11938                        .map(serde_json::from_slice)
11939                        .transpose()?,
11940                    resolved: completion.resolved,
11941                },
11942                Some(proto::completion::Source::BufferWord) => {
11943                    let word_range = completion
11944                        .buffer_word_start
11945                        .and_then(deserialize_anchor)
11946                        .context("invalid buffer word start")?
11947                        ..completion
11948                            .buffer_word_end
11949                            .and_then(deserialize_anchor)
11950                            .context("invalid buffer word end")?;
11951                    CompletionSource::BufferWord {
11952                        word_range,
11953                        resolved: completion.resolved,
11954                    }
11955                }
11956                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11957                    sort_text: completion
11958                        .sort_text
11959                        .context("expected sort text to exist")?,
11960                },
11961                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11962            },
11963        })
11964    }
11965
11966    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11967        let (kind, lsp_action) = match &action.lsp_action {
11968            LspAction::Action(code_action) => (
11969                proto::code_action::Kind::Action as i32,
11970                serde_json::to_vec(code_action).unwrap(),
11971            ),
11972            LspAction::Command(command) => (
11973                proto::code_action::Kind::Command as i32,
11974                serde_json::to_vec(command).unwrap(),
11975            ),
11976            LspAction::CodeLens(code_lens) => (
11977                proto::code_action::Kind::CodeLens as i32,
11978                serde_json::to_vec(code_lens).unwrap(),
11979            ),
11980        };
11981
11982        proto::CodeAction {
11983            server_id: action.server_id.0 as u64,
11984            start: Some(serialize_anchor(&action.range.start)),
11985            end: Some(serialize_anchor(&action.range.end)),
11986            lsp_action,
11987            kind,
11988            resolved: action.resolved,
11989        }
11990    }
11991
11992    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11993        let start = action
11994            .start
11995            .and_then(deserialize_anchor)
11996            .context("invalid start")?;
11997        let end = action
11998            .end
11999            .and_then(deserialize_anchor)
12000            .context("invalid end")?;
12001        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12002            Some(proto::code_action::Kind::Action) => {
12003                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12004            }
12005            Some(proto::code_action::Kind::Command) => {
12006                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12007            }
12008            Some(proto::code_action::Kind::CodeLens) => {
12009                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12010            }
12011            None => anyhow::bail!("Unknown action kind {}", action.kind),
12012        };
12013        Ok(CodeAction {
12014            server_id: LanguageServerId(action.server_id as usize),
12015            range: start..end,
12016            resolved: action.resolved,
12017            lsp_action,
12018        })
12019    }
12020
12021    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12022        match &formatting_result {
12023            Ok(_) => self.last_formatting_failure = None,
12024            Err(error) => {
12025                let error_string = format!("{error:#}");
12026                log::error!("Formatting failed: {error_string}");
12027                self.last_formatting_failure
12028                    .replace(error_string.lines().join(" "));
12029            }
12030        }
12031    }
12032
12033    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12034        self.lsp_server_capabilities.remove(&for_server);
12035        self.semantic_token_config.remove_server_data(for_server);
12036        for lsp_data in self.lsp_data.values_mut() {
12037            lsp_data.remove_server_data(for_server);
12038        }
12039        if let Some(local) = self.as_local_mut() {
12040            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12041            local
12042                .workspace_pull_diagnostics_result_ids
12043                .remove(&for_server);
12044            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12045                buffer_servers.remove(&for_server);
12046            }
12047        }
12048    }
12049
12050    pub fn result_id_for_buffer_pull(
12051        &self,
12052        server_id: LanguageServerId,
12053        buffer_id: BufferId,
12054        registration_id: &Option<SharedString>,
12055        cx: &App,
12056    ) -> Option<SharedString> {
12057        let abs_path = self
12058            .buffer_store
12059            .read(cx)
12060            .get(buffer_id)
12061            .and_then(|b| File::from_dyn(b.read(cx).file()))
12062            .map(|f| f.abs_path(cx))?;
12063        self.as_local()?
12064            .buffer_pull_diagnostics_result_ids
12065            .get(&server_id)?
12066            .get(registration_id)?
12067            .get(&abs_path)?
12068            .clone()
12069    }
12070
12071    /// Gets all result_ids for a workspace diagnostics pull request.
12072    /// 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.
12073    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12074    pub fn result_ids_for_workspace_refresh(
12075        &self,
12076        server_id: LanguageServerId,
12077        registration_id: &Option<SharedString>,
12078    ) -> HashMap<PathBuf, SharedString> {
12079        let Some(local) = self.as_local() else {
12080            return HashMap::default();
12081        };
12082        local
12083            .workspace_pull_diagnostics_result_ids
12084            .get(&server_id)
12085            .into_iter()
12086            .filter_map(|diagnostics| diagnostics.get(registration_id))
12087            .flatten()
12088            .filter_map(|(abs_path, result_id)| {
12089                let result_id = local
12090                    .buffer_pull_diagnostics_result_ids
12091                    .get(&server_id)
12092                    .and_then(|buffer_ids_result_ids| {
12093                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12094                    })
12095                    .cloned()
12096                    .flatten()
12097                    .or_else(|| result_id.clone())?;
12098                Some((abs_path.clone(), result_id))
12099            })
12100            .collect()
12101    }
12102
12103    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12104        if let Some(LanguageServerState::Running {
12105            workspace_diagnostics_refresh_tasks,
12106            ..
12107        }) = self
12108            .as_local_mut()
12109            .and_then(|local| local.language_servers.get_mut(&server_id))
12110        {
12111            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12112                diagnostics.refresh_tx.try_send(()).ok();
12113            }
12114        }
12115    }
12116
12117    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12118    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12119    /// which requires refreshing both workspace and document diagnostics.
12120    pub fn pull_document_diagnostics_for_server(
12121        &mut self,
12122        server_id: LanguageServerId,
12123        source_buffer_id: Option<BufferId>,
12124        cx: &mut Context<Self>,
12125    ) -> Shared<Task<()>> {
12126        let Some(local) = self.as_local_mut() else {
12127            return Task::ready(()).shared();
12128        };
12129        let mut buffers_to_refresh = HashSet::default();
12130        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12131            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12132                buffers_to_refresh.insert(*buffer_id);
12133            }
12134        }
12135
12136        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12137    }
12138
12139    pub fn pull_document_diagnostics_for_buffer_edit(
12140        &mut self,
12141        buffer_id: BufferId,
12142        cx: &mut Context<Self>,
12143    ) {
12144        let Some(local) = self.as_local_mut() else {
12145            return;
12146        };
12147        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12148        else {
12149            return;
12150        };
12151        for server_id in languages_servers {
12152            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12153        }
12154    }
12155
12156    fn apply_workspace_diagnostic_report(
12157        &mut self,
12158        server_id: LanguageServerId,
12159        report: lsp::WorkspaceDiagnosticReportResult,
12160        registration_id: Option<SharedString>,
12161        cx: &mut Context<Self>,
12162    ) {
12163        let mut workspace_diagnostics =
12164            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12165                report,
12166                server_id,
12167                registration_id,
12168            );
12169        workspace_diagnostics.retain(|d| match &d.diagnostics {
12170            LspPullDiagnostics::Response {
12171                server_id,
12172                registration_id,
12173                ..
12174            } => self.diagnostic_registration_exists(*server_id, registration_id),
12175            LspPullDiagnostics::Default => false,
12176        });
12177        let mut unchanged_buffers = HashMap::default();
12178        let workspace_diagnostics_updates = workspace_diagnostics
12179            .into_iter()
12180            .filter_map(
12181                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12182                    LspPullDiagnostics::Response {
12183                        server_id,
12184                        uri,
12185                        diagnostics,
12186                        registration_id,
12187                    } => Some((
12188                        server_id,
12189                        uri,
12190                        diagnostics,
12191                        workspace_diagnostics.version,
12192                        registration_id,
12193                    )),
12194                    LspPullDiagnostics::Default => None,
12195                },
12196            )
12197            .fold(
12198                HashMap::default(),
12199                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12200                    let (result_id, diagnostics) = match diagnostics {
12201                        PulledDiagnostics::Unchanged { result_id } => {
12202                            unchanged_buffers
12203                                .entry(new_registration_id.clone())
12204                                .or_insert_with(HashSet::default)
12205                                .insert(uri.clone());
12206                            (Some(result_id), Vec::new())
12207                        }
12208                        PulledDiagnostics::Changed {
12209                            result_id,
12210                            diagnostics,
12211                        } => (result_id, diagnostics),
12212                    };
12213                    let disk_based_sources = Cow::Owned(
12214                        self.language_server_adapter_for_id(server_id)
12215                            .as_ref()
12216                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12217                            .unwrap_or(&[])
12218                            .to_vec(),
12219                    );
12220
12221                    let Some(abs_path) = uri.to_file_path().ok() else {
12222                        return acc;
12223                    };
12224                    let Some((worktree, relative_path)) =
12225                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12226                    else {
12227                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12228                        return acc;
12229                    };
12230                    let worktree_id = worktree.read(cx).id();
12231                    let project_path = ProjectPath {
12232                        worktree_id,
12233                        path: relative_path,
12234                    };
12235                    if let Some(local_lsp_store) = self.as_local_mut() {
12236                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12237                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12238                    }
12239                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12240                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12241                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12242                        acc.entry(server_id)
12243                            .or_insert_with(HashMap::default)
12244                            .entry(new_registration_id.clone())
12245                            .or_insert_with(Vec::new)
12246                            .push(DocumentDiagnosticsUpdate {
12247                                server_id,
12248                                diagnostics: lsp::PublishDiagnosticsParams {
12249                                    uri,
12250                                    diagnostics,
12251                                    version,
12252                                },
12253                                result_id: result_id.map(SharedString::new),
12254                                disk_based_sources,
12255                                registration_id: new_registration_id,
12256                            });
12257                    }
12258                    acc
12259                },
12260            );
12261
12262        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12263            for (registration_id, diagnostic_updates) in diagnostic_updates {
12264                self.merge_lsp_diagnostics(
12265                    DiagnosticSourceKind::Pulled,
12266                    diagnostic_updates,
12267                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12268                        DiagnosticSourceKind::Pulled => {
12269                            old_diagnostic.registration_id != registration_id
12270                                || unchanged_buffers
12271                                    .get(&old_diagnostic.registration_id)
12272                                    .is_some_and(|unchanged_buffers| {
12273                                        unchanged_buffers.contains(&document_uri)
12274                                    })
12275                        }
12276                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12277                    },
12278                    cx,
12279                )
12280                .log_err();
12281            }
12282        }
12283    }
12284
12285    fn register_server_capabilities(
12286        &mut self,
12287        server_id: LanguageServerId,
12288        params: lsp::RegistrationParams,
12289        cx: &mut Context<Self>,
12290    ) -> anyhow::Result<()> {
12291        let server = self
12292            .language_server_for_id(server_id)
12293            .with_context(|| format!("no server {server_id} found"))?;
12294        for reg in params.registrations {
12295            match reg.method.as_str() {
12296                "workspace/didChangeWatchedFiles" => {
12297                    if let Some(options) = reg.register_options {
12298                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12299                            let caps = serde_json::from_value(options)?;
12300                            local_lsp_store
12301                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12302                            true
12303                        } else {
12304                            false
12305                        };
12306                        if notify {
12307                            notify_server_capabilities_updated(&server, cx);
12308                        }
12309                    }
12310                }
12311                "workspace/didChangeConfiguration" => {
12312                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12313                }
12314                "workspace/didChangeWorkspaceFolders" => {
12315                    // In this case register options is an empty object, we can ignore it
12316                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12317                        supported: Some(true),
12318                        change_notifications: Some(OneOf::Right(reg.id)),
12319                    };
12320                    server.update_capabilities(|capabilities| {
12321                        capabilities
12322                            .workspace
12323                            .get_or_insert_default()
12324                            .workspace_folders = Some(caps);
12325                    });
12326                    notify_server_capabilities_updated(&server, cx);
12327                }
12328                "workspace/symbol" => {
12329                    let options = parse_register_capabilities(reg)?;
12330                    server.update_capabilities(|capabilities| {
12331                        capabilities.workspace_symbol_provider = Some(options);
12332                    });
12333                    notify_server_capabilities_updated(&server, cx);
12334                }
12335                "workspace/fileOperations" => {
12336                    if let Some(options) = reg.register_options {
12337                        let caps = serde_json::from_value(options)?;
12338                        server.update_capabilities(|capabilities| {
12339                            capabilities
12340                                .workspace
12341                                .get_or_insert_default()
12342                                .file_operations = Some(caps);
12343                        });
12344                        notify_server_capabilities_updated(&server, cx);
12345                    }
12346                }
12347                "workspace/executeCommand" => {
12348                    if let Some(options) = reg.register_options {
12349                        let options = serde_json::from_value(options)?;
12350                        server.update_capabilities(|capabilities| {
12351                            capabilities.execute_command_provider = Some(options);
12352                        });
12353                        notify_server_capabilities_updated(&server, cx);
12354                    }
12355                }
12356                "textDocument/rangeFormatting" => {
12357                    let options = parse_register_capabilities(reg)?;
12358                    server.update_capabilities(|capabilities| {
12359                        capabilities.document_range_formatting_provider = Some(options);
12360                    });
12361                    notify_server_capabilities_updated(&server, cx);
12362                }
12363                "textDocument/onTypeFormatting" => {
12364                    if let Some(options) = reg
12365                        .register_options
12366                        .map(serde_json::from_value)
12367                        .transpose()?
12368                    {
12369                        server.update_capabilities(|capabilities| {
12370                            capabilities.document_on_type_formatting_provider = Some(options);
12371                        });
12372                        notify_server_capabilities_updated(&server, cx);
12373                    }
12374                }
12375                "textDocument/formatting" => {
12376                    let options = parse_register_capabilities(reg)?;
12377                    server.update_capabilities(|capabilities| {
12378                        capabilities.document_formatting_provider = Some(options);
12379                    });
12380                    notify_server_capabilities_updated(&server, cx);
12381                }
12382                "textDocument/rename" => {
12383                    let options = parse_register_capabilities(reg)?;
12384                    server.update_capabilities(|capabilities| {
12385                        capabilities.rename_provider = Some(options);
12386                    });
12387                    notify_server_capabilities_updated(&server, cx);
12388                }
12389                "textDocument/inlayHint" => {
12390                    let options = parse_register_capabilities(reg)?;
12391                    server.update_capabilities(|capabilities| {
12392                        capabilities.inlay_hint_provider = Some(options);
12393                    });
12394                    notify_server_capabilities_updated(&server, cx);
12395                }
12396                "textDocument/documentSymbol" => {
12397                    let options = parse_register_capabilities(reg)?;
12398                    server.update_capabilities(|capabilities| {
12399                        capabilities.document_symbol_provider = Some(options);
12400                    });
12401                    notify_server_capabilities_updated(&server, cx);
12402                }
12403                "textDocument/codeAction" => {
12404                    let options = parse_register_capabilities(reg)?;
12405                    let provider = match options {
12406                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12407                        OneOf::Right(caps) => caps,
12408                    };
12409                    server.update_capabilities(|capabilities| {
12410                        capabilities.code_action_provider = Some(provider);
12411                    });
12412                    notify_server_capabilities_updated(&server, cx);
12413                }
12414                "textDocument/definition" => {
12415                    let options = parse_register_capabilities(reg)?;
12416                    server.update_capabilities(|capabilities| {
12417                        capabilities.definition_provider = Some(options);
12418                    });
12419                    notify_server_capabilities_updated(&server, cx);
12420                }
12421                "textDocument/completion" => {
12422                    if let Some(caps) = reg
12423                        .register_options
12424                        .map(serde_json::from_value::<CompletionOptions>)
12425                        .transpose()?
12426                    {
12427                        server.update_capabilities(|capabilities| {
12428                            capabilities.completion_provider = Some(caps.clone());
12429                        });
12430
12431                        if let Some(local) = self.as_local() {
12432                            let mut buffers_with_language_server = Vec::new();
12433                            for handle in self.buffer_store.read(cx).buffers() {
12434                                let buffer_id = handle.read(cx).remote_id();
12435                                if local
12436                                    .buffers_opened_in_servers
12437                                    .get(&buffer_id)
12438                                    .filter(|s| s.contains(&server_id))
12439                                    .is_some()
12440                                {
12441                                    buffers_with_language_server.push(handle);
12442                                }
12443                            }
12444                            let triggers = caps
12445                                .trigger_characters
12446                                .unwrap_or_default()
12447                                .into_iter()
12448                                .collect::<BTreeSet<_>>();
12449                            for handle in buffers_with_language_server {
12450                                let triggers = triggers.clone();
12451                                let _ = handle.update(cx, move |buffer, cx| {
12452                                    buffer.set_completion_triggers(server_id, triggers, cx);
12453                                });
12454                            }
12455                        }
12456                        notify_server_capabilities_updated(&server, cx);
12457                    }
12458                }
12459                "textDocument/hover" => {
12460                    let options = parse_register_capabilities(reg)?;
12461                    let provider = match options {
12462                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12463                        OneOf::Right(caps) => caps,
12464                    };
12465                    server.update_capabilities(|capabilities| {
12466                        capabilities.hover_provider = Some(provider);
12467                    });
12468                    notify_server_capabilities_updated(&server, cx);
12469                }
12470                "textDocument/signatureHelp" => {
12471                    if let Some(caps) = reg
12472                        .register_options
12473                        .map(serde_json::from_value)
12474                        .transpose()?
12475                    {
12476                        server.update_capabilities(|capabilities| {
12477                            capabilities.signature_help_provider = Some(caps);
12478                        });
12479                        notify_server_capabilities_updated(&server, cx);
12480                    }
12481                }
12482                "textDocument/didChange" => {
12483                    if let Some(sync_kind) = reg
12484                        .register_options
12485                        .and_then(|opts| opts.get("syncKind").cloned())
12486                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12487                        .transpose()?
12488                    {
12489                        server.update_capabilities(|capabilities| {
12490                            let mut sync_options =
12491                                Self::take_text_document_sync_options(capabilities);
12492                            sync_options.change = Some(sync_kind);
12493                            capabilities.text_document_sync =
12494                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12495                        });
12496                        notify_server_capabilities_updated(&server, cx);
12497                    }
12498                }
12499                "textDocument/didSave" => {
12500                    if let Some(include_text) = reg
12501                        .register_options
12502                        .map(|opts| {
12503                            let transpose = opts
12504                                .get("includeText")
12505                                .cloned()
12506                                .map(serde_json::from_value::<Option<bool>>)
12507                                .transpose();
12508                            match transpose {
12509                                Ok(value) => Ok(value.flatten()),
12510                                Err(e) => Err(e),
12511                            }
12512                        })
12513                        .transpose()?
12514                    {
12515                        server.update_capabilities(|capabilities| {
12516                            let mut sync_options =
12517                                Self::take_text_document_sync_options(capabilities);
12518                            sync_options.save =
12519                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12520                                    include_text,
12521                                }));
12522                            capabilities.text_document_sync =
12523                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12524                        });
12525                        notify_server_capabilities_updated(&server, cx);
12526                    }
12527                }
12528                "textDocument/codeLens" => {
12529                    if let Some(caps) = reg
12530                        .register_options
12531                        .map(serde_json::from_value)
12532                        .transpose()?
12533                    {
12534                        server.update_capabilities(|capabilities| {
12535                            capabilities.code_lens_provider = Some(caps);
12536                        });
12537                        notify_server_capabilities_updated(&server, cx);
12538                    }
12539                }
12540                "textDocument/diagnostic" => {
12541                    if let Some(caps) = reg
12542                        .register_options
12543                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12544                        .transpose()?
12545                    {
12546                        let local = self
12547                            .as_local_mut()
12548                            .context("Expected LSP Store to be local")?;
12549                        let state = local
12550                            .language_servers
12551                            .get_mut(&server_id)
12552                            .context("Could not obtain Language Servers state")?;
12553                        local
12554                            .language_server_dynamic_registrations
12555                            .entry(server_id)
12556                            .or_default()
12557                            .diagnostics
12558                            .insert(Some(reg.id.clone()), caps.clone());
12559
12560                        let supports_workspace_diagnostics =
12561                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12562                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12563                                    diagnostic_options.workspace_diagnostics
12564                                }
12565                                DiagnosticServerCapabilities::RegistrationOptions(
12566                                    diagnostic_registration_options,
12567                                ) => {
12568                                    diagnostic_registration_options
12569                                        .diagnostic_options
12570                                        .workspace_diagnostics
12571                                }
12572                            };
12573
12574                        if supports_workspace_diagnostics(&caps) {
12575                            if let LanguageServerState::Running {
12576                                workspace_diagnostics_refresh_tasks,
12577                                ..
12578                            } = state
12579                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12580                                    Some(reg.id.clone()),
12581                                    caps.clone(),
12582                                    server.clone(),
12583                                    cx,
12584                                )
12585                            {
12586                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12587                            }
12588                        }
12589
12590                        server.update_capabilities(|capabilities| {
12591                            capabilities.diagnostic_provider = Some(caps);
12592                        });
12593
12594                        notify_server_capabilities_updated(&server, cx);
12595
12596                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12597                    }
12598                }
12599                "textDocument/documentColor" => {
12600                    let options = parse_register_capabilities(reg)?;
12601                    let provider = match options {
12602                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12603                        OneOf::Right(caps) => caps,
12604                    };
12605                    server.update_capabilities(|capabilities| {
12606                        capabilities.color_provider = Some(provider);
12607                    });
12608                    notify_server_capabilities_updated(&server, cx);
12609                }
12610                "textDocument/foldingRange" => {
12611                    let options = parse_register_capabilities(reg)?;
12612                    let provider = match options {
12613                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12614                        OneOf::Right(caps) => caps,
12615                    };
12616                    server.update_capabilities(|capabilities| {
12617                        capabilities.folding_range_provider = Some(provider);
12618                    });
12619                    notify_server_capabilities_updated(&server, cx);
12620                }
12621                _ => log::warn!("unhandled capability registration: {reg:?}"),
12622            }
12623        }
12624
12625        Ok(())
12626    }
12627
12628    fn unregister_server_capabilities(
12629        &mut self,
12630        server_id: LanguageServerId,
12631        params: lsp::UnregistrationParams,
12632        cx: &mut Context<Self>,
12633    ) -> anyhow::Result<()> {
12634        let server = self
12635            .language_server_for_id(server_id)
12636            .with_context(|| format!("no server {server_id} found"))?;
12637        for unreg in params.unregisterations.iter() {
12638            match unreg.method.as_str() {
12639                "workspace/didChangeWatchedFiles" => {
12640                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12641                        local_lsp_store
12642                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12643                        true
12644                    } else {
12645                        false
12646                    };
12647                    if notify {
12648                        notify_server_capabilities_updated(&server, cx);
12649                    }
12650                }
12651                "workspace/didChangeConfiguration" => {
12652                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12653                }
12654                "workspace/didChangeWorkspaceFolders" => {
12655                    server.update_capabilities(|capabilities| {
12656                        capabilities
12657                            .workspace
12658                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12659                                workspace_folders: None,
12660                                file_operations: None,
12661                            })
12662                            .workspace_folders = None;
12663                    });
12664                    notify_server_capabilities_updated(&server, cx);
12665                }
12666                "workspace/symbol" => {
12667                    server.update_capabilities(|capabilities| {
12668                        capabilities.workspace_symbol_provider = None
12669                    });
12670                    notify_server_capabilities_updated(&server, cx);
12671                }
12672                "workspace/fileOperations" => {
12673                    server.update_capabilities(|capabilities| {
12674                        capabilities
12675                            .workspace
12676                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12677                                workspace_folders: None,
12678                                file_operations: None,
12679                            })
12680                            .file_operations = None;
12681                    });
12682                    notify_server_capabilities_updated(&server, cx);
12683                }
12684                "workspace/executeCommand" => {
12685                    server.update_capabilities(|capabilities| {
12686                        capabilities.execute_command_provider = None;
12687                    });
12688                    notify_server_capabilities_updated(&server, cx);
12689                }
12690                "textDocument/rangeFormatting" => {
12691                    server.update_capabilities(|capabilities| {
12692                        capabilities.document_range_formatting_provider = None
12693                    });
12694                    notify_server_capabilities_updated(&server, cx);
12695                }
12696                "textDocument/onTypeFormatting" => {
12697                    server.update_capabilities(|capabilities| {
12698                        capabilities.document_on_type_formatting_provider = None;
12699                    });
12700                    notify_server_capabilities_updated(&server, cx);
12701                }
12702                "textDocument/formatting" => {
12703                    server.update_capabilities(|capabilities| {
12704                        capabilities.document_formatting_provider = None;
12705                    });
12706                    notify_server_capabilities_updated(&server, cx);
12707                }
12708                "textDocument/rename" => {
12709                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12710                    notify_server_capabilities_updated(&server, cx);
12711                }
12712                "textDocument/codeAction" => {
12713                    server.update_capabilities(|capabilities| {
12714                        capabilities.code_action_provider = None;
12715                    });
12716                    notify_server_capabilities_updated(&server, cx);
12717                }
12718                "textDocument/definition" => {
12719                    server.update_capabilities(|capabilities| {
12720                        capabilities.definition_provider = None;
12721                    });
12722                    notify_server_capabilities_updated(&server, cx);
12723                }
12724                "textDocument/completion" => {
12725                    server.update_capabilities(|capabilities| {
12726                        capabilities.completion_provider = None;
12727                    });
12728                    notify_server_capabilities_updated(&server, cx);
12729                }
12730                "textDocument/hover" => {
12731                    server.update_capabilities(|capabilities| {
12732                        capabilities.hover_provider = None;
12733                    });
12734                    notify_server_capabilities_updated(&server, cx);
12735                }
12736                "textDocument/signatureHelp" => {
12737                    server.update_capabilities(|capabilities| {
12738                        capabilities.signature_help_provider = None;
12739                    });
12740                    notify_server_capabilities_updated(&server, cx);
12741                }
12742                "textDocument/didChange" => {
12743                    server.update_capabilities(|capabilities| {
12744                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12745                        sync_options.change = None;
12746                        capabilities.text_document_sync =
12747                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12748                    });
12749                    notify_server_capabilities_updated(&server, cx);
12750                }
12751                "textDocument/didSave" => {
12752                    server.update_capabilities(|capabilities| {
12753                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12754                        sync_options.save = None;
12755                        capabilities.text_document_sync =
12756                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12757                    });
12758                    notify_server_capabilities_updated(&server, cx);
12759                }
12760                "textDocument/codeLens" => {
12761                    server.update_capabilities(|capabilities| {
12762                        capabilities.code_lens_provider = None;
12763                    });
12764                    notify_server_capabilities_updated(&server, cx);
12765                }
12766                "textDocument/diagnostic" => {
12767                    let local = self
12768                        .as_local_mut()
12769                        .context("Expected LSP Store to be local")?;
12770
12771                    let state = local
12772                        .language_servers
12773                        .get_mut(&server_id)
12774                        .context("Could not obtain Language Servers state")?;
12775                    let registrations = local
12776                        .language_server_dynamic_registrations
12777                        .get_mut(&server_id)
12778                        .with_context(|| {
12779                            format!("Expected dynamic registration to exist for server {server_id}")
12780                        })?;
12781                    registrations.diagnostics
12782                        .remove(&Some(unreg.id.clone()))
12783                        .with_context(|| format!(
12784                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12785                            unreg.id)
12786                        )?;
12787                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12788
12789                    if let LanguageServerState::Running {
12790                        workspace_diagnostics_refresh_tasks,
12791                        ..
12792                    } = state
12793                    {
12794                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12795                    }
12796
12797                    self.clear_unregistered_diagnostics(
12798                        server_id,
12799                        SharedString::from(unreg.id.clone()),
12800                        cx,
12801                    )?;
12802
12803                    if removed_last_diagnostic_provider {
12804                        server.update_capabilities(|capabilities| {
12805                            debug_assert!(capabilities.diagnostic_provider.is_some());
12806                            capabilities.diagnostic_provider = None;
12807                        });
12808                    }
12809
12810                    notify_server_capabilities_updated(&server, cx);
12811                }
12812                "textDocument/documentColor" => {
12813                    server.update_capabilities(|capabilities| {
12814                        capabilities.color_provider = None;
12815                    });
12816                    notify_server_capabilities_updated(&server, cx);
12817                }
12818                "textDocument/foldingRange" => {
12819                    server.update_capabilities(|capabilities| {
12820                        capabilities.folding_range_provider = None;
12821                    });
12822                    notify_server_capabilities_updated(&server, cx);
12823                }
12824                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12825            }
12826        }
12827
12828        Ok(())
12829    }
12830
12831    fn clear_unregistered_diagnostics(
12832        &mut self,
12833        server_id: LanguageServerId,
12834        cleared_registration_id: SharedString,
12835        cx: &mut Context<Self>,
12836    ) -> anyhow::Result<()> {
12837        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12838
12839        self.buffer_store.update(cx, |buffer_store, cx| {
12840            for buffer_handle in buffer_store.buffers() {
12841                let buffer = buffer_handle.read(cx);
12842                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12843                let Some(abs_path) = abs_path else {
12844                    continue;
12845                };
12846                affected_abs_paths.insert(abs_path);
12847            }
12848        });
12849
12850        let local = self.as_local().context("Expected LSP Store to be local")?;
12851        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12852            let Some(worktree) = self
12853                .worktree_store
12854                .read(cx)
12855                .worktree_for_id(*worktree_id, cx)
12856            else {
12857                continue;
12858            };
12859
12860            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
12861                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
12862                    let has_matching_registration =
12863                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
12864                            entry.diagnostic.registration_id.as_ref()
12865                                == Some(&cleared_registration_id)
12866                        });
12867                    if has_matching_registration {
12868                        let abs_path = worktree.read(cx).absolutize(rel_path);
12869                        affected_abs_paths.insert(abs_path);
12870                    }
12871                }
12872            }
12873        }
12874
12875        if affected_abs_paths.is_empty() {
12876            return Ok(());
12877        }
12878
12879        // Send a fake diagnostic update which clears the state for the registration ID
12880        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
12881            affected_abs_paths
12882                .into_iter()
12883                .map(|abs_path| DocumentDiagnosticsUpdate {
12884                    diagnostics: DocumentDiagnostics {
12885                        diagnostics: Vec::new(),
12886                        document_abs_path: abs_path,
12887                        version: None,
12888                    },
12889                    result_id: None,
12890                    registration_id: Some(cleared_registration_id.clone()),
12891                    server_id,
12892                    disk_based_sources: Cow::Borrowed(&[]),
12893                })
12894                .collect();
12895
12896        let merge_registration_id = cleared_registration_id.clone();
12897        self.merge_diagnostic_entries(
12898            clears,
12899            move |_, diagnostic, _| {
12900                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
12901                    diagnostic.registration_id != Some(merge_registration_id.clone())
12902                } else {
12903                    true
12904                }
12905            },
12906            cx,
12907        )?;
12908
12909        Ok(())
12910    }
12911
12912    async fn deduplicate_range_based_lsp_requests<T>(
12913        lsp_store: &Entity<Self>,
12914        server_id: Option<LanguageServerId>,
12915        lsp_request_id: LspRequestId,
12916        proto_request: &T::ProtoRequest,
12917        range: Range<Anchor>,
12918        cx: &mut AsyncApp,
12919    ) -> Result<()>
12920    where
12921        T: LspCommand,
12922        T::ProtoRequest: proto::LspRequestMessage,
12923    {
12924        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12925        let version = deserialize_version(proto_request.buffer_version());
12926        let buffer = lsp_store.update(cx, |this, cx| {
12927            this.buffer_store.read(cx).get_existing(buffer_id)
12928        })?;
12929        buffer
12930            .update(cx, |buffer, _| buffer.wait_for_version(version))
12931            .await?;
12932        lsp_store.update(cx, |lsp_store, cx| {
12933            let buffer_snapshot = buffer.read(cx).snapshot();
12934            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12935            let chunks_queried_for = lsp_data
12936                .inlay_hints
12937                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
12938                .collect::<Vec<_>>();
12939            match chunks_queried_for.as_slice() {
12940                &[chunk] => {
12941                    let key = LspKey {
12942                        request_type: TypeId::of::<T>(),
12943                        server_queried: server_id,
12944                    };
12945                    let previous_request = lsp_data
12946                        .chunk_lsp_requests
12947                        .entry(key)
12948                        .or_default()
12949                        .insert(chunk, lsp_request_id);
12950                    if let Some((previous_request, running_requests)) =
12951                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12952                    {
12953                        running_requests.remove(&previous_request);
12954                    }
12955                }
12956                _ambiguous_chunks => {
12957                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12958                    // there, a buffer version-based check will be performed and outdated requests discarded.
12959                }
12960            }
12961            anyhow::Ok(())
12962        })?;
12963
12964        Ok(())
12965    }
12966
12967    async fn query_lsp_locally<T>(
12968        lsp_store: Entity<Self>,
12969        for_server_id: Option<LanguageServerId>,
12970        sender_id: proto::PeerId,
12971        lsp_request_id: LspRequestId,
12972        proto_request: T::ProtoRequest,
12973        position: Option<Anchor>,
12974        cx: &mut AsyncApp,
12975    ) -> Result<()>
12976    where
12977        T: LspCommand + Clone,
12978        T::ProtoRequest: proto::LspRequestMessage,
12979        <T::ProtoRequest as proto::RequestMessage>::Response:
12980            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12981    {
12982        let (buffer_version, buffer) =
12983            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
12984        let request =
12985            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12986        let key = LspKey {
12987            request_type: TypeId::of::<T>(),
12988            server_queried: for_server_id,
12989        };
12990        lsp_store.update(cx, |lsp_store, cx| {
12991            let request_task = match for_server_id {
12992                Some(server_id) => {
12993                    let server_task = lsp_store.request_lsp(
12994                        buffer.clone(),
12995                        LanguageServerToQuery::Other(server_id),
12996                        request.clone(),
12997                        cx,
12998                    );
12999                    cx.background_spawn(async move {
13000                        let mut responses = Vec::new();
13001                        match server_task.await {
13002                            Ok(response) => responses.push((server_id, response)),
13003                            // rust-analyzer likes to error with this when its still loading up
13004                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13005                            Err(e) => log::error!(
13006                                "Error handling response for request {request:?}: {e:#}"
13007                            ),
13008                        }
13009                        responses
13010                    })
13011                }
13012                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13013            };
13014            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13015            if T::ProtoRequest::stop_previous_requests() {
13016                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13017                    lsp_requests.clear();
13018                }
13019            }
13020            lsp_data.lsp_requests.entry(key).or_default().insert(
13021                lsp_request_id,
13022                cx.spawn(async move |lsp_store, cx| {
13023                    let response = request_task.await;
13024                    lsp_store
13025                        .update(cx, |lsp_store, cx| {
13026                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13027                            {
13028                                let response = response
13029                                    .into_iter()
13030                                    .map(|(server_id, response)| {
13031                                        (
13032                                            server_id.to_proto(),
13033                                            T::response_to_proto(
13034                                                response,
13035                                                lsp_store,
13036                                                sender_id,
13037                                                &buffer_version,
13038                                                cx,
13039                                            )
13040                                            .into(),
13041                                        )
13042                                    })
13043                                    .collect::<HashMap<_, _>>();
13044                                match client.send_lsp_response::<T::ProtoRequest>(
13045                                    project_id,
13046                                    lsp_request_id,
13047                                    response,
13048                                ) {
13049                                    Ok(()) => {}
13050                                    Err(e) => {
13051                                        log::error!("Failed to send LSP response: {e:#}",)
13052                                    }
13053                                }
13054                            }
13055                        })
13056                        .ok();
13057                }),
13058            );
13059        });
13060        Ok(())
13061    }
13062
13063    async fn wait_for_buffer_version<T>(
13064        lsp_store: &Entity<Self>,
13065        proto_request: &T::ProtoRequest,
13066        cx: &mut AsyncApp,
13067    ) -> Result<(Global, Entity<Buffer>)>
13068    where
13069        T: LspCommand,
13070        T::ProtoRequest: proto::LspRequestMessage,
13071    {
13072        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13073        let version = deserialize_version(proto_request.buffer_version());
13074        let buffer = lsp_store.update(cx, |this, cx| {
13075            this.buffer_store.read(cx).get_existing(buffer_id)
13076        })?;
13077        buffer
13078            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13079            .await?;
13080        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13081        Ok((buffer_version, buffer))
13082    }
13083
13084    fn take_text_document_sync_options(
13085        capabilities: &mut lsp::ServerCapabilities,
13086    ) -> lsp::TextDocumentSyncOptions {
13087        match capabilities.text_document_sync.take() {
13088            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13089            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13090                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13091                sync_options.change = Some(sync_kind);
13092                sync_options
13093            }
13094            None => lsp::TextDocumentSyncOptions::default(),
13095        }
13096    }
13097
13098    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13099        self.downstream_client.clone()
13100    }
13101
13102    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13103        self.worktree_store.clone()
13104    }
13105
13106    /// Gets what's stored in the LSP data for the given buffer.
13107    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13108        self.lsp_data.get_mut(&buffer_id)
13109    }
13110
13111    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13112    /// new [`BufferLspData`] will be created to replace the previous state.
13113    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13114        let (buffer_id, buffer_version) =
13115            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13116        let lsp_data = self
13117            .lsp_data
13118            .entry(buffer_id)
13119            .or_insert_with(|| BufferLspData::new(buffer, cx));
13120        if buffer_version.changed_since(&lsp_data.buffer_version) {
13121            // To send delta requests for semantic tokens, the previous tokens
13122            // need to be kept between buffer changes.
13123            let semantic_tokens = lsp_data.semantic_tokens.take();
13124            *lsp_data = BufferLspData::new(buffer, cx);
13125            lsp_data.semantic_tokens = semantic_tokens;
13126        }
13127        lsp_data
13128    }
13129}
13130
13131// Registration with registerOptions as null, should fallback to true.
13132// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13133fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13134    reg: lsp::Registration,
13135) -> Result<OneOf<bool, T>> {
13136    Ok(match reg.register_options {
13137        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13138        None => OneOf::Left(true),
13139    })
13140}
13141
13142fn subscribe_to_binary_statuses(
13143    languages: &Arc<LanguageRegistry>,
13144    cx: &mut Context<'_, LspStore>,
13145) -> Task<()> {
13146    let mut server_statuses = languages.language_server_binary_statuses();
13147    cx.spawn(async move |lsp_store, cx| {
13148        while let Some((server_name, binary_status)) = server_statuses.next().await {
13149            if lsp_store
13150                .update(cx, |_, cx| {
13151                    let mut message = None;
13152                    let binary_status = match binary_status {
13153                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13154                        BinaryStatus::CheckingForUpdate => {
13155                            proto::ServerBinaryStatus::CheckingForUpdate
13156                        }
13157                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13158                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13159                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13160                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13161                        BinaryStatus::Failed { error } => {
13162                            message = Some(error);
13163                            proto::ServerBinaryStatus::Failed
13164                        }
13165                    };
13166                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13167                        // Binary updates are about the binary that might not have any language server id at that point.
13168                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13169                        language_server_id: LanguageServerId(0),
13170                        name: Some(server_name),
13171                        message: proto::update_language_server::Variant::StatusUpdate(
13172                            proto::StatusUpdate {
13173                                message,
13174                                status: Some(proto::status_update::Status::Binary(
13175                                    binary_status as i32,
13176                                )),
13177                            },
13178                        ),
13179                    });
13180                })
13181                .is_err()
13182            {
13183                break;
13184            }
13185        }
13186    })
13187}
13188
13189fn lsp_workspace_diagnostics_refresh(
13190    registration_id: Option<String>,
13191    options: DiagnosticServerCapabilities,
13192    server: Arc<LanguageServer>,
13193    cx: &mut Context<'_, LspStore>,
13194) -> Option<WorkspaceRefreshTask> {
13195    let identifier = workspace_diagnostic_identifier(&options)?;
13196    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13197
13198    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13199    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13200    refresh_tx.try_send(()).ok();
13201
13202    let request_timeout = ProjectSettings::get_global(cx)
13203        .global_lsp_settings
13204        .get_request_timeout();
13205
13206    // 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.
13207    // This allows users to increase the duration if need be
13208    let timeout = if request_timeout != Duration::ZERO {
13209        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13210    } else {
13211        request_timeout
13212    };
13213
13214    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13215        let mut attempts = 0;
13216        let max_attempts = 50;
13217        let mut requests = 0;
13218
13219        loop {
13220            let Some(()) = refresh_rx.recv().await else {
13221                return;
13222            };
13223
13224            'request: loop {
13225                requests += 1;
13226                if attempts > max_attempts {
13227                    log::error!(
13228                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13229                    );
13230                    return;
13231                }
13232                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13233                cx.background_executor()
13234                    .timer(Duration::from_millis(backoff_millis))
13235                    .await;
13236                attempts += 1;
13237
13238                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13239                    lsp_store
13240                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13241                        .into_iter()
13242                        .filter_map(|(abs_path, result_id)| {
13243                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13244                            Some(lsp::PreviousResultId {
13245                                uri,
13246                                value: result_id.to_string(),
13247                            })
13248                        })
13249                        .collect()
13250                }) else {
13251                    return;
13252                };
13253
13254                let token = if let Some(registration_id) = &registration_id {
13255                    format!(
13256                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13257                        server.server_id(),
13258                    )
13259                } else {
13260                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13261                };
13262
13263                progress_rx.try_recv().ok();
13264                let timer = server.request_timer(timeout).fuse();
13265                let progress = pin!(progress_rx.recv().fuse());
13266                let response_result = server
13267                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13268                        lsp::WorkspaceDiagnosticParams {
13269                            previous_result_ids,
13270                            identifier: identifier.clone(),
13271                            work_done_progress_params: Default::default(),
13272                            partial_result_params: lsp::PartialResultParams {
13273                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13274                            },
13275                        },
13276                        select(timer, progress).then(|either| match either {
13277                            Either::Left((message, ..)) => ready(message).left_future(),
13278                            Either::Right(..) => pending::<String>().right_future(),
13279                        }),
13280                    )
13281                    .await;
13282
13283                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13284                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13285                match response_result {
13286                    ConnectionResult::Timeout => {
13287                        log::error!("Timeout during workspace diagnostics pull");
13288                        continue 'request;
13289                    }
13290                    ConnectionResult::ConnectionReset => {
13291                        log::error!("Server closed a workspace diagnostics pull request");
13292                        continue 'request;
13293                    }
13294                    ConnectionResult::Result(Err(e)) => {
13295                        log::error!("Error during workspace diagnostics pull: {e:#}");
13296                        break 'request;
13297                    }
13298                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13299                        attempts = 0;
13300                        if lsp_store
13301                            .update(cx, |lsp_store, cx| {
13302                                lsp_store.apply_workspace_diagnostic_report(
13303                                    server.server_id(),
13304                                    pulled_diagnostics,
13305                                    registration_id_shared.clone(),
13306                                    cx,
13307                                )
13308                            })
13309                            .is_err()
13310                        {
13311                            return;
13312                        }
13313                        break 'request;
13314                    }
13315                }
13316            }
13317        }
13318    });
13319
13320    Some(WorkspaceRefreshTask {
13321        refresh_tx,
13322        progress_tx,
13323        task: workspace_query_language_server,
13324    })
13325}
13326
13327fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13328    match &options {
13329        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13330            .identifier
13331            .as_deref()
13332            .map(SharedString::new),
13333        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13334            let diagnostic_options = &registration_options.diagnostic_options;
13335            diagnostic_options
13336                .identifier
13337                .as_deref()
13338                .map(SharedString::new)
13339        }
13340    }
13341}
13342
13343fn workspace_diagnostic_identifier(
13344    options: &DiagnosticServerCapabilities,
13345) -> Option<Option<String>> {
13346    match &options {
13347        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13348            if !diagnostic_options.workspace_diagnostics {
13349                return None;
13350            }
13351            Some(diagnostic_options.identifier.clone())
13352        }
13353        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13354            let diagnostic_options = &registration_options.diagnostic_options;
13355            if !diagnostic_options.workspace_diagnostics {
13356                return None;
13357            }
13358            Some(diagnostic_options.identifier.clone())
13359        }
13360    }
13361}
13362
13363fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13364    let CompletionSource::BufferWord {
13365        word_range,
13366        resolved,
13367    } = &mut completion.source
13368    else {
13369        return;
13370    };
13371    if *resolved {
13372        return;
13373    }
13374
13375    if completion.new_text
13376        != snapshot
13377            .text_for_range(word_range.clone())
13378            .collect::<String>()
13379    {
13380        return;
13381    }
13382
13383    let mut offset = 0;
13384    for chunk in snapshot.chunks(word_range.clone(), true) {
13385        let end_offset = offset + chunk.text.len();
13386        if let Some(highlight_id) = chunk.syntax_highlight_id {
13387            completion
13388                .label
13389                .runs
13390                .push((offset..end_offset, highlight_id));
13391        }
13392        offset = end_offset;
13393    }
13394    *resolved = true;
13395}
13396
13397impl EventEmitter<LspStoreEvent> for LspStore {}
13398
13399fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13400    hover
13401        .contents
13402        .retain(|hover_block| !hover_block.text.trim().is_empty());
13403    if hover.contents.is_empty() {
13404        None
13405    } else {
13406        Some(hover)
13407    }
13408}
13409
13410async fn populate_labels_for_completions(
13411    new_completions: Vec<CoreCompletion>,
13412    language: Option<Arc<Language>>,
13413    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13414) -> Vec<Completion> {
13415    let lsp_completions = new_completions
13416        .iter()
13417        .filter_map(|new_completion| {
13418            new_completion
13419                .source
13420                .lsp_completion(true)
13421                .map(|lsp_completion| lsp_completion.into_owned())
13422        })
13423        .collect::<Vec<_>>();
13424
13425    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13426        lsp_adapter
13427            .labels_for_completions(&lsp_completions, language)
13428            .await
13429            .log_err()
13430            .unwrap_or_default()
13431    } else {
13432        Vec::new()
13433    }
13434    .into_iter()
13435    .fuse();
13436
13437    let mut completions = Vec::new();
13438    for completion in new_completions {
13439        match completion.source.lsp_completion(true) {
13440            Some(lsp_completion) => {
13441                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13442
13443                let mut label = labels.next().flatten().unwrap_or_else(|| {
13444                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13445                });
13446                ensure_uniform_list_compatible_label(&mut label);
13447                completions.push(Completion {
13448                    label,
13449                    documentation,
13450                    replace_range: completion.replace_range,
13451                    new_text: completion.new_text,
13452                    insert_text_mode: lsp_completion.insert_text_mode,
13453                    source: completion.source,
13454                    icon_path: None,
13455                    confirm: None,
13456                    match_start: None,
13457                    snippet_deduplication_key: None,
13458                });
13459            }
13460            None => {
13461                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13462                ensure_uniform_list_compatible_label(&mut label);
13463                completions.push(Completion {
13464                    label,
13465                    documentation: None,
13466                    replace_range: completion.replace_range,
13467                    new_text: completion.new_text,
13468                    source: completion.source,
13469                    insert_text_mode: None,
13470                    icon_path: None,
13471                    confirm: None,
13472                    match_start: None,
13473                    snippet_deduplication_key: None,
13474                });
13475            }
13476        }
13477    }
13478    completions
13479}
13480
13481#[derive(Debug)]
13482pub enum LanguageServerToQuery {
13483    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13484    FirstCapable,
13485    /// Query a specific language server.
13486    Other(LanguageServerId),
13487}
13488
13489#[derive(Default)]
13490struct RenamePathsWatchedForServer {
13491    did_rename: Vec<RenameActionPredicate>,
13492    will_rename: Vec<RenameActionPredicate>,
13493}
13494
13495impl RenamePathsWatchedForServer {
13496    fn with_did_rename_patterns(
13497        mut self,
13498        did_rename: Option<&FileOperationRegistrationOptions>,
13499    ) -> Self {
13500        if let Some(did_rename) = did_rename {
13501            self.did_rename = did_rename
13502                .filters
13503                .iter()
13504                .filter_map(|filter| filter.try_into().log_err())
13505                .collect();
13506        }
13507        self
13508    }
13509    fn with_will_rename_patterns(
13510        mut self,
13511        will_rename: Option<&FileOperationRegistrationOptions>,
13512    ) -> Self {
13513        if let Some(will_rename) = will_rename {
13514            self.will_rename = will_rename
13515                .filters
13516                .iter()
13517                .filter_map(|filter| filter.try_into().log_err())
13518                .collect();
13519        }
13520        self
13521    }
13522
13523    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13524        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13525    }
13526    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13527        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13528    }
13529}
13530
13531impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13532    type Error = globset::Error;
13533    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13534        Ok(Self {
13535            kind: ops.pattern.matches.clone(),
13536            glob: GlobBuilder::new(&ops.pattern.glob)
13537                .case_insensitive(
13538                    ops.pattern
13539                        .options
13540                        .as_ref()
13541                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13542                )
13543                .build()?
13544                .compile_matcher(),
13545        })
13546    }
13547}
13548struct RenameActionPredicate {
13549    glob: GlobMatcher,
13550    kind: Option<FileOperationPatternKind>,
13551}
13552
13553impl RenameActionPredicate {
13554    // Returns true if language server should be notified
13555    fn eval(&self, path: &str, is_dir: bool) -> bool {
13556        self.kind.as_ref().is_none_or(|kind| {
13557            let expected_kind = if is_dir {
13558                FileOperationPatternKind::Folder
13559            } else {
13560                FileOperationPatternKind::File
13561            };
13562            kind == &expected_kind
13563        }) && self.glob.is_match(path)
13564    }
13565}
13566
13567#[derive(Default)]
13568struct LanguageServerWatchedPaths {
13569    worktree_paths: HashMap<WorktreeId, GlobSet>,
13570    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13571}
13572
13573#[derive(Default)]
13574struct LanguageServerWatchedPathsBuilder {
13575    worktree_paths: HashMap<WorktreeId, GlobSet>,
13576    abs_paths: HashMap<Arc<Path>, GlobSet>,
13577}
13578
13579impl LanguageServerWatchedPathsBuilder {
13580    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13581        self.worktree_paths.insert(worktree_id, glob_set);
13582    }
13583    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13584        self.abs_paths.insert(path, glob_set);
13585    }
13586    fn build(
13587        self,
13588        fs: Arc<dyn Fs>,
13589        language_server_id: LanguageServerId,
13590        cx: &mut Context<LspStore>,
13591    ) -> LanguageServerWatchedPaths {
13592        let lsp_store = cx.weak_entity();
13593
13594        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13595        let abs_paths = self
13596            .abs_paths
13597            .into_iter()
13598            .map(|(abs_path, globset)| {
13599                let task = cx.spawn({
13600                    let abs_path = abs_path.clone();
13601                    let fs = fs.clone();
13602
13603                    let lsp_store = lsp_store.clone();
13604                    async move |_, cx| {
13605                        maybe!(async move {
13606                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13607                            while let Some(update) = push_updates.0.next().await {
13608                                let action = lsp_store
13609                                    .update(cx, |this, _| {
13610                                        let Some(local) = this.as_local() else {
13611                                            return ControlFlow::Break(());
13612                                        };
13613                                        let Some(watcher) = local
13614                                            .language_server_watched_paths
13615                                            .get(&language_server_id)
13616                                        else {
13617                                            return ControlFlow::Break(());
13618                                        };
13619                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13620                                            "Watched abs path is not registered with a watcher",
13621                                        );
13622                                        let matching_entries = update
13623                                            .into_iter()
13624                                            .filter(|event| globs.is_match(&event.path))
13625                                            .collect::<Vec<_>>();
13626                                        this.lsp_notify_abs_paths_changed(
13627                                            language_server_id,
13628                                            matching_entries,
13629                                        );
13630                                        ControlFlow::Continue(())
13631                                    })
13632                                    .ok()?;
13633
13634                                if action.is_break() {
13635                                    break;
13636                                }
13637                            }
13638                            Some(())
13639                        })
13640                        .await;
13641                    }
13642                });
13643                (abs_path, (globset, task))
13644            })
13645            .collect();
13646        LanguageServerWatchedPaths {
13647            worktree_paths: self.worktree_paths,
13648            abs_paths,
13649        }
13650    }
13651}
13652
13653struct LspBufferSnapshot {
13654    version: i32,
13655    snapshot: TextBufferSnapshot,
13656}
13657
13658/// A prompt requested by LSP server.
13659#[derive(Clone, Debug)]
13660pub struct LanguageServerPromptRequest {
13661    pub id: usize,
13662    pub level: PromptLevel,
13663    pub message: String,
13664    pub actions: Vec<MessageActionItem>,
13665    pub lsp_name: String,
13666    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13667}
13668
13669impl LanguageServerPromptRequest {
13670    pub fn new(
13671        level: PromptLevel,
13672        message: String,
13673        actions: Vec<MessageActionItem>,
13674        lsp_name: String,
13675        response_channel: smol::channel::Sender<MessageActionItem>,
13676    ) -> Self {
13677        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13678        LanguageServerPromptRequest {
13679            id,
13680            level,
13681            message,
13682            actions,
13683            lsp_name,
13684            response_channel,
13685        }
13686    }
13687    pub async fn respond(self, index: usize) -> Option<()> {
13688        if let Some(response) = self.actions.into_iter().nth(index) {
13689            self.response_channel.send(response).await.ok()
13690        } else {
13691            None
13692        }
13693    }
13694
13695    #[cfg(any(test, feature = "test-support"))]
13696    pub fn test(
13697        level: PromptLevel,
13698        message: String,
13699        actions: Vec<MessageActionItem>,
13700        lsp_name: String,
13701    ) -> Self {
13702        let (tx, _rx) = smol::channel::unbounded();
13703        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13704    }
13705}
13706impl PartialEq for LanguageServerPromptRequest {
13707    fn eq(&self, other: &Self) -> bool {
13708        self.message == other.message && self.actions == other.actions
13709    }
13710}
13711
13712#[derive(Clone, Debug, PartialEq)]
13713pub enum LanguageServerLogType {
13714    Log(MessageType),
13715    Trace { verbose_info: Option<String> },
13716    Rpc { received: bool },
13717}
13718
13719impl LanguageServerLogType {
13720    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13721        match self {
13722            Self::Log(log_type) => {
13723                use proto::log_message::LogLevel;
13724                let level = match *log_type {
13725                    MessageType::ERROR => LogLevel::Error,
13726                    MessageType::WARNING => LogLevel::Warning,
13727                    MessageType::INFO => LogLevel::Info,
13728                    MessageType::LOG => LogLevel::Log,
13729                    other => {
13730                        log::warn!("Unknown lsp log message type: {other:?}");
13731                        LogLevel::Log
13732                    }
13733                };
13734                proto::language_server_log::LogType::Log(proto::LogMessage {
13735                    level: level as i32,
13736                })
13737            }
13738            Self::Trace { verbose_info } => {
13739                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13740                    verbose_info: verbose_info.to_owned(),
13741                })
13742            }
13743            Self::Rpc { received } => {
13744                let kind = if *received {
13745                    proto::rpc_message::Kind::Received
13746                } else {
13747                    proto::rpc_message::Kind::Sent
13748                };
13749                let kind = kind as i32;
13750                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13751            }
13752        }
13753    }
13754
13755    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13756        use proto::log_message::LogLevel;
13757        use proto::rpc_message;
13758        match log_type {
13759            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13760                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13761                    LogLevel::Error => MessageType::ERROR,
13762                    LogLevel::Warning => MessageType::WARNING,
13763                    LogLevel::Info => MessageType::INFO,
13764                    LogLevel::Log => MessageType::LOG,
13765                },
13766            ),
13767            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13768                verbose_info: trace_message.verbose_info,
13769            },
13770            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13771                received: match rpc_message::Kind::from_i32(message.kind)
13772                    .unwrap_or(rpc_message::Kind::Received)
13773                {
13774                    rpc_message::Kind::Received => true,
13775                    rpc_message::Kind::Sent => false,
13776                },
13777            },
13778        }
13779    }
13780}
13781
13782pub struct WorkspaceRefreshTask {
13783    refresh_tx: mpsc::Sender<()>,
13784    progress_tx: mpsc::Sender<()>,
13785    #[allow(dead_code)]
13786    task: Task<()>,
13787}
13788
13789pub enum LanguageServerState {
13790    Starting {
13791        startup: Task<Option<Arc<LanguageServer>>>,
13792        /// List of language servers that will be added to the workspace once it's initialization completes.
13793        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13794    },
13795
13796    Running {
13797        adapter: Arc<CachedLspAdapter>,
13798        server: Arc<LanguageServer>,
13799        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13800        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13801    },
13802}
13803
13804impl LanguageServerState {
13805    fn add_workspace_folder(&self, uri: Uri) {
13806        match self {
13807            LanguageServerState::Starting {
13808                pending_workspace_folders,
13809                ..
13810            } => {
13811                pending_workspace_folders.lock().insert(uri);
13812            }
13813            LanguageServerState::Running { server, .. } => {
13814                server.add_workspace_folder(uri);
13815            }
13816        }
13817    }
13818    fn _remove_workspace_folder(&self, uri: Uri) {
13819        match self {
13820            LanguageServerState::Starting {
13821                pending_workspace_folders,
13822                ..
13823            } => {
13824                pending_workspace_folders.lock().remove(&uri);
13825            }
13826            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13827        }
13828    }
13829}
13830
13831impl std::fmt::Debug for LanguageServerState {
13832    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13833        match self {
13834            LanguageServerState::Starting { .. } => {
13835                f.debug_struct("LanguageServerState::Starting").finish()
13836            }
13837            LanguageServerState::Running { .. } => {
13838                f.debug_struct("LanguageServerState::Running").finish()
13839            }
13840        }
13841    }
13842}
13843
13844#[derive(Clone, Debug, Serialize)]
13845pub struct LanguageServerProgress {
13846    pub is_disk_based_diagnostics_progress: bool,
13847    pub is_cancellable: bool,
13848    pub title: Option<String>,
13849    pub message: Option<String>,
13850    pub percentage: Option<usize>,
13851    #[serde(skip_serializing)]
13852    pub last_update_at: Instant,
13853}
13854
13855#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13856pub struct DiagnosticSummary {
13857    pub error_count: usize,
13858    pub warning_count: usize,
13859}
13860
13861impl DiagnosticSummary {
13862    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13863        let mut this = Self {
13864            error_count: 0,
13865            warning_count: 0,
13866        };
13867
13868        for entry in diagnostics {
13869            if entry.diagnostic.is_primary {
13870                match entry.diagnostic.severity {
13871                    DiagnosticSeverity::ERROR => this.error_count += 1,
13872                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13873                    _ => {}
13874                }
13875            }
13876        }
13877
13878        this
13879    }
13880
13881    pub fn is_empty(&self) -> bool {
13882        self.error_count == 0 && self.warning_count == 0
13883    }
13884
13885    pub fn to_proto(
13886        self,
13887        language_server_id: LanguageServerId,
13888        path: &RelPath,
13889    ) -> proto::DiagnosticSummary {
13890        proto::DiagnosticSummary {
13891            path: path.to_proto(),
13892            language_server_id: language_server_id.0 as u64,
13893            error_count: self.error_count as u32,
13894            warning_count: self.warning_count as u32,
13895        }
13896    }
13897}
13898
13899#[derive(Clone, Debug)]
13900pub enum CompletionDocumentation {
13901    /// There is no documentation for this completion.
13902    Undocumented,
13903    /// A single line of documentation.
13904    SingleLine(SharedString),
13905    /// Multiple lines of plain text documentation.
13906    MultiLinePlainText(SharedString),
13907    /// Markdown documentation.
13908    MultiLineMarkdown(SharedString),
13909    /// Both single line and multiple lines of plain text documentation.
13910    SingleLineAndMultiLinePlainText {
13911        single_line: SharedString,
13912        plain_text: Option<SharedString>,
13913    },
13914}
13915
13916impl CompletionDocumentation {
13917    #[cfg(any(test, feature = "test-support"))]
13918    pub fn text(&self) -> SharedString {
13919        match self {
13920            CompletionDocumentation::Undocumented => "".into(),
13921            CompletionDocumentation::SingleLine(s) => s.clone(),
13922            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13923            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13924            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13925                single_line.clone()
13926            }
13927        }
13928    }
13929}
13930
13931impl From<lsp::Documentation> for CompletionDocumentation {
13932    fn from(docs: lsp::Documentation) -> Self {
13933        match docs {
13934            lsp::Documentation::String(text) => {
13935                if text.lines().count() <= 1 {
13936                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
13937                } else {
13938                    CompletionDocumentation::MultiLinePlainText(text.into())
13939                }
13940            }
13941
13942            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13943                lsp::MarkupKind::PlainText => {
13944                    if value.lines().count() <= 1 {
13945                        CompletionDocumentation::SingleLine(value.into())
13946                    } else {
13947                        CompletionDocumentation::MultiLinePlainText(value.into())
13948                    }
13949                }
13950
13951                lsp::MarkupKind::Markdown => {
13952                    CompletionDocumentation::MultiLineMarkdown(value.into())
13953                }
13954            },
13955        }
13956    }
13957}
13958
13959pub enum ResolvedHint {
13960    Resolved(InlayHint),
13961    Resolving(Shared<Task<()>>),
13962}
13963
13964pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
13965    glob.components()
13966        .take_while(|component| match component {
13967            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13968            _ => true,
13969        })
13970        .collect()
13971}
13972
13973pub struct SshLspAdapter {
13974    name: LanguageServerName,
13975    binary: LanguageServerBinary,
13976    initialization_options: Option<String>,
13977    code_action_kinds: Option<Vec<CodeActionKind>>,
13978}
13979
13980impl SshLspAdapter {
13981    pub fn new(
13982        name: LanguageServerName,
13983        binary: LanguageServerBinary,
13984        initialization_options: Option<String>,
13985        code_action_kinds: Option<String>,
13986    ) -> Self {
13987        Self {
13988            name,
13989            binary,
13990            initialization_options,
13991            code_action_kinds: code_action_kinds
13992                .as_ref()
13993                .and_then(|c| serde_json::from_str(c).ok()),
13994        }
13995    }
13996}
13997
13998impl LspInstaller for SshLspAdapter {
13999    type BinaryVersion = ();
14000    async fn check_if_user_installed(
14001        &self,
14002        _: &dyn LspAdapterDelegate,
14003        _: Option<Toolchain>,
14004        _: &AsyncApp,
14005    ) -> Option<LanguageServerBinary> {
14006        Some(self.binary.clone())
14007    }
14008
14009    async fn cached_server_binary(
14010        &self,
14011        _: PathBuf,
14012        _: &dyn LspAdapterDelegate,
14013    ) -> Option<LanguageServerBinary> {
14014        None
14015    }
14016
14017    async fn fetch_latest_server_version(
14018        &self,
14019        _: &dyn LspAdapterDelegate,
14020        _: bool,
14021        _: &mut AsyncApp,
14022    ) -> Result<()> {
14023        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14024    }
14025
14026    async fn fetch_server_binary(
14027        &self,
14028        _: (),
14029        _: PathBuf,
14030        _: &dyn LspAdapterDelegate,
14031    ) -> Result<LanguageServerBinary> {
14032        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14033    }
14034}
14035
14036#[async_trait(?Send)]
14037impl LspAdapter for SshLspAdapter {
14038    fn name(&self) -> LanguageServerName {
14039        self.name.clone()
14040    }
14041
14042    async fn initialization_options(
14043        self: Arc<Self>,
14044        _: &Arc<dyn LspAdapterDelegate>,
14045        _: &mut AsyncApp,
14046    ) -> Result<Option<serde_json::Value>> {
14047        let Some(options) = &self.initialization_options else {
14048            return Ok(None);
14049        };
14050        let result = serde_json::from_str(options)?;
14051        Ok(result)
14052    }
14053
14054    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14055        self.code_action_kinds.clone()
14056    }
14057}
14058
14059pub fn language_server_settings<'a>(
14060    delegate: &'a dyn LspAdapterDelegate,
14061    language: &LanguageServerName,
14062    cx: &'a App,
14063) -> Option<&'a LspSettings> {
14064    language_server_settings_for(
14065        SettingsLocation {
14066            worktree_id: delegate.worktree_id(),
14067            path: RelPath::empty(),
14068        },
14069        language,
14070        cx,
14071    )
14072}
14073
14074pub fn language_server_settings_for<'a>(
14075    location: SettingsLocation<'a>,
14076    language: &LanguageServerName,
14077    cx: &'a App,
14078) -> Option<&'a LspSettings> {
14079    ProjectSettings::get(Some(location), cx).lsp.get(language)
14080}
14081
14082pub struct LocalLspAdapterDelegate {
14083    lsp_store: WeakEntity<LspStore>,
14084    worktree: worktree::Snapshot,
14085    fs: Arc<dyn Fs>,
14086    http_client: Arc<dyn HttpClient>,
14087    language_registry: Arc<LanguageRegistry>,
14088    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14089}
14090
14091impl LocalLspAdapterDelegate {
14092    pub fn new(
14093        language_registry: Arc<LanguageRegistry>,
14094        environment: &Entity<ProjectEnvironment>,
14095        lsp_store: WeakEntity<LspStore>,
14096        worktree: &Entity<Worktree>,
14097        http_client: Arc<dyn HttpClient>,
14098        fs: Arc<dyn Fs>,
14099        cx: &mut App,
14100    ) -> Arc<Self> {
14101        let load_shell_env_task =
14102            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14103
14104        Arc::new(Self {
14105            lsp_store,
14106            worktree: worktree.read(cx).snapshot(),
14107            fs,
14108            http_client,
14109            language_registry,
14110            load_shell_env_task,
14111        })
14112    }
14113
14114    pub fn from_local_lsp(
14115        local: &LocalLspStore,
14116        worktree: &Entity<Worktree>,
14117        cx: &mut App,
14118    ) -> Arc<Self> {
14119        Self::new(
14120            local.languages.clone(),
14121            &local.environment,
14122            local.weak.clone(),
14123            worktree,
14124            local.http_client.clone(),
14125            local.fs.clone(),
14126            cx,
14127        )
14128    }
14129}
14130
14131#[async_trait]
14132impl LspAdapterDelegate for LocalLspAdapterDelegate {
14133    fn show_notification(&self, message: &str, cx: &mut App) {
14134        self.lsp_store
14135            .update(cx, |_, cx| {
14136                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14137            })
14138            .ok();
14139    }
14140
14141    fn http_client(&self) -> Arc<dyn HttpClient> {
14142        self.http_client.clone()
14143    }
14144
14145    fn worktree_id(&self) -> WorktreeId {
14146        self.worktree.id()
14147    }
14148
14149    fn worktree_root_path(&self) -> &Path {
14150        self.worktree.abs_path().as_ref()
14151    }
14152
14153    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14154        self.worktree.resolve_relative_path(path)
14155    }
14156
14157    async fn shell_env(&self) -> HashMap<String, String> {
14158        let task = self.load_shell_env_task.clone();
14159        task.await.unwrap_or_default()
14160    }
14161
14162    async fn npm_package_installed_version(
14163        &self,
14164        package_name: &str,
14165    ) -> Result<Option<(PathBuf, Version)>> {
14166        let local_package_directory = self.worktree_root_path();
14167        let node_modules_directory = local_package_directory.join("node_modules");
14168
14169        if let Some(version) =
14170            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14171        {
14172            return Ok(Some((node_modules_directory, version)));
14173        }
14174        let Some(npm) = self.which("npm".as_ref()).await else {
14175            log::warn!(
14176                "Failed to find npm executable for {:?}",
14177                local_package_directory
14178            );
14179            return Ok(None);
14180        };
14181
14182        let env = self.shell_env().await;
14183        let output = util::command::new_command(&npm)
14184            .args(["root", "-g"])
14185            .envs(env)
14186            .current_dir(local_package_directory)
14187            .output()
14188            .await?;
14189        let global_node_modules =
14190            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14191
14192        if let Some(version) =
14193            read_package_installed_version(global_node_modules.clone(), package_name).await?
14194        {
14195            return Ok(Some((global_node_modules, version)));
14196        }
14197        return Ok(None);
14198    }
14199
14200    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14201        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14202        if self.fs.is_file(&worktree_abs_path).await {
14203            worktree_abs_path.pop();
14204        }
14205
14206        let env = self.shell_env().await;
14207
14208        let shell_path = env.get("PATH").cloned();
14209
14210        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14211    }
14212
14213    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14214        let mut working_dir = self.worktree_root_path().to_path_buf();
14215        if self.fs.is_file(&working_dir).await {
14216            working_dir.pop();
14217        }
14218        let output = util::command::new_command(&command.path)
14219            .args(command.arguments)
14220            .envs(command.env.clone().unwrap_or_default())
14221            .current_dir(working_dir)
14222            .output()
14223            .await?;
14224
14225        anyhow::ensure!(
14226            output.status.success(),
14227            "{}, stdout: {:?}, stderr: {:?}",
14228            output.status,
14229            String::from_utf8_lossy(&output.stdout),
14230            String::from_utf8_lossy(&output.stderr)
14231        );
14232        Ok(())
14233    }
14234
14235    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14236        self.language_registry
14237            .update_lsp_binary_status(server_name, status);
14238    }
14239
14240    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14241        self.language_registry
14242            .all_lsp_adapters()
14243            .into_iter()
14244            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14245            .collect()
14246    }
14247
14248    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14249        let dir = self.language_registry.language_server_download_dir(name)?;
14250
14251        if !dir.exists() {
14252            smol::fs::create_dir_all(&dir)
14253                .await
14254                .context("failed to create container directory")
14255                .log_err()?;
14256        }
14257
14258        Some(dir)
14259    }
14260
14261    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14262        let entry = self
14263            .worktree
14264            .entry_for_path(path)
14265            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14266        let abs_path = self.worktree.absolutize(&entry.path);
14267        self.fs.load(&abs_path).await
14268    }
14269}
14270
14271async fn populate_labels_for_symbols(
14272    symbols: Vec<CoreSymbol>,
14273    language_registry: &Arc<LanguageRegistry>,
14274    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14275    output: &mut Vec<Symbol>,
14276) {
14277    #[allow(clippy::mutable_key_type)]
14278    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14279
14280    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14281    for symbol in symbols {
14282        let Some(file_name) = symbol.path.file_name() else {
14283            continue;
14284        };
14285        let language = language_registry
14286            .load_language_for_file_path(Path::new(file_name))
14287            .await
14288            .ok()
14289            .or_else(|| {
14290                unknown_paths.insert(file_name.into());
14291                None
14292            });
14293        symbols_by_language
14294            .entry(language)
14295            .or_default()
14296            .push(symbol);
14297    }
14298
14299    for unknown_path in unknown_paths {
14300        log::info!("no language found for symbol in file {unknown_path:?}");
14301    }
14302
14303    let mut label_params = Vec::new();
14304    for (language, mut symbols) in symbols_by_language {
14305        label_params.clear();
14306        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14307            name: mem::take(&mut symbol.name),
14308            kind: symbol.kind,
14309            container_name: symbol.container_name.take(),
14310        }));
14311
14312        let mut labels = Vec::new();
14313        if let Some(language) = language {
14314            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14315                language_registry
14316                    .lsp_adapters(&language.name())
14317                    .first()
14318                    .cloned()
14319            });
14320            if let Some(lsp_adapter) = lsp_adapter {
14321                labels = lsp_adapter
14322                    .labels_for_symbols(&label_params, &language)
14323                    .await
14324                    .log_err()
14325                    .unwrap_or_default();
14326            }
14327        }
14328
14329        for (
14330            (
14331                symbol,
14332                language::Symbol {
14333                    name,
14334                    container_name,
14335                    ..
14336                },
14337            ),
14338            label,
14339        ) in symbols
14340            .into_iter()
14341            .zip(label_params.drain(..))
14342            .zip(labels.into_iter().chain(iter::repeat(None)))
14343        {
14344            output.push(Symbol {
14345                language_server_name: symbol.language_server_name,
14346                source_worktree_id: symbol.source_worktree_id,
14347                source_language_server_id: symbol.source_language_server_id,
14348                path: symbol.path,
14349                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14350                name,
14351                kind: symbol.kind,
14352                range: symbol.range,
14353                container_name,
14354            });
14355        }
14356    }
14357}
14358
14359pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14360    text.lines()
14361        .map(|line| line.trim())
14362        .filter(|line| !line.is_empty())
14363        .join(separator)
14364}
14365
14366fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14367    match server.capabilities().text_document_sync.as_ref()? {
14368        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14369            // Server wants didSave but didn't specify includeText.
14370            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14371            // Server doesn't want didSave at all.
14372            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14373            // Server provided SaveOptions.
14374            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14375                Some(save_options.include_text.unwrap_or(false))
14376            }
14377        },
14378        // We do not have any save info. Kind affects didChange only.
14379        lsp::TextDocumentSyncCapability::Kind(_) => None,
14380    }
14381}
14382
14383/// Completion items are displayed in a `UniformList`.
14384/// Usually, those items are single-line strings, but in LSP responses,
14385/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14386/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14387/// 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,
14388/// breaking the completions menu presentation.
14389///
14390/// 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.
14391pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14392    let mut new_text = String::with_capacity(label.text.len());
14393    let mut offset_map = vec![0; label.text.len() + 1];
14394    let mut last_char_was_space = false;
14395    let mut new_idx = 0;
14396    let chars = label.text.char_indices().fuse();
14397    let mut newlines_removed = false;
14398
14399    for (idx, c) in chars {
14400        offset_map[idx] = new_idx;
14401
14402        match c {
14403            '\n' if last_char_was_space => {
14404                newlines_removed = true;
14405            }
14406            '\t' | ' ' if last_char_was_space => {}
14407            '\n' if !last_char_was_space => {
14408                new_text.push(' ');
14409                new_idx += 1;
14410                last_char_was_space = true;
14411                newlines_removed = true;
14412            }
14413            ' ' | '\t' => {
14414                new_text.push(' ');
14415                new_idx += 1;
14416                last_char_was_space = true;
14417            }
14418            _ => {
14419                new_text.push(c);
14420                new_idx += c.len_utf8();
14421                last_char_was_space = false;
14422            }
14423        }
14424    }
14425    offset_map[label.text.len()] = new_idx;
14426
14427    // Only modify the label if newlines were removed.
14428    if !newlines_removed {
14429        return;
14430    }
14431
14432    let last_index = new_idx;
14433    let mut run_ranges_errors = Vec::new();
14434    label.runs.retain_mut(|(range, _)| {
14435        match offset_map.get(range.start) {
14436            Some(&start) => range.start = start,
14437            None => {
14438                run_ranges_errors.push(range.clone());
14439                return false;
14440            }
14441        }
14442
14443        match offset_map.get(range.end) {
14444            Some(&end) => range.end = end,
14445            None => {
14446                run_ranges_errors.push(range.clone());
14447                range.end = last_index;
14448            }
14449        }
14450        true
14451    });
14452    if !run_ranges_errors.is_empty() {
14453        log::error!(
14454            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14455            label.text
14456        );
14457    }
14458
14459    let mut wrong_filter_range = None;
14460    if label.filter_range == (0..label.text.len()) {
14461        label.filter_range = 0..new_text.len();
14462    } else {
14463        let mut original_filter_range = Some(label.filter_range.clone());
14464        match offset_map.get(label.filter_range.start) {
14465            Some(&start) => label.filter_range.start = start,
14466            None => {
14467                wrong_filter_range = original_filter_range.take();
14468                label.filter_range.start = last_index;
14469            }
14470        }
14471
14472        match offset_map.get(label.filter_range.end) {
14473            Some(&end) => label.filter_range.end = end,
14474            None => {
14475                wrong_filter_range = original_filter_range.take();
14476                label.filter_range.end = last_index;
14477            }
14478        }
14479    }
14480    if let Some(wrong_filter_range) = wrong_filter_range {
14481        log::error!(
14482            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14483            label.text
14484        );
14485    }
14486
14487    label.text = new_text;
14488}