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    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate,
   76    LspInstaller, ManifestDelegate, ManifestName, ModelineSettings, OffsetUtf16, Patch, PointUtf16,
   77    TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152#[cfg(any(test, feature = "test-support"))]
  153pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  154pub use semantic_tokens::{
  155    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  156};
  157
  158pub use worktree::{
  159    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  160    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  161};
  162
  163const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  164pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  165const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  166const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  167static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  168
  169#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  170pub enum ProgressToken {
  171    Number(i32),
  172    String(SharedString),
  173}
  174
  175impl std::fmt::Display for ProgressToken {
  176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  177        match self {
  178            Self::Number(number) => write!(f, "{number}"),
  179            Self::String(string) => write!(f, "{string}"),
  180        }
  181    }
  182}
  183
  184impl ProgressToken {
  185    fn from_lsp(value: lsp::NumberOrString) -> Self {
  186        match value {
  187            lsp::NumberOrString::Number(number) => Self::Number(number),
  188            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  189        }
  190    }
  191
  192    fn to_lsp(&self) -> lsp::NumberOrString {
  193        match self {
  194            Self::Number(number) => lsp::NumberOrString::Number(*number),
  195            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  196        }
  197    }
  198
  199    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  200        Some(match value.value? {
  201            proto::progress_token::Value::Number(number) => Self::Number(number),
  202            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  203        })
  204    }
  205
  206    fn to_proto(&self) -> proto::ProgressToken {
  207        proto::ProgressToken {
  208            value: Some(match self {
  209                Self::Number(number) => proto::progress_token::Value::Number(*number),
  210                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  211            }),
  212        }
  213    }
  214}
  215
  216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  217pub enum FormatTrigger {
  218    Save,
  219    Manual,
  220}
  221
  222pub enum LspFormatTarget {
  223    Buffers,
  224    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  225}
  226
  227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  228pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  229
  230struct OpenLspBuffer(Entity<Buffer>);
  231
  232impl FormatTrigger {
  233    fn from_proto(value: i32) -> FormatTrigger {
  234        match value {
  235            0 => FormatTrigger::Save,
  236            1 => FormatTrigger::Manual,
  237            _ => FormatTrigger::Save,
  238        }
  239    }
  240}
  241
  242#[derive(Clone)]
  243struct UnifiedLanguageServer {
  244    id: LanguageServerId,
  245    project_roots: HashSet<Arc<RelPath>>,
  246}
  247
  248/// Settings that affect language server identity.
  249///
  250/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  251/// updated via `workspace/didChangeConfiguration` without restarting the server.
  252#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  253struct LanguageServerSeedSettings {
  254    binary: Option<BinarySettings>,
  255    initialization_options: Option<serde_json::Value>,
  256}
  257
  258#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  259struct LanguageServerSeed {
  260    worktree_id: WorktreeId,
  261    name: LanguageServerName,
  262    toolchain: Option<Toolchain>,
  263    settings: LanguageServerSeedSettings,
  264}
  265
  266#[derive(Debug)]
  267pub struct DocumentDiagnosticsUpdate<'a, D> {
  268    pub diagnostics: D,
  269    pub result_id: Option<SharedString>,
  270    pub registration_id: Option<SharedString>,
  271    pub server_id: LanguageServerId,
  272    pub disk_based_sources: Cow<'a, [String]>,
  273}
  274
  275pub struct DocumentDiagnostics {
  276    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  277    document_abs_path: PathBuf,
  278    version: Option<i32>,
  279}
  280
  281#[derive(Default, Debug)]
  282struct DynamicRegistrations {
  283    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  284    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  285}
  286
  287pub struct LocalLspStore {
  288    weak: WeakEntity<LspStore>,
  289    pub worktree_store: Entity<WorktreeStore>,
  290    toolchain_store: Entity<LocalToolchainStore>,
  291    http_client: Arc<dyn HttpClient>,
  292    environment: Entity<ProjectEnvironment>,
  293    fs: Arc<dyn Fs>,
  294    languages: Arc<LanguageRegistry>,
  295    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  296    yarn: Entity<YarnPathStore>,
  297    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  298    buffers_being_formatted: HashSet<BufferId>,
  299    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  300    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  301    watched_manifest_filenames: HashSet<ManifestName>,
  302    language_server_paths_watched_for_rename:
  303        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  304    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  305    supplementary_language_servers:
  306        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  307    prettier_store: Entity<PrettierStore>,
  308    next_diagnostic_group_id: usize,
  309    diagnostics: HashMap<
  310        WorktreeId,
  311        HashMap<
  312            Arc<RelPath>,
  313            Vec<(
  314                LanguageServerId,
  315                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  316            )>,
  317        >,
  318    >,
  319    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  320    _subscription: gpui::Subscription,
  321    lsp_tree: LanguageServerTree,
  322    registered_buffers: HashMap<BufferId, usize>,
  323    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  324    buffer_pull_diagnostics_result_ids: HashMap<
  325        LanguageServerId,
  326        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  327    >,
  328    workspace_pull_diagnostics_result_ids: HashMap<
  329        LanguageServerId,
  330        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  331    >,
  332    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  333
  334    buffers_to_refresh_hash_set: HashSet<BufferId>,
  335    buffers_to_refresh_queue: VecDeque<BufferId>,
  336    _background_diagnostics_worker: Shared<Task<()>>,
  337}
  338
  339impl LocalLspStore {
  340    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  341    pub fn running_language_server_for_id(
  342        &self,
  343        id: LanguageServerId,
  344    ) -> Option<&Arc<LanguageServer>> {
  345        let language_server_state = self.language_servers.get(&id)?;
  346
  347        match language_server_state {
  348            LanguageServerState::Running { server, .. } => Some(server),
  349            LanguageServerState::Starting { .. } => None,
  350        }
  351    }
  352
  353    fn get_or_insert_language_server(
  354        &mut self,
  355        worktree_handle: &Entity<Worktree>,
  356        delegate: Arc<LocalLspAdapterDelegate>,
  357        disposition: &Arc<LaunchDisposition>,
  358        language_name: &LanguageName,
  359        cx: &mut App,
  360    ) -> LanguageServerId {
  361        let key = LanguageServerSeed {
  362            worktree_id: worktree_handle.read(cx).id(),
  363            name: disposition.server_name.clone(),
  364            settings: LanguageServerSeedSettings {
  365                binary: disposition.settings.binary.clone(),
  366                initialization_options: disposition.settings.initialization_options.clone(),
  367            },
  368            toolchain: disposition.toolchain.clone(),
  369        };
  370        if let Some(state) = self.language_server_ids.get_mut(&key) {
  371            state.project_roots.insert(disposition.path.path.clone());
  372            state.id
  373        } else {
  374            let adapter = self
  375                .languages
  376                .lsp_adapters(language_name)
  377                .into_iter()
  378                .find(|adapter| adapter.name() == disposition.server_name)
  379                .expect("To find LSP adapter");
  380            let new_language_server_id = self.start_language_server(
  381                worktree_handle,
  382                delegate,
  383                adapter,
  384                disposition.settings.clone(),
  385                key.clone(),
  386                language_name.clone(),
  387                cx,
  388            );
  389            if let Some(state) = self.language_server_ids.get_mut(&key) {
  390                state.project_roots.insert(disposition.path.path.clone());
  391            } else {
  392                debug_assert!(
  393                    false,
  394                    "Expected `start_language_server` to ensure that `key` exists in a map"
  395                );
  396            }
  397            new_language_server_id
  398        }
  399    }
  400
  401    fn start_language_server(
  402        &mut self,
  403        worktree_handle: &Entity<Worktree>,
  404        delegate: Arc<LocalLspAdapterDelegate>,
  405        adapter: Arc<CachedLspAdapter>,
  406        settings: Arc<LspSettings>,
  407        key: LanguageServerSeed,
  408        language_name: LanguageName,
  409        cx: &mut App,
  410    ) -> LanguageServerId {
  411        let worktree = worktree_handle.read(cx);
  412
  413        let worktree_id = worktree.id();
  414        let worktree_abs_path = worktree.abs_path();
  415        let toolchain = key.toolchain.clone();
  416        let override_options = settings.initialization_options.clone();
  417
  418        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  419
  420        let server_id = self.languages.next_language_server_id();
  421        log::trace!(
  422            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  423            adapter.name.0
  424        );
  425
  426        let wait_until_worktree_trust =
  427            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  428                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  429                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  430                });
  431                if can_trust {
  432                    self.restricted_worktrees_tasks.remove(&worktree_id);
  433                    None
  434                } else {
  435                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  436                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  437                        hash_map::Entry::Vacant(v) => {
  438                            let (mut tx, rx) = watch::channel::<bool>();
  439                            let lsp_store = self.weak.clone();
  440                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  441                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  442                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  443                                        tx.blocking_send(true).ok();
  444                                        lsp_store
  445                                            .update(cx, |lsp_store, _| {
  446                                                if let Some(local_lsp_store) =
  447                                                    lsp_store.as_local_mut()
  448                                                {
  449                                                    local_lsp_store
  450                                                        .restricted_worktrees_tasks
  451                                                        .remove(&worktree_id);
  452                                                }
  453                                            })
  454                                            .ok();
  455                                    }
  456                                }
  457                            });
  458                            v.insert((subscription, rx.clone()));
  459                            Some(rx)
  460                        }
  461                    }
  462                }
  463            });
  464        let update_binary_status = wait_until_worktree_trust.is_none();
  465
  466        let binary = self.get_language_server_binary(
  467            worktree_abs_path.clone(),
  468            adapter.clone(),
  469            settings,
  470            toolchain.clone(),
  471            delegate.clone(),
  472            true,
  473            wait_until_worktree_trust,
  474            cx,
  475        );
  476        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  477
  478        let pending_server = cx.spawn({
  479            let adapter = adapter.clone();
  480            let server_name = adapter.name.clone();
  481            let stderr_capture = stderr_capture.clone();
  482            #[cfg(any(test, feature = "test-support"))]
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485            async move |cx| {
  486                let binary = binary.await?;
  487                #[cfg(any(test, feature = "test-support"))]
  488                if let Some(server) = lsp_store
  489                    .update(&mut cx.clone(), |this, cx| {
  490                        this.languages.create_fake_language_server(
  491                            server_id,
  492                            &server_name,
  493                            binary.clone(),
  494                            &mut cx.to_async(),
  495                        )
  496                    })
  497                    .ok()
  498                    .flatten()
  499                {
  500                    return Ok(server);
  501                }
  502
  503                let code_action_kinds = adapter.code_action_kinds();
  504                lsp::LanguageServer::new(
  505                    stderr_capture,
  506                    server_id,
  507                    server_name,
  508                    binary,
  509                    &worktree_abs_path,
  510                    code_action_kinds,
  511                    Some(pending_workspace_folders),
  512                    cx,
  513                )
  514            }
  515        });
  516
  517        let startup = {
  518            let server_name = adapter.name.0.clone();
  519            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  520            let key = key.clone();
  521            let adapter = adapter.clone();
  522            let lsp_store = self.weak.clone();
  523            let pending_workspace_folders = pending_workspace_folders.clone();
  524            let pull_diagnostics = ProjectSettings::get_global(cx)
  525                .diagnostics
  526                .lsp_pull_diagnostics
  527                .enabled;
  528            let settings_location = SettingsLocation {
  529                worktree_id,
  530                path: RelPath::empty(),
  531            };
  532            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  533                .language(Some(settings_location), Some(&language_name), cx)
  534                .semantic_tokens
  535                .use_tree_sitter();
  536            cx.spawn(async move |cx| {
  537                let result = async {
  538                    let language_server = pending_server.await?;
  539
  540                    let workspace_config = Self::workspace_configuration_for_adapter(
  541                        adapter.adapter.clone(),
  542                        &delegate,
  543                        toolchain,
  544                        None,
  545                        cx,
  546                    )
  547                    .await?;
  548
  549                    let mut initialization_options = Self::initialization_options_for_adapter(
  550                        adapter.adapter.clone(),
  551                        &delegate,
  552                        cx,
  553                    )
  554                    .await?;
  555
  556                    match (&mut initialization_options, override_options) {
  557                        (Some(initialization_options), Some(override_options)) => {
  558                            merge_json_value_into(override_options, initialization_options);
  559                        }
  560                        (None, override_options) => initialization_options = override_options,
  561                        _ => {}
  562                    }
  563
  564                    let initialization_params = cx.update(|cx| {
  565                        let mut params = language_server.default_initialize_params(
  566                            pull_diagnostics,
  567                            augments_syntax_tokens,
  568                            cx,
  569                        );
  570                        params.initialization_options = initialization_options;
  571                        adapter.adapter.prepare_initialize_params(params, cx)
  572                    })?;
  573
  574                    Self::setup_lsp_messages(
  575                        lsp_store.clone(),
  576                        &language_server,
  577                        delegate.clone(),
  578                        adapter.clone(),
  579                    );
  580
  581                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  582                        settings: workspace_config,
  583                    };
  584                    let language_server = cx
  585                        .update(|cx| {
  586                            let request_timeout = ProjectSettings::get_global(cx)
  587                                .global_lsp_settings
  588                                .get_request_timeout();
  589
  590                            language_server.initialize(
  591                                initialization_params,
  592                                Arc::new(did_change_configuration_params.clone()),
  593                                request_timeout,
  594                                cx,
  595                            )
  596                        })
  597                        .await
  598                        .inspect_err(|_| {
  599                            if let Some(lsp_store) = lsp_store.upgrade() {
  600                                lsp_store.update(cx, |lsp_store, cx| {
  601                                    lsp_store.cleanup_lsp_data(server_id);
  602                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  603                                });
  604                            }
  605                        })?;
  606
  607                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  608                        did_change_configuration_params,
  609                    )?;
  610
  611                    anyhow::Ok(language_server)
  612                }
  613                .await;
  614
  615                match result {
  616                    Ok(server) => {
  617                        lsp_store
  618                            .update(cx, |lsp_store, cx| {
  619                                lsp_store.insert_newly_running_language_server(
  620                                    adapter,
  621                                    server.clone(),
  622                                    server_id,
  623                                    key,
  624                                    pending_workspace_folders,
  625                                    cx,
  626                                );
  627                            })
  628                            .ok();
  629                        stderr_capture.lock().take();
  630                        Some(server)
  631                    }
  632
  633                    Err(err) => {
  634                        let log = stderr_capture.lock().take().unwrap_or_default();
  635                        delegate.update_status(
  636                            adapter.name(),
  637                            BinaryStatus::Failed {
  638                                error: if log.is_empty() {
  639                                    format!("{err:#}")
  640                                } else {
  641                                    format!("{err:#}\n-- stderr --\n{log}")
  642                                },
  643                            },
  644                        );
  645                        log::error!(
  646                            "Failed to start language server {server_name:?}: {}",
  647                            redact_command(&format!("{err:?}"))
  648                        );
  649                        if !log.is_empty() {
  650                            log::error!("server stderr: {}", redact_command(&log));
  651                        }
  652                        None
  653                    }
  654                }
  655            })
  656        };
  657        let state = LanguageServerState::Starting {
  658            startup,
  659            pending_workspace_folders,
  660        };
  661
  662        if update_binary_status {
  663            self.languages
  664                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  665        }
  666
  667        self.language_servers.insert(server_id, state);
  668        self.language_server_ids
  669            .entry(key)
  670            .or_insert(UnifiedLanguageServer {
  671                id: server_id,
  672                project_roots: Default::default(),
  673            });
  674        server_id
  675    }
  676
  677    fn get_language_server_binary(
  678        &self,
  679        worktree_abs_path: Arc<Path>,
  680        adapter: Arc<CachedLspAdapter>,
  681        settings: Arc<LspSettings>,
  682        toolchain: Option<Toolchain>,
  683        delegate: Arc<dyn LspAdapterDelegate>,
  684        allow_binary_download: bool,
  685        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  686        cx: &mut App,
  687    ) -> Task<Result<LanguageServerBinary>> {
  688        if let Some(settings) = &settings.binary
  689            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  690        {
  691            let settings = settings.clone();
  692            let languages = self.languages.clone();
  693            return cx.background_spawn(async move {
  694                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  695                    let already_trusted =  *wait_until_worktree_trust.borrow();
  696                    if !already_trusted {
  697                        log::info!(
  698                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  699                            adapter.name(),
  700                        );
  701                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  702                            if worktree_trusted {
  703                                break;
  704                            }
  705                        }
  706                        log::info!(
  707                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  708                            adapter.name(),
  709                        );
  710                    }
  711                    languages
  712                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  713                }
  714                let mut env = delegate.shell_env().await;
  715                env.extend(settings.env.unwrap_or_default());
  716
  717                Ok(LanguageServerBinary {
  718                    path: delegate.resolve_relative_path(path),
  719                    env: Some(env),
  720                    arguments: settings
  721                        .arguments
  722                        .unwrap_or_default()
  723                        .iter()
  724                        .map(Into::into)
  725                        .collect(),
  726                })
  727            });
  728        }
  729        let lsp_binary_options = LanguageServerBinaryOptions {
  730            allow_path_lookup: !settings
  731                .binary
  732                .as_ref()
  733                .and_then(|b| b.ignore_system_version)
  734                .unwrap_or_default(),
  735            allow_binary_download,
  736            pre_release: settings
  737                .fetch
  738                .as_ref()
  739                .and_then(|f| f.pre_release)
  740                .unwrap_or(false),
  741        };
  742
  743        cx.spawn(async move |cx| {
  744            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  745                let already_trusted =  *wait_until_worktree_trust.borrow();
  746                if !already_trusted {
  747                    log::info!(
  748                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  749                        adapter.name(),
  750                    );
  751                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  752                        if worktree_trusted {
  753                            break;
  754                        }
  755                    }
  756                    log::info!(
  757                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  758                            adapter.name(),
  759                    );
  760                }
  761            }
  762
  763            let (existing_binary, maybe_download_binary) = adapter
  764                .clone()
  765                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  766                .await
  767                .await;
  768
  769            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  770
  771            let mut binary = match (existing_binary, maybe_download_binary) {
  772                (binary, None) => binary?,
  773                (Err(_), Some(downloader)) => downloader.await?,
  774                (Ok(existing_binary), Some(downloader)) => {
  775                    let mut download_timeout = cx
  776                        .background_executor()
  777                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  778                        .fuse();
  779                    let mut downloader = downloader.fuse();
  780                    futures::select! {
  781                        _ = download_timeout => {
  782                            // Return existing binary and kick the existing work to the background.
  783                            cx.spawn(async move |_| downloader.await).detach();
  784                            Ok(existing_binary)
  785                        },
  786                        downloaded_or_existing_binary = downloader => {
  787                            // If download fails, this results in the existing binary.
  788                            downloaded_or_existing_binary
  789                        }
  790                    }?
  791                }
  792            };
  793            let mut shell_env = delegate.shell_env().await;
  794
  795            shell_env.extend(binary.env.unwrap_or_default());
  796
  797            if let Some(settings) = settings.binary.as_ref() {
  798                if let Some(arguments) = &settings.arguments {
  799                    binary.arguments = arguments.iter().map(Into::into).collect();
  800                }
  801                if let Some(env) = &settings.env {
  802                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  803                }
  804            }
  805
  806            binary.env = Some(shell_env);
  807            Ok(binary)
  808        })
  809    }
  810
  811    fn setup_lsp_messages(
  812        lsp_store: WeakEntity<LspStore>,
  813        language_server: &LanguageServer,
  814        delegate: Arc<dyn LspAdapterDelegate>,
  815        adapter: Arc<CachedLspAdapter>,
  816    ) {
  817        let name = language_server.name();
  818        let server_id = language_server.server_id();
  819        language_server
  820            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  821                let adapter = adapter.clone();
  822                let this = lsp_store.clone();
  823                move |mut params, cx| {
  824                    let adapter = adapter.clone();
  825                    if let Some(this) = this.upgrade() {
  826                        this.update(cx, |this, cx| {
  827                            adapter.process_diagnostics(&mut params, server_id);
  828
  829                            this.merge_lsp_diagnostics(
  830                                DiagnosticSourceKind::Pushed,
  831                                vec![DocumentDiagnosticsUpdate {
  832                                    server_id,
  833                                    diagnostics: params,
  834                                    result_id: None,
  835                                    disk_based_sources: Cow::Borrowed(
  836                                        &adapter.disk_based_diagnostic_sources,
  837                                    ),
  838                                    registration_id: None,
  839                                }],
  840                                |_, diagnostic, _cx| match diagnostic.source_kind {
  841                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  842                                        adapter.retain_old_diagnostic(diagnostic)
  843                                    }
  844                                    DiagnosticSourceKind::Pulled => true,
  845                                },
  846                                cx,
  847                            )
  848                            .log_err();
  849                        });
  850                    }
  851                }
  852            })
  853            .detach();
  854        language_server
  855            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  856                let adapter = adapter.adapter.clone();
  857                let delegate = delegate.clone();
  858                let this = lsp_store.clone();
  859                move |params, cx| {
  860                    let adapter = adapter.clone();
  861                    let delegate = delegate.clone();
  862                    let this = this.clone();
  863                    let mut cx = cx.clone();
  864                    async move {
  865                        let toolchain_for_id = this
  866                            .update(&mut cx, |this, _| {
  867                                this.as_local()?.language_server_ids.iter().find_map(
  868                                    |(seed, value)| {
  869                                        (value.id == server_id).then(|| seed.toolchain.clone())
  870                                    },
  871                                )
  872                            })?
  873                            .context("Expected the LSP store to be in a local mode")?;
  874
  875                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  876                        for item in &params.items {
  877                            let scope_uri = item.scope_uri.clone();
  878                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  879                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  880                            else {
  881                                // We've already queried workspace configuration of this URI.
  882                                continue;
  883                            };
  884                            let workspace_config = Self::workspace_configuration_for_adapter(
  885                                adapter.clone(),
  886                                &delegate,
  887                                toolchain_for_id.clone(),
  888                                scope_uri,
  889                                &mut cx,
  890                            )
  891                            .await?;
  892                            new_scope_uri.insert(workspace_config);
  893                        }
  894
  895                        Ok(params
  896                            .items
  897                            .into_iter()
  898                            .filter_map(|item| {
  899                                let workspace_config =
  900                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  901                                if let Some(section) = &item.section {
  902                                    Some(
  903                                        workspace_config
  904                                            .get(section)
  905                                            .cloned()
  906                                            .unwrap_or(serde_json::Value::Null),
  907                                    )
  908                                } else {
  909                                    Some(workspace_config.clone())
  910                                }
  911                            })
  912                            .collect())
  913                    }
  914                }
  915            })
  916            .detach();
  917
  918        language_server
  919            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  920                let this = lsp_store.clone();
  921                move |_, cx| {
  922                    let this = this.clone();
  923                    let cx = cx.clone();
  924                    async move {
  925                        let Some(server) =
  926                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  927                        else {
  928                            return Ok(None);
  929                        };
  930                        let root = server.workspace_folders();
  931                        Ok(Some(
  932                            root.into_iter()
  933                                .map(|uri| WorkspaceFolder {
  934                                    uri,
  935                                    name: Default::default(),
  936                                })
  937                                .collect(),
  938                        ))
  939                    }
  940                }
  941            })
  942            .detach();
  943        // Even though we don't have handling for these requests, respond to them to
  944        // avoid stalling any language server like `gopls` which waits for a response
  945        // to these requests when initializing.
  946        language_server
  947            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  948                let this = lsp_store.clone();
  949                move |params, cx| {
  950                    let this = this.clone();
  951                    let mut cx = cx.clone();
  952                    async move {
  953                        this.update(&mut cx, |this, _| {
  954                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  955                            {
  956                                status
  957                                    .progress_tokens
  958                                    .insert(ProgressToken::from_lsp(params.token));
  959                            }
  960                        })?;
  961
  962                        Ok(())
  963                    }
  964                }
  965            })
  966            .detach();
  967
  968        language_server
  969            .on_request::<lsp::request::RegisterCapability, _, _>({
  970                let lsp_store = lsp_store.clone();
  971                move |params, cx| {
  972                    let lsp_store = lsp_store.clone();
  973                    let mut cx = cx.clone();
  974                    async move {
  975                        lsp_store
  976                            .update(&mut cx, |lsp_store, cx| {
  977                                if lsp_store.as_local().is_some() {
  978                                    match lsp_store
  979                                        .register_server_capabilities(server_id, params, cx)
  980                                    {
  981                                        Ok(()) => {}
  982                                        Err(e) => {
  983                                            log::error!(
  984                                                "Failed to register server capabilities: {e:#}"
  985                                            );
  986                                        }
  987                                    };
  988                                }
  989                            })
  990                            .ok();
  991                        Ok(())
  992                    }
  993                }
  994            })
  995            .detach();
  996
  997        language_server
  998            .on_request::<lsp::request::UnregisterCapability, _, _>({
  999                let lsp_store = lsp_store.clone();
 1000                move |params, cx| {
 1001                    let lsp_store = lsp_store.clone();
 1002                    let mut cx = cx.clone();
 1003                    async move {
 1004                        lsp_store
 1005                            .update(&mut cx, |lsp_store, cx| {
 1006                                if lsp_store.as_local().is_some() {
 1007                                    match lsp_store
 1008                                        .unregister_server_capabilities(server_id, params, cx)
 1009                                    {
 1010                                        Ok(()) => {}
 1011                                        Err(e) => {
 1012                                            log::error!(
 1013                                                "Failed to unregister server capabilities: {e:#}"
 1014                                            );
 1015                                        }
 1016                                    }
 1017                                }
 1018                            })
 1019                            .ok();
 1020                        Ok(())
 1021                    }
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        language_server
 1027            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1028                let this = lsp_store.clone();
 1029                move |params, cx| {
 1030                    let mut cx = cx.clone();
 1031                    let this = this.clone();
 1032                    async move {
 1033                        LocalLspStore::on_lsp_workspace_edit(
 1034                            this.clone(),
 1035                            params,
 1036                            server_id,
 1037                            &mut cx,
 1038                        )
 1039                        .await
 1040                    }
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        language_server
 1046            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1047                let lsp_store = lsp_store.clone();
 1048                let request_id = Arc::new(AtomicUsize::new(0));
 1049                move |(), cx| {
 1050                    let lsp_store = lsp_store.clone();
 1051                    let request_id = request_id.clone();
 1052                    let mut cx = cx.clone();
 1053                    async move {
 1054                        lsp_store
 1055                            .update(&mut cx, |lsp_store, cx| {
 1056                                let request_id =
 1057                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1058                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1059                                    server_id,
 1060                                    request_id,
 1061                                });
 1062                                lsp_store
 1063                                    .downstream_client
 1064                                    .as_ref()
 1065                                    .map(|(client, project_id)| {
 1066                                        client.send(proto::RefreshInlayHints {
 1067                                            project_id: *project_id,
 1068                                            server_id: server_id.to_proto(),
 1069                                            request_id: request_id.map(|id| id as u64),
 1070                                        })
 1071                                    })
 1072                            })?
 1073                            .transpose()?;
 1074                        Ok(())
 1075                    }
 1076                }
 1077            })
 1078            .detach();
 1079
 1080        language_server
 1081            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1082                let this = lsp_store.clone();
 1083                move |(), cx| {
 1084                    let this = this.clone();
 1085                    let mut cx = cx.clone();
 1086                    async move {
 1087                        this.update(&mut cx, |this, cx| {
 1088                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1089                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1090                                client.send(proto::RefreshCodeLens {
 1091                                    project_id: *project_id,
 1092                                })
 1093                            })
 1094                        })?
 1095                        .transpose()?;
 1096                        Ok(())
 1097                    }
 1098                }
 1099            })
 1100            .detach();
 1101
 1102        language_server
 1103            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1104                let lsp_store = lsp_store.clone();
 1105                let request_id = Arc::new(AtomicUsize::new(0));
 1106                move |(), cx| {
 1107                    let lsp_store = lsp_store.clone();
 1108                    let request_id = request_id.clone();
 1109                    let mut cx = cx.clone();
 1110                    async move {
 1111                        lsp_store
 1112                            .update(&mut cx, |lsp_store, cx| {
 1113                                let request_id =
 1114                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1115                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1116                                    server_id,
 1117                                    request_id,
 1118                                });
 1119                                lsp_store
 1120                                    .downstream_client
 1121                                    .as_ref()
 1122                                    .map(|(client, project_id)| {
 1123                                        client.send(proto::RefreshSemanticTokens {
 1124                                            project_id: *project_id,
 1125                                            server_id: server_id.to_proto(),
 1126                                            request_id: request_id.map(|id| id as u64),
 1127                                        })
 1128                                    })
 1129                            })?
 1130                            .transpose()?;
 1131                        Ok(())
 1132                    }
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        language_server
 1138            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1139                let this = lsp_store.clone();
 1140                move |(), cx| {
 1141                    let this = this.clone();
 1142                    let mut cx = cx.clone();
 1143                    async move {
 1144                        this.update(&mut cx, |lsp_store, cx| {
 1145                            lsp_store.pull_workspace_diagnostics(server_id);
 1146                            lsp_store
 1147                                .downstream_client
 1148                                .as_ref()
 1149                                .map(|(client, project_id)| {
 1150                                    client.send(proto::PullWorkspaceDiagnostics {
 1151                                        project_id: *project_id,
 1152                                        server_id: server_id.to_proto(),
 1153                                    })
 1154                                })
 1155                                .transpose()?;
 1156                            anyhow::Ok(
 1157                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1158                            )
 1159                        })??
 1160                        .await;
 1161                        Ok(())
 1162                    }
 1163                }
 1164            })
 1165            .detach();
 1166
 1167        language_server
 1168            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1169                let this = lsp_store.clone();
 1170                let name = name.to_string();
 1171                let adapter = adapter.clone();
 1172                move |params, cx| {
 1173                    let this = this.clone();
 1174                    let name = name.to_string();
 1175                    let adapter = adapter.clone();
 1176                    let mut cx = cx.clone();
 1177                    async move {
 1178                        let actions = params.actions.unwrap_or_default();
 1179                        let message = params.message.clone();
 1180                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1181                        let level = match params.typ {
 1182                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1183                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1184                            _ => PromptLevel::Info,
 1185                        };
 1186                        let request = LanguageServerPromptRequest::new(
 1187                            level,
 1188                            params.message,
 1189                            actions,
 1190                            name.clone(),
 1191                            tx,
 1192                        );
 1193
 1194                        let did_update = this
 1195                            .update(&mut cx, |_, cx| {
 1196                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1197                            })
 1198                            .is_ok();
 1199                        if did_update {
 1200                            let response = rx.recv().await.ok();
 1201                            if let Some(ref selected_action) = response {
 1202                                let context = language::PromptResponseContext {
 1203                                    message,
 1204                                    selected_action: selected_action.clone(),
 1205                                };
 1206                                adapter.process_prompt_response(&context, &mut cx)
 1207                            }
 1208
 1209                            Ok(response)
 1210                        } else {
 1211                            Ok(None)
 1212                        }
 1213                    }
 1214                }
 1215            })
 1216            .detach();
 1217        language_server
 1218            .on_notification::<lsp::notification::ShowMessage, _>({
 1219                let this = lsp_store.clone();
 1220                let name = name.to_string();
 1221                move |params, cx| {
 1222                    let this = this.clone();
 1223                    let name = name.to_string();
 1224                    let mut cx = cx.clone();
 1225
 1226                    let (tx, _) = smol::channel::bounded(1);
 1227                    let level = match params.typ {
 1228                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1229                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1230                        _ => PromptLevel::Info,
 1231                    };
 1232                    let request =
 1233                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1234
 1235                    let _ = this.update(&mut cx, |_, cx| {
 1236                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1237                    });
 1238                }
 1239            })
 1240            .detach();
 1241
 1242        let disk_based_diagnostics_progress_token =
 1243            adapter.disk_based_diagnostics_progress_token.clone();
 1244
 1245        language_server
 1246            .on_notification::<lsp::notification::Progress, _>({
 1247                let this = lsp_store.clone();
 1248                move |params, cx| {
 1249                    if let Some(this) = this.upgrade() {
 1250                        this.update(cx, |this, cx| {
 1251                            this.on_lsp_progress(
 1252                                params,
 1253                                server_id,
 1254                                disk_based_diagnostics_progress_token.clone(),
 1255                                cx,
 1256                            );
 1257                        });
 1258                    }
 1259                }
 1260            })
 1261            .detach();
 1262
 1263        language_server
 1264            .on_notification::<lsp::notification::LogMessage, _>({
 1265                let this = lsp_store.clone();
 1266                move |params, cx| {
 1267                    if let Some(this) = this.upgrade() {
 1268                        this.update(cx, |_, cx| {
 1269                            cx.emit(LspStoreEvent::LanguageServerLog(
 1270                                server_id,
 1271                                LanguageServerLogType::Log(params.typ),
 1272                                params.message,
 1273                            ));
 1274                        });
 1275                    }
 1276                }
 1277            })
 1278            .detach();
 1279
 1280        language_server
 1281            .on_notification::<lsp::notification::LogTrace, _>({
 1282                let this = lsp_store.clone();
 1283                move |params, cx| {
 1284                    let mut cx = cx.clone();
 1285                    if let Some(this) = this.upgrade() {
 1286                        this.update(&mut cx, |_, cx| {
 1287                            cx.emit(LspStoreEvent::LanguageServerLog(
 1288                                server_id,
 1289                                LanguageServerLogType::Trace {
 1290                                    verbose_info: params.verbose,
 1291                                },
 1292                                params.message,
 1293                            ));
 1294                        });
 1295                    }
 1296                }
 1297            })
 1298            .detach();
 1299
 1300        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1301        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1303        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1304    }
 1305
 1306    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1307        let shutdown_futures = self
 1308            .language_servers
 1309            .drain()
 1310            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1311            .collect::<Vec<_>>();
 1312
 1313        async move {
 1314            join_all(shutdown_futures).await;
 1315        }
 1316    }
 1317
 1318    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1319        match server_state {
 1320            LanguageServerState::Running { server, .. } => {
 1321                if let Some(shutdown) = server.shutdown() {
 1322                    shutdown.await;
 1323                }
 1324            }
 1325            LanguageServerState::Starting { startup, .. } => {
 1326                if let Some(server) = startup.await
 1327                    && let Some(shutdown) = server.shutdown()
 1328                {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332        }
 1333        Ok(())
 1334    }
 1335
 1336    fn language_servers_for_worktree(
 1337        &self,
 1338        worktree_id: WorktreeId,
 1339    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1340        self.language_server_ids
 1341            .iter()
 1342            .filter_map(move |(seed, state)| {
 1343                if seed.worktree_id != worktree_id {
 1344                    return None;
 1345                }
 1346
 1347                if let Some(LanguageServerState::Running { server, .. }) =
 1348                    self.language_servers.get(&state.id)
 1349                {
 1350                    Some(server)
 1351                } else {
 1352                    None
 1353                }
 1354            })
 1355    }
 1356
 1357    fn language_server_ids_for_project_path(
 1358        &self,
 1359        project_path: ProjectPath,
 1360        language: &Language,
 1361        cx: &mut App,
 1362    ) -> Vec<LanguageServerId> {
 1363        let Some(worktree) = self
 1364            .worktree_store
 1365            .read(cx)
 1366            .worktree_for_id(project_path.worktree_id, cx)
 1367        else {
 1368            return Vec::new();
 1369        };
 1370        let delegate: Arc<dyn ManifestDelegate> =
 1371            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1372
 1373        self.lsp_tree
 1374            .get(
 1375                project_path,
 1376                language.name(),
 1377                language.manifest(),
 1378                &delegate,
 1379                cx,
 1380            )
 1381            .collect::<Vec<_>>()
 1382    }
 1383
 1384    fn language_server_ids_for_buffer(
 1385        &self,
 1386        buffer: &Buffer,
 1387        cx: &mut App,
 1388    ) -> Vec<LanguageServerId> {
 1389        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1390            let worktree_id = file.worktree_id(cx);
 1391
 1392            let path: Arc<RelPath> = file
 1393                .path()
 1394                .parent()
 1395                .map(Arc::from)
 1396                .unwrap_or_else(|| file.path().clone());
 1397            let worktree_path = ProjectPath { worktree_id, path };
 1398            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1399        } else {
 1400            Vec::new()
 1401        }
 1402    }
 1403
 1404    fn language_servers_for_buffer<'a>(
 1405        &'a self,
 1406        buffer: &'a Buffer,
 1407        cx: &'a mut App,
 1408    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1409        self.language_server_ids_for_buffer(buffer, cx)
 1410            .into_iter()
 1411            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1412                LanguageServerState::Running {
 1413                    adapter, server, ..
 1414                } => Some((adapter, server)),
 1415                _ => None,
 1416            })
 1417    }
 1418
 1419    async fn execute_code_action_kind_locally(
 1420        lsp_store: WeakEntity<LspStore>,
 1421        mut buffers: Vec<Entity<Buffer>>,
 1422        kind: CodeActionKind,
 1423        push_to_history: bool,
 1424        cx: &mut AsyncApp,
 1425    ) -> anyhow::Result<ProjectTransaction> {
 1426        // Do not allow multiple concurrent code actions requests for the
 1427        // same buffer.
 1428        lsp_store.update(cx, |this, cx| {
 1429            let this = this.as_local_mut().unwrap();
 1430            buffers.retain(|buffer| {
 1431                this.buffers_being_formatted
 1432                    .insert(buffer.read(cx).remote_id())
 1433            });
 1434        })?;
 1435        let _cleanup = defer({
 1436            let this = lsp_store.clone();
 1437            let mut cx = cx.clone();
 1438            let buffers = &buffers;
 1439            move || {
 1440                this.update(&mut cx, |this, cx| {
 1441                    let this = this.as_local_mut().unwrap();
 1442                    for buffer in buffers {
 1443                        this.buffers_being_formatted
 1444                            .remove(&buffer.read(cx).remote_id());
 1445                    }
 1446                })
 1447                .ok();
 1448            }
 1449        });
 1450        let mut project_transaction = ProjectTransaction::default();
 1451
 1452        for buffer in &buffers {
 1453            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1454                buffer.update(cx, |buffer, cx| {
 1455                    lsp_store
 1456                        .as_local()
 1457                        .unwrap()
 1458                        .language_servers_for_buffer(buffer, cx)
 1459                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1460                        .collect::<Vec<_>>()
 1461                })
 1462            })?;
 1463            for (_, language_server) in adapters_and_servers.iter() {
 1464                let actions = Self::get_server_code_actions_from_action_kinds(
 1465                    &lsp_store,
 1466                    language_server.server_id(),
 1467                    vec![kind.clone()],
 1468                    buffer,
 1469                    cx,
 1470                )
 1471                .await?;
 1472                Self::execute_code_actions_on_server(
 1473                    &lsp_store,
 1474                    language_server,
 1475                    actions,
 1476                    push_to_history,
 1477                    &mut project_transaction,
 1478                    cx,
 1479                )
 1480                .await?;
 1481            }
 1482        }
 1483        Ok(project_transaction)
 1484    }
 1485
 1486    async fn format_locally(
 1487        lsp_store: WeakEntity<LspStore>,
 1488        mut buffers: Vec<FormattableBuffer>,
 1489        push_to_history: bool,
 1490        trigger: FormatTrigger,
 1491        logger: zlog::Logger,
 1492        cx: &mut AsyncApp,
 1493    ) -> anyhow::Result<ProjectTransaction> {
 1494        // Do not allow multiple concurrent formatting requests for the
 1495        // same buffer.
 1496        lsp_store.update(cx, |this, cx| {
 1497            let this = this.as_local_mut().unwrap();
 1498            buffers.retain(|buffer| {
 1499                this.buffers_being_formatted
 1500                    .insert(buffer.handle.read(cx).remote_id())
 1501            });
 1502        })?;
 1503
 1504        let _cleanup = defer({
 1505            let this = lsp_store.clone();
 1506            let mut cx = cx.clone();
 1507            let buffers = &buffers;
 1508            move || {
 1509                this.update(&mut cx, |this, cx| {
 1510                    let this = this.as_local_mut().unwrap();
 1511                    for buffer in buffers {
 1512                        this.buffers_being_formatted
 1513                            .remove(&buffer.handle.read(cx).remote_id());
 1514                    }
 1515                })
 1516                .ok();
 1517            }
 1518        });
 1519
 1520        let mut project_transaction = ProjectTransaction::default();
 1521
 1522        for buffer in &buffers {
 1523            zlog::debug!(
 1524                logger =>
 1525                "formatting buffer '{:?}'",
 1526                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1527            );
 1528            // Create an empty transaction to hold all of the formatting edits.
 1529            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1530                // ensure no transactions created while formatting are
 1531                // grouped with the previous transaction in the history
 1532                // based on the transaction group interval
 1533                buffer.finalize_last_transaction();
 1534                buffer
 1535                    .start_transaction()
 1536                    .context("transaction already open")?;
 1537                buffer.end_transaction(cx);
 1538                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1539                buffer.finalize_last_transaction();
 1540                anyhow::Ok(transaction_id)
 1541            })?;
 1542
 1543            let result = Self::format_buffer_locally(
 1544                lsp_store.clone(),
 1545                buffer,
 1546                formatting_transaction_id,
 1547                trigger,
 1548                logger,
 1549                cx,
 1550            )
 1551            .await;
 1552
 1553            buffer.handle.update(cx, |buffer, cx| {
 1554                let Some(formatting_transaction) =
 1555                    buffer.get_transaction(formatting_transaction_id).cloned()
 1556                else {
 1557                    zlog::warn!(logger => "no formatting transaction");
 1558                    return;
 1559                };
 1560                if formatting_transaction.edit_ids.is_empty() {
 1561                    zlog::debug!(logger => "no changes made while formatting");
 1562                    buffer.forget_transaction(formatting_transaction_id);
 1563                    return;
 1564                }
 1565                if !push_to_history {
 1566                    zlog::trace!(logger => "forgetting format transaction");
 1567                    buffer.forget_transaction(formatting_transaction.id);
 1568                }
 1569                project_transaction
 1570                    .0
 1571                    .insert(cx.entity(), formatting_transaction);
 1572            });
 1573
 1574            result?;
 1575        }
 1576
 1577        Ok(project_transaction)
 1578    }
 1579
 1580    async fn format_buffer_locally(
 1581        lsp_store: WeakEntity<LspStore>,
 1582        buffer: &FormattableBuffer,
 1583        formatting_transaction_id: clock::Lamport,
 1584        trigger: FormatTrigger,
 1585        logger: zlog::Logger,
 1586        cx: &mut AsyncApp,
 1587    ) -> Result<()> {
 1588        let (adapters_and_servers, settings, request_timeout) =
 1589            lsp_store.update(cx, |lsp_store, cx| {
 1590                buffer.handle.update(cx, |buffer, cx| {
 1591                    let adapters_and_servers = lsp_store
 1592                        .as_local()
 1593                        .unwrap()
 1594                        .language_servers_for_buffer(buffer, cx)
 1595                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1596                        .collect::<Vec<_>>();
 1597                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1598                    let request_timeout = ProjectSettings::get_global(cx)
 1599                        .global_lsp_settings
 1600                        .get_request_timeout();
 1601                    (adapters_and_servers, settings, request_timeout)
 1602                })
 1603            })?;
 1604
 1605        // handle whitespace formatting
 1606        if settings.remove_trailing_whitespace_on_save {
 1607            zlog::trace!(logger => "removing trailing whitespace");
 1608            let diff = buffer
 1609                .handle
 1610                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1611                .await;
 1612            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1613                buffer.apply_diff(diff, cx);
 1614            })?;
 1615        }
 1616
 1617        if settings.ensure_final_newline_on_save {
 1618            zlog::trace!(logger => "ensuring final newline");
 1619            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1620                buffer.ensure_final_newline(cx);
 1621            })?;
 1622        }
 1623
 1624        // Formatter for `code_actions_on_format` that runs before
 1625        // the rest of the formatters
 1626        let mut code_actions_on_format_formatters = None;
 1627        let should_run_code_actions_on_format = !matches!(
 1628            (trigger, &settings.format_on_save),
 1629            (FormatTrigger::Save, &FormatOnSave::Off)
 1630        );
 1631        if should_run_code_actions_on_format {
 1632            let have_code_actions_to_run_on_format = settings
 1633                .code_actions_on_format
 1634                .values()
 1635                .any(|enabled| *enabled);
 1636            if have_code_actions_to_run_on_format {
 1637                zlog::trace!(logger => "going to run code actions on format");
 1638                code_actions_on_format_formatters = Some(
 1639                    settings
 1640                        .code_actions_on_format
 1641                        .iter()
 1642                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1643                        .cloned()
 1644                        .map(Formatter::CodeAction)
 1645                        .collect::<Vec<_>>(),
 1646                );
 1647            }
 1648        }
 1649
 1650        let formatters = match (trigger, &settings.format_on_save) {
 1651            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1652            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1653                settings.formatter.as_ref()
 1654            }
 1655        };
 1656
 1657        let formatters = code_actions_on_format_formatters
 1658            .iter()
 1659            .flatten()
 1660            .chain(formatters);
 1661
 1662        for formatter in formatters {
 1663            let formatter = if formatter == &Formatter::Auto {
 1664                if settings.prettier.allowed {
 1665                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1666                    &Formatter::Prettier
 1667                } else {
 1668                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1669                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1670                }
 1671            } else {
 1672                formatter
 1673            };
 1674            if let Err(err) = Self::apply_formatter(
 1675                formatter,
 1676                &lsp_store,
 1677                buffer,
 1678                formatting_transaction_id,
 1679                &adapters_and_servers,
 1680                &settings,
 1681                request_timeout,
 1682                logger,
 1683                cx,
 1684            )
 1685            .await
 1686            {
 1687                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1688            }
 1689        }
 1690
 1691        Ok(())
 1692    }
 1693
 1694    async fn apply_formatter(
 1695        formatter: &Formatter,
 1696        lsp_store: &WeakEntity<LspStore>,
 1697        buffer: &FormattableBuffer,
 1698        formatting_transaction_id: clock::Lamport,
 1699        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1700        settings: &LanguageSettings,
 1701        request_timeout: Duration,
 1702        logger: zlog::Logger,
 1703        cx: &mut AsyncApp,
 1704    ) -> anyhow::Result<()> {
 1705        match formatter {
 1706            Formatter::None => {
 1707                zlog::trace!(logger => "skipping formatter 'none'");
 1708                return Ok(());
 1709            }
 1710            Formatter::Auto => {
 1711                debug_panic!("Auto resolved above");
 1712                return Ok(());
 1713            }
 1714            Formatter::Prettier => {
 1715                let logger = zlog::scoped!(logger => "prettier");
 1716                zlog::trace!(logger => "formatting");
 1717                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1718
 1719                // When selection ranges are provided (via FormatSelections), we pass the
 1720                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1721                // After diffing, we filter the resulting edits to only keep those that
 1722                // overlap with the original byte-level selection ranges.
 1723                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1724                    Some(ranges) if !ranges.is_empty() => {
 1725                        let (utf16_range, byte_ranges) =
 1726                            buffer.handle.read_with(cx, |buffer, _cx| {
 1727                                let snapshot = buffer.snapshot();
 1728                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1729                                let mut max_end_utf16 = OffsetUtf16(0);
 1730                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1731                                for range in ranges {
 1732                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1733                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1734                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1735                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1736
 1737                                    let start_byte = range.start.to_offset(&snapshot);
 1738                                    let end_byte = range.end.to_offset(&snapshot);
 1739                                    byte_ranges.push(start_byte..end_byte);
 1740                                }
 1741                                (min_start_utf16..max_end_utf16, byte_ranges)
 1742                            });
 1743                        (Some(utf16_range), Some(byte_ranges))
 1744                    }
 1745                    _ => (None, None),
 1746                };
 1747
 1748                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1749                    lsp_store.prettier_store().unwrap().downgrade()
 1750                })?;
 1751                let diff = prettier_store::format_with_prettier(
 1752                    &prettier,
 1753                    &buffer.handle,
 1754                    range_utf16,
 1755                    cx,
 1756                )
 1757                .await
 1758                .transpose()?;
 1759                let Some(mut diff) = diff else {
 1760                    zlog::trace!(logger => "No changes");
 1761                    return Ok(());
 1762                };
 1763
 1764                if let Some(byte_ranges) = byte_ranges {
 1765                    diff.edits.retain(|(edit_range, _)| {
 1766                        byte_ranges.iter().any(|selection_range| {
 1767                            edit_range.start < selection_range.end
 1768                                && edit_range.end > selection_range.start
 1769                        })
 1770                    });
 1771                    if diff.edits.is_empty() {
 1772                        zlog::trace!(logger => "No changes within selection");
 1773                        return Ok(());
 1774                    }
 1775                }
 1776
 1777                extend_formatting_transaction(
 1778                    buffer,
 1779                    formatting_transaction_id,
 1780                    cx,
 1781                    |buffer, cx| {
 1782                        buffer.apply_diff(diff, cx);
 1783                    },
 1784                )?;
 1785            }
 1786            Formatter::External { command, arguments } => {
 1787                let logger = zlog::scoped!(logger => "command");
 1788
 1789                if buffer.ranges.is_some() {
 1790                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1791                    return Ok(());
 1792                }
 1793
 1794                zlog::trace!(logger => "formatting");
 1795                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1796
 1797                let diff =
 1798                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1799                        .await
 1800                        .with_context(|| {
 1801                            format!("Failed to format buffer via external command: {}", command)
 1802                        })?;
 1803                let Some(diff) = diff else {
 1804                    zlog::trace!(logger => "No changes");
 1805                    return Ok(());
 1806                };
 1807
 1808                extend_formatting_transaction(
 1809                    buffer,
 1810                    formatting_transaction_id,
 1811                    cx,
 1812                    |buffer, cx| {
 1813                        buffer.apply_diff(diff, cx);
 1814                    },
 1815                )?;
 1816            }
 1817            Formatter::LanguageServer(specifier) => {
 1818                let logger = zlog::scoped!(logger => "language-server");
 1819                zlog::trace!(logger => "formatting");
 1820                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1821
 1822                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1823                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1824                    return Ok(());
 1825                };
 1826
 1827                let language_server = match specifier {
 1828                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1829                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1830                            if adapter.name.0.as_ref() == name {
 1831                                Some(server.clone())
 1832                            } else {
 1833                                None
 1834                            }
 1835                        })
 1836                    }
 1837                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1838                        .iter()
 1839                        .find(|(_, server)| Self::server_supports_formatting(server))
 1840                        .map(|(_, server)| server.clone()),
 1841                };
 1842
 1843                let Some(language_server) = language_server else {
 1844                    log::debug!(
 1845                        "No language server found to format buffer '{:?}'. Skipping",
 1846                        buffer_path_abs.as_path().to_string_lossy()
 1847                    );
 1848                    return Ok(());
 1849                };
 1850
 1851                zlog::trace!(
 1852                    logger =>
 1853                    "Formatting buffer '{:?}' using language server '{:?}'",
 1854                    buffer_path_abs.as_path().to_string_lossy(),
 1855                    language_server.name()
 1856                );
 1857
 1858                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1859                    zlog::trace!(logger => "formatting ranges");
 1860                    Self::format_ranges_via_lsp(
 1861                        &lsp_store,
 1862                        &buffer.handle,
 1863                        ranges,
 1864                        buffer_path_abs,
 1865                        &language_server,
 1866                        &settings,
 1867                        cx,
 1868                    )
 1869                    .await
 1870                    .context("Failed to format ranges via language server")?
 1871                } else {
 1872                    zlog::trace!(logger => "formatting full");
 1873                    Self::format_via_lsp(
 1874                        &lsp_store,
 1875                        &buffer.handle,
 1876                        buffer_path_abs,
 1877                        &language_server,
 1878                        &settings,
 1879                        cx,
 1880                    )
 1881                    .await
 1882                    .context("failed to format via language server")?
 1883                };
 1884
 1885                if edits.is_empty() {
 1886                    zlog::trace!(logger => "No changes");
 1887                    return Ok(());
 1888                }
 1889                extend_formatting_transaction(
 1890                    buffer,
 1891                    formatting_transaction_id,
 1892                    cx,
 1893                    |buffer, cx| {
 1894                        buffer.edit(edits, None, cx);
 1895                    },
 1896                )?;
 1897            }
 1898            Formatter::CodeAction(code_action_name) => {
 1899                let logger = zlog::scoped!(logger => "code-actions");
 1900                zlog::trace!(logger => "formatting");
 1901                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1902
 1903                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1904                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1905                    return Ok(());
 1906                };
 1907
 1908                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1909                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1910
 1911                let mut actions_and_servers = Vec::new();
 1912
 1913                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1914                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1915                        &lsp_store,
 1916                        language_server.server_id(),
 1917                        vec![code_action_kind.clone()],
 1918                        &buffer.handle,
 1919                        cx,
 1920                    )
 1921                    .await
 1922                    .with_context(|| {
 1923                        format!(
 1924                            "Failed to resolve code action {:?} with language server {}",
 1925                            code_action_kind,
 1926                            language_server.name()
 1927                        )
 1928                    });
 1929                    let Ok(actions) = actions_result else {
 1930                        // note: it may be better to set result to the error and break formatters here
 1931                        // but for now we try to execute the actions that we can resolve and skip the rest
 1932                        zlog::error!(
 1933                            logger =>
 1934                            "Failed to resolve code action {:?} with language server {}",
 1935                            code_action_kind,
 1936                            language_server.name()
 1937                        );
 1938                        continue;
 1939                    };
 1940                    for action in actions {
 1941                        actions_and_servers.push((action, index));
 1942                    }
 1943                }
 1944
 1945                if actions_and_servers.is_empty() {
 1946                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1947                    return Ok(());
 1948                }
 1949
 1950                'actions: for (mut action, server_index) in actions_and_servers {
 1951                    let server = &adapters_and_servers[server_index].1;
 1952
 1953                    let describe_code_action = |action: &CodeAction| {
 1954                        format!(
 1955                            "code action '{}' with title \"{}\" on server {}",
 1956                            action
 1957                                .lsp_action
 1958                                .action_kind()
 1959                                .unwrap_or("unknown".into())
 1960                                .as_str(),
 1961                            action.lsp_action.title(),
 1962                            server.name(),
 1963                        )
 1964                    };
 1965
 1966                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1967
 1968                    if let Err(err) =
 1969                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1970                    {
 1971                        zlog::error!(
 1972                            logger =>
 1973                            "Failed to resolve {}. Error: {}",
 1974                            describe_code_action(&action),
 1975                            err
 1976                        );
 1977                        continue;
 1978                    }
 1979
 1980                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1981                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1982                        // but filters out and logs warnings for code actions that require unreasonably
 1983                        // difficult handling on our part, such as:
 1984                        // - applying edits that call commands
 1985                        //   which can result in arbitrary workspace edits being sent from the server that
 1986                        //   have no way of being tied back to the command that initiated them (i.e. we
 1987                        //   can't know which edits are part of the format request, or if the server is done sending
 1988                        //   actions in response to the command)
 1989                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1990                        //   as we then would need to handle such changes correctly in the local history as well
 1991                        //   as the remote history through the ProjectTransaction
 1992                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1993                        // Supporting these actions is not impossible, but not supported as of yet.
 1994                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1995                            zlog::trace!(
 1996                                logger =>
 1997                                "No changes for code action. Skipping {}",
 1998                                describe_code_action(&action),
 1999                            );
 2000                            continue;
 2001                        }
 2002
 2003                        let mut operations = Vec::new();
 2004                        if let Some(document_changes) = edit.document_changes {
 2005                            match document_changes {
 2006                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2007                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2008                                ),
 2009                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2010                            }
 2011                        } else if let Some(changes) = edit.changes {
 2012                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2013                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2014                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2015                                        uri,
 2016                                        version: None,
 2017                                    },
 2018                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2019                                })
 2020                            }));
 2021                        }
 2022
 2023                        let mut edits = Vec::with_capacity(operations.len());
 2024
 2025                        if operations.is_empty() {
 2026                            zlog::trace!(
 2027                                logger =>
 2028                                "No changes for code action. Skipping {}",
 2029                                describe_code_action(&action),
 2030                            );
 2031                            continue;
 2032                        }
 2033                        for operation in operations {
 2034                            let op = match operation {
 2035                                lsp::DocumentChangeOperation::Edit(op) => op,
 2036                                lsp::DocumentChangeOperation::Op(_) => {
 2037                                    zlog::warn!(
 2038                                        logger =>
 2039                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2040                                        describe_code_action(&action),
 2041                                    );
 2042                                    continue 'actions;
 2043                                }
 2044                            };
 2045                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2046                                zlog::warn!(
 2047                                    logger =>
 2048                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2049                                    &op.text_document.uri,
 2050                                    describe_code_action(&action),
 2051                                );
 2052                                continue 'actions;
 2053                            };
 2054                            if &file_path != buffer_path_abs {
 2055                                zlog::warn!(
 2056                                    logger =>
 2057                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2058                                    file_path,
 2059                                    buffer_path_abs,
 2060                                    describe_code_action(&action),
 2061                                );
 2062                                continue 'actions;
 2063                            }
 2064
 2065                            let mut lsp_edits = Vec::new();
 2066                            for edit in op.edits {
 2067                                match edit {
 2068                                    Edit::Plain(edit) => {
 2069                                        if !lsp_edits.contains(&edit) {
 2070                                            lsp_edits.push(edit);
 2071                                        }
 2072                                    }
 2073                                    Edit::Annotated(edit) => {
 2074                                        if !lsp_edits.contains(&edit.text_edit) {
 2075                                            lsp_edits.push(edit.text_edit);
 2076                                        }
 2077                                    }
 2078                                    Edit::Snippet(_) => {
 2079                                        zlog::warn!(
 2080                                            logger =>
 2081                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2082                                            describe_code_action(&action),
 2083                                        );
 2084                                        continue 'actions;
 2085                                    }
 2086                                }
 2087                            }
 2088                            let edits_result = lsp_store
 2089                                .update(cx, |lsp_store, cx| {
 2090                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2091                                        &buffer.handle,
 2092                                        lsp_edits,
 2093                                        server.server_id(),
 2094                                        op.text_document.version,
 2095                                        cx,
 2096                                    )
 2097                                })?
 2098                                .await;
 2099                            let Ok(resolved_edits) = edits_result else {
 2100                                zlog::warn!(
 2101                                    logger =>
 2102                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2103                                    buffer_path_abs.as_path(),
 2104                                    describe_code_action(&action),
 2105                                );
 2106                                continue 'actions;
 2107                            };
 2108                            edits.extend(resolved_edits);
 2109                        }
 2110
 2111                        if edits.is_empty() {
 2112                            zlog::warn!(logger => "No edits resolved from LSP");
 2113                            continue;
 2114                        }
 2115
 2116                        extend_formatting_transaction(
 2117                            buffer,
 2118                            formatting_transaction_id,
 2119                            cx,
 2120                            |buffer, cx| {
 2121                                zlog::info!(
 2122                                    "Applying edits {edits:?}. Content: {:?}",
 2123                                    buffer.text()
 2124                                );
 2125                                buffer.edit(edits, None, cx);
 2126                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2127                            },
 2128                        )?;
 2129                    }
 2130
 2131                    let Some(command) = action.lsp_action.command() else {
 2132                        continue;
 2133                    };
 2134
 2135                    zlog::warn!(
 2136                        logger =>
 2137                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2138                        &command.command,
 2139                    );
 2140
 2141                    let server_capabilities = server.capabilities();
 2142                    let available_commands = server_capabilities
 2143                        .execute_command_provider
 2144                        .as_ref()
 2145                        .map(|options| options.commands.as_slice())
 2146                        .unwrap_or_default();
 2147                    if !available_commands.contains(&command.command) {
 2148                        zlog::warn!(
 2149                            logger =>
 2150                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2151                            command.command,
 2152                            server.name(),
 2153                        );
 2154                        continue;
 2155                    }
 2156
 2157                    extend_formatting_transaction(
 2158                        buffer,
 2159                        formatting_transaction_id,
 2160                        cx,
 2161                        |_, _| {},
 2162                    )?;
 2163                    zlog::info!(logger => "Executing command {}", &command.command);
 2164
 2165                    lsp_store.update(cx, |this, _| {
 2166                        this.as_local_mut()
 2167                            .unwrap()
 2168                            .last_workspace_edits_by_language_server
 2169                            .remove(&server.server_id());
 2170                    })?;
 2171
 2172                    let execute_command_result = server
 2173                        .request::<lsp::request::ExecuteCommand>(
 2174                            lsp::ExecuteCommandParams {
 2175                                command: command.command.clone(),
 2176                                arguments: command.arguments.clone().unwrap_or_default(),
 2177                                ..Default::default()
 2178                            },
 2179                            request_timeout,
 2180                        )
 2181                        .await
 2182                        .into_response();
 2183
 2184                    if execute_command_result.is_err() {
 2185                        zlog::error!(
 2186                            logger =>
 2187                            "Failed to execute command '{}' as part of {}",
 2188                            &command.command,
 2189                            describe_code_action(&action),
 2190                        );
 2191                        continue 'actions;
 2192                    }
 2193
 2194                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2195                        this.as_local_mut()
 2196                            .unwrap()
 2197                            .last_workspace_edits_by_language_server
 2198                            .remove(&server.server_id())
 2199                            .unwrap_or_default()
 2200                    })?;
 2201
 2202                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2203                    {
 2204                        zlog::trace!(
 2205                            logger =>
 2206                            "Successfully captured {} edits that resulted from command {}",
 2207                            transaction.edit_ids.len(),
 2208                            &command.command,
 2209                        );
 2210                        let transaction_id_project_transaction = transaction.id;
 2211                        buffer.handle.update(cx, |buffer, _| {
 2212                            // it may have been removed from history if push_to_history was
 2213                            // false in deserialize_workspace_edit. If so push it so we
 2214                            // can merge it with the format transaction
 2215                            // and pop the combined transaction off the history stack
 2216                            // later if push_to_history is false
 2217                            if buffer.get_transaction(transaction.id).is_none() {
 2218                                buffer.push_transaction(transaction, Instant::now());
 2219                            }
 2220                            buffer.merge_transactions(
 2221                                transaction_id_project_transaction,
 2222                                formatting_transaction_id,
 2223                            );
 2224                        });
 2225                    }
 2226
 2227                    if project_transaction_command.0.is_empty() {
 2228                        continue;
 2229                    }
 2230
 2231                    let mut extra_buffers = String::new();
 2232                    for buffer in project_transaction_command.0.keys() {
 2233                        buffer.read_with(cx, |b, cx| {
 2234                            let Some(path) = b.project_path(cx) else {
 2235                                return;
 2236                            };
 2237
 2238                            if !extra_buffers.is_empty() {
 2239                                extra_buffers.push_str(", ");
 2240                            }
 2241                            extra_buffers.push_str(path.path.as_unix_str());
 2242                        });
 2243                    }
 2244                    zlog::warn!(
 2245                        logger =>
 2246                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2247                        &command.command,
 2248                        extra_buffers,
 2249                    );
 2250                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2251                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2252                    // add it so it's included, and merge it into the format transaction when its created later
 2253                }
 2254            }
 2255        }
 2256
 2257        Ok(())
 2258    }
 2259
 2260    pub async fn format_ranges_via_lsp(
 2261        this: &WeakEntity<LspStore>,
 2262        buffer_handle: &Entity<Buffer>,
 2263        ranges: &[Range<Anchor>],
 2264        abs_path: &Path,
 2265        language_server: &Arc<LanguageServer>,
 2266        settings: &LanguageSettings,
 2267        cx: &mut AsyncApp,
 2268    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2269        let capabilities = &language_server.capabilities();
 2270        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2271        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2272            anyhow::bail!(
 2273                "{} language server does not support range formatting",
 2274                language_server.name()
 2275            );
 2276        }
 2277
 2278        let uri = file_path_to_lsp_url(abs_path)?;
 2279        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2280
 2281        let request_timeout = cx.update(|app| {
 2282            ProjectSettings::get_global(app)
 2283                .global_lsp_settings
 2284                .get_request_timeout()
 2285        });
 2286        let lsp_edits = {
 2287            let mut lsp_ranges = Vec::new();
 2288            this.update(cx, |_this, cx| {
 2289                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2290                // not have been sent to the language server. This seems like a fairly systemic
 2291                // issue, though, the resolution probably is not specific to formatting.
 2292                //
 2293                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2294                // LSP.
 2295                let snapshot = buffer_handle.read(cx).snapshot();
 2296                for range in ranges {
 2297                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2298                }
 2299                anyhow::Ok(())
 2300            })??;
 2301
 2302            let mut edits = None;
 2303            for range in lsp_ranges {
 2304                if let Some(mut edit) = language_server
 2305                    .request::<lsp::request::RangeFormatting>(
 2306                        lsp::DocumentRangeFormattingParams {
 2307                            text_document: text_document.clone(),
 2308                            range,
 2309                            options: lsp_command::lsp_formatting_options(settings),
 2310                            work_done_progress_params: Default::default(),
 2311                        },
 2312                        request_timeout,
 2313                    )
 2314                    .await
 2315                    .into_response()?
 2316                {
 2317                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2318                }
 2319            }
 2320            edits
 2321        };
 2322
 2323        if let Some(lsp_edits) = lsp_edits {
 2324            this.update(cx, |this, cx| {
 2325                this.as_local_mut().unwrap().edits_from_lsp(
 2326                    buffer_handle,
 2327                    lsp_edits,
 2328                    language_server.server_id(),
 2329                    None,
 2330                    cx,
 2331                )
 2332            })?
 2333            .await
 2334        } else {
 2335            Ok(Vec::with_capacity(0))
 2336        }
 2337    }
 2338
 2339    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2340        let capabilities = server.capabilities();
 2341        let formatting = capabilities.document_formatting_provider.as_ref();
 2342        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2343        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2344            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2345    }
 2346
 2347    async fn format_via_lsp(
 2348        this: &WeakEntity<LspStore>,
 2349        buffer: &Entity<Buffer>,
 2350        abs_path: &Path,
 2351        language_server: &Arc<LanguageServer>,
 2352        settings: &LanguageSettings,
 2353        cx: &mut AsyncApp,
 2354    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2355        let logger = zlog::scoped!("lsp_format");
 2356        zlog::debug!(logger => "Formatting via LSP");
 2357
 2358        let uri = file_path_to_lsp_url(abs_path)?;
 2359        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2360        let capabilities = &language_server.capabilities();
 2361
 2362        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2363        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2364
 2365        let request_timeout = cx.update(|app| {
 2366            ProjectSettings::get_global(app)
 2367                .global_lsp_settings
 2368                .get_request_timeout()
 2369        });
 2370
 2371        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2372            let _timer = zlog::time!(logger => "format-full");
 2373            language_server
 2374                .request::<lsp::request::Formatting>(
 2375                    lsp::DocumentFormattingParams {
 2376                        text_document,
 2377                        options: lsp_command::lsp_formatting_options(settings),
 2378                        work_done_progress_params: Default::default(),
 2379                    },
 2380                    request_timeout,
 2381                )
 2382                .await
 2383                .into_response()?
 2384        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2385            let _timer = zlog::time!(logger => "format-range");
 2386            let buffer_start = lsp::Position::new(0, 0);
 2387            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2388            language_server
 2389                .request::<lsp::request::RangeFormatting>(
 2390                    lsp::DocumentRangeFormattingParams {
 2391                        text_document: text_document.clone(),
 2392                        range: lsp::Range::new(buffer_start, buffer_end),
 2393                        options: lsp_command::lsp_formatting_options(settings),
 2394                        work_done_progress_params: Default::default(),
 2395                    },
 2396                    request_timeout,
 2397                )
 2398                .await
 2399                .into_response()?
 2400        } else {
 2401            None
 2402        };
 2403
 2404        if let Some(lsp_edits) = lsp_edits {
 2405            this.update(cx, |this, cx| {
 2406                this.as_local_mut().unwrap().edits_from_lsp(
 2407                    buffer,
 2408                    lsp_edits,
 2409                    language_server.server_id(),
 2410                    None,
 2411                    cx,
 2412                )
 2413            })?
 2414            .await
 2415        } else {
 2416            Ok(Vec::with_capacity(0))
 2417        }
 2418    }
 2419
 2420    async fn format_via_external_command(
 2421        buffer: &FormattableBuffer,
 2422        command: &str,
 2423        arguments: Option<&[String]>,
 2424        cx: &mut AsyncApp,
 2425    ) -> Result<Option<Diff>> {
 2426        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2427            let file = File::from_dyn(buffer.file())?;
 2428            let worktree = file.worktree.read(cx);
 2429            let mut worktree_path = worktree.abs_path().to_path_buf();
 2430            if worktree.root_entry()?.is_file() {
 2431                worktree_path.pop();
 2432            }
 2433            Some(worktree_path)
 2434        });
 2435
 2436        use util::command::Stdio;
 2437        let mut child = util::command::new_command(command);
 2438
 2439        if let Some(buffer_env) = buffer.env.as_ref() {
 2440            child.envs(buffer_env);
 2441        }
 2442
 2443        if let Some(working_dir_path) = working_dir_path {
 2444            child.current_dir(working_dir_path);
 2445        }
 2446
 2447        if let Some(arguments) = arguments {
 2448            child.args(arguments.iter().map(|arg| {
 2449                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2450                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2451                } else {
 2452                    arg.replace("{buffer_path}", "Untitled")
 2453                }
 2454            }));
 2455        }
 2456
 2457        let mut child = child
 2458            .stdin(Stdio::piped())
 2459            .stdout(Stdio::piped())
 2460            .stderr(Stdio::piped())
 2461            .spawn()?;
 2462
 2463        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2464        let text = buffer
 2465            .handle
 2466            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2467        for chunk in text.chunks() {
 2468            stdin.write_all(chunk.as_bytes()).await?;
 2469        }
 2470        stdin.flush().await?;
 2471
 2472        let output = child.output().await?;
 2473        anyhow::ensure!(
 2474            output.status.success(),
 2475            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2476            output.status.code(),
 2477            String::from_utf8_lossy(&output.stdout),
 2478            String::from_utf8_lossy(&output.stderr),
 2479        );
 2480
 2481        let stdout = String::from_utf8(output.stdout)?;
 2482        Ok(Some(
 2483            buffer
 2484                .handle
 2485                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2486                .await,
 2487        ))
 2488    }
 2489
 2490    async fn try_resolve_code_action(
 2491        lang_server: &LanguageServer,
 2492        action: &mut CodeAction,
 2493        request_timeout: Duration,
 2494    ) -> anyhow::Result<()> {
 2495        match &mut action.lsp_action {
 2496            LspAction::Action(lsp_action) => {
 2497                if !action.resolved
 2498                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2499                    && lsp_action.data.is_some()
 2500                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2501                {
 2502                    **lsp_action = lang_server
 2503                        .request::<lsp::request::CodeActionResolveRequest>(
 2504                            *lsp_action.clone(),
 2505                            request_timeout,
 2506                        )
 2507                        .await
 2508                        .into_response()?;
 2509                }
 2510            }
 2511            LspAction::CodeLens(lens) => {
 2512                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2513                    *lens = lang_server
 2514                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2515                        .await
 2516                        .into_response()?;
 2517                }
 2518            }
 2519            LspAction::Command(_) => {}
 2520        }
 2521
 2522        action.resolved = true;
 2523        anyhow::Ok(())
 2524    }
 2525
 2526    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2527        let buffer = buffer_handle.read(cx);
 2528
 2529        let file = buffer.file().cloned();
 2530
 2531        let Some(file) = File::from_dyn(file.as_ref()) else {
 2532            return;
 2533        };
 2534        if !file.is_local() {
 2535            return;
 2536        }
 2537        let path = ProjectPath::from_file(file, cx);
 2538        let worktree_id = file.worktree_id(cx);
 2539        let language = buffer.language().cloned();
 2540
 2541        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2542            for (server_id, diagnostics) in
 2543                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2544            {
 2545                self.update_buffer_diagnostics(
 2546                    buffer_handle,
 2547                    server_id,
 2548                    None,
 2549                    None,
 2550                    None,
 2551                    Vec::new(),
 2552                    diagnostics,
 2553                    cx,
 2554                )
 2555                .log_err();
 2556            }
 2557        }
 2558        let Some(language) = language else {
 2559            return;
 2560        };
 2561        let Some(snapshot) = self
 2562            .worktree_store
 2563            .read(cx)
 2564            .worktree_for_id(worktree_id, cx)
 2565            .map(|worktree| worktree.read(cx).snapshot())
 2566        else {
 2567            return;
 2568        };
 2569        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2570
 2571        for server_id in
 2572            self.lsp_tree
 2573                .get(path, language.name(), language.manifest(), &delegate, cx)
 2574        {
 2575            let server = self
 2576                .language_servers
 2577                .get(&server_id)
 2578                .and_then(|server_state| {
 2579                    if let LanguageServerState::Running { server, .. } = server_state {
 2580                        Some(server.clone())
 2581                    } else {
 2582                        None
 2583                    }
 2584                });
 2585            let server = match server {
 2586                Some(server) => server,
 2587                None => continue,
 2588            };
 2589
 2590            buffer_handle.update(cx, |buffer, cx| {
 2591                buffer.set_completion_triggers(
 2592                    server.server_id(),
 2593                    server
 2594                        .capabilities()
 2595                        .completion_provider
 2596                        .as_ref()
 2597                        .and_then(|provider| {
 2598                            provider
 2599                                .trigger_characters
 2600                                .as_ref()
 2601                                .map(|characters| characters.iter().cloned().collect())
 2602                        })
 2603                        .unwrap_or_default(),
 2604                    cx,
 2605                );
 2606            });
 2607        }
 2608    }
 2609
 2610    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2611        buffer.update(cx, |buffer, cx| {
 2612            let Some(language) = buffer.language() else {
 2613                return;
 2614            };
 2615            let path = ProjectPath {
 2616                worktree_id: old_file.worktree_id(cx),
 2617                path: old_file.path.clone(),
 2618            };
 2619            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2620                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2621                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2622            }
 2623        });
 2624    }
 2625
 2626    fn update_buffer_diagnostics(
 2627        &mut self,
 2628        buffer: &Entity<Buffer>,
 2629        server_id: LanguageServerId,
 2630        registration_id: Option<Option<SharedString>>,
 2631        result_id: Option<SharedString>,
 2632        version: Option<i32>,
 2633        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2634        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        cx: &mut Context<LspStore>,
 2636    ) -> Result<()> {
 2637        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2638            Ordering::Equal
 2639                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2640                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2641                .then_with(|| a.severity.cmp(&b.severity))
 2642                .then_with(|| a.message.cmp(&b.message))
 2643        }
 2644
 2645        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2646        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2647        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2648
 2649        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2650            Ordering::Equal
 2651                .then_with(|| a.range.start.cmp(&b.range.start))
 2652                .then_with(|| b.range.end.cmp(&a.range.end))
 2653                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2654        });
 2655
 2656        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2657
 2658        let edits_since_save = std::cell::LazyCell::new(|| {
 2659            let saved_version = buffer.read(cx).saved_version();
 2660            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2661        });
 2662
 2663        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2664
 2665        for (new_diagnostic, entry) in diagnostics {
 2666            let start;
 2667            let end;
 2668            if new_diagnostic && entry.diagnostic.is_disk_based {
 2669                // Some diagnostics are based on files on disk instead of buffers'
 2670                // current contents. Adjust these diagnostics' ranges to reflect
 2671                // any unsaved edits.
 2672                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2673                // and were properly adjusted on reuse.
 2674                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2675                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2676            } else {
 2677                start = entry.range.start;
 2678                end = entry.range.end;
 2679            }
 2680
 2681            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2682                ..snapshot.clip_point_utf16(end, Bias::Right);
 2683
 2684            // Expand empty ranges by one codepoint
 2685            if range.start == range.end {
 2686                // This will be go to the next boundary when being clipped
 2687                range.end.column += 1;
 2688                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2689                if range.start == range.end && range.end.column > 0 {
 2690                    range.start.column -= 1;
 2691                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2692                }
 2693            }
 2694
 2695            sanitized_diagnostics.push(DiagnosticEntry {
 2696                range,
 2697                diagnostic: entry.diagnostic,
 2698            });
 2699        }
 2700        drop(edits_since_save);
 2701
 2702        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2703        buffer.update(cx, |buffer, cx| {
 2704            if let Some(registration_id) = registration_id {
 2705                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2706                    self.buffer_pull_diagnostics_result_ids
 2707                        .entry(server_id)
 2708                        .or_default()
 2709                        .entry(registration_id)
 2710                        .or_default()
 2711                        .insert(abs_path, result_id);
 2712                }
 2713            }
 2714
 2715            buffer.update_diagnostics(server_id, set, cx)
 2716        });
 2717
 2718        Ok(())
 2719    }
 2720
 2721    fn register_language_server_for_invisible_worktree(
 2722        &mut self,
 2723        worktree: &Entity<Worktree>,
 2724        language_server_id: LanguageServerId,
 2725        cx: &mut App,
 2726    ) {
 2727        let worktree = worktree.read(cx);
 2728        let worktree_id = worktree.id();
 2729        debug_assert!(!worktree.is_visible());
 2730        let Some(mut origin_seed) = self
 2731            .language_server_ids
 2732            .iter()
 2733            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2734        else {
 2735            return;
 2736        };
 2737        origin_seed.worktree_id = worktree_id;
 2738        self.language_server_ids
 2739            .entry(origin_seed)
 2740            .or_insert_with(|| UnifiedLanguageServer {
 2741                id: language_server_id,
 2742                project_roots: Default::default(),
 2743            });
 2744    }
 2745
 2746    fn register_buffer_with_language_servers(
 2747        &mut self,
 2748        buffer_handle: &Entity<Buffer>,
 2749        only_register_servers: HashSet<LanguageServerSelector>,
 2750        cx: &mut Context<LspStore>,
 2751    ) {
 2752        let buffer = buffer_handle.read(cx);
 2753        let buffer_id = buffer.remote_id();
 2754
 2755        let Some(file) = File::from_dyn(buffer.file()) else {
 2756            return;
 2757        };
 2758        if !file.is_local() {
 2759            return;
 2760        }
 2761
 2762        let abs_path = file.abs_path(cx);
 2763        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2764            return;
 2765        };
 2766        let initial_snapshot = buffer.text_snapshot();
 2767        let worktree_id = file.worktree_id(cx);
 2768
 2769        let Some(language) = buffer.language().cloned() else {
 2770            return;
 2771        };
 2772        let path: Arc<RelPath> = file
 2773            .path()
 2774            .parent()
 2775            .map(Arc::from)
 2776            .unwrap_or_else(|| file.path().clone());
 2777        let Some(worktree) = self
 2778            .worktree_store
 2779            .read(cx)
 2780            .worktree_for_id(worktree_id, cx)
 2781        else {
 2782            return;
 2783        };
 2784        let language_name = language.name();
 2785        let (reused, delegate, servers) = self
 2786            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2787            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2788            .unwrap_or_else(|| {
 2789                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2790                let delegate: Arc<dyn ManifestDelegate> =
 2791                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2792
 2793                let servers = self
 2794                    .lsp_tree
 2795                    .walk(
 2796                        ProjectPath { worktree_id, path },
 2797                        language.name(),
 2798                        language.manifest(),
 2799                        &delegate,
 2800                        cx,
 2801                    )
 2802                    .collect::<Vec<_>>();
 2803                (false, lsp_delegate, servers)
 2804            });
 2805        let servers_and_adapters = servers
 2806            .into_iter()
 2807            .filter_map(|server_node| {
 2808                if reused && server_node.server_id().is_none() {
 2809                    return None;
 2810                }
 2811                if !only_register_servers.is_empty() {
 2812                    if let Some(server_id) = server_node.server_id()
 2813                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2814                    {
 2815                        return None;
 2816                    }
 2817                    if let Some(name) = server_node.name()
 2818                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2819                    {
 2820                        return None;
 2821                    }
 2822                }
 2823
 2824                let server_id = server_node.server_id_or_init(|disposition| {
 2825                    let path = &disposition.path;
 2826
 2827                    {
 2828                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2829
 2830                        let server_id = self.get_or_insert_language_server(
 2831                            &worktree,
 2832                            delegate.clone(),
 2833                            disposition,
 2834                            &language_name,
 2835                            cx,
 2836                        );
 2837
 2838                        if let Some(state) = self.language_servers.get(&server_id)
 2839                            && let Ok(uri) = uri
 2840                        {
 2841                            state.add_workspace_folder(uri);
 2842                        };
 2843                        server_id
 2844                    }
 2845                })?;
 2846                let server_state = self.language_servers.get(&server_id)?;
 2847                if let LanguageServerState::Running {
 2848                    server, adapter, ..
 2849                } = server_state
 2850                {
 2851                    Some((server.clone(), adapter.clone()))
 2852                } else {
 2853                    None
 2854                }
 2855            })
 2856            .collect::<Vec<_>>();
 2857        for (server, adapter) in servers_and_adapters {
 2858            buffer_handle.update(cx, |buffer, cx| {
 2859                buffer.set_completion_triggers(
 2860                    server.server_id(),
 2861                    server
 2862                        .capabilities()
 2863                        .completion_provider
 2864                        .as_ref()
 2865                        .and_then(|provider| {
 2866                            provider
 2867                                .trigger_characters
 2868                                .as_ref()
 2869                                .map(|characters| characters.iter().cloned().collect())
 2870                        })
 2871                        .unwrap_or_default(),
 2872                    cx,
 2873                );
 2874            });
 2875
 2876            let snapshot = LspBufferSnapshot {
 2877                version: 0,
 2878                snapshot: initial_snapshot.clone(),
 2879            };
 2880
 2881            let mut registered = false;
 2882            self.buffer_snapshots
 2883                .entry(buffer_id)
 2884                .or_default()
 2885                .entry(server.server_id())
 2886                .or_insert_with(|| {
 2887                    registered = true;
 2888                    server.register_buffer(
 2889                        uri.clone(),
 2890                        adapter.language_id(&language.name()),
 2891                        0,
 2892                        initial_snapshot.text(),
 2893                    );
 2894
 2895                    vec![snapshot]
 2896                });
 2897
 2898            self.buffers_opened_in_servers
 2899                .entry(buffer_id)
 2900                .or_default()
 2901                .insert(server.server_id());
 2902            if registered {
 2903                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2904                    language_server_id: server.server_id(),
 2905                    name: None,
 2906                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2907                        proto::RegisteredForBuffer {
 2908                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2909                            buffer_id: buffer_id.to_proto(),
 2910                        },
 2911                    ),
 2912                });
 2913            }
 2914        }
 2915    }
 2916
 2917    fn reuse_existing_language_server<'lang_name>(
 2918        &self,
 2919        server_tree: &LanguageServerTree,
 2920        worktree: &Entity<Worktree>,
 2921        language_name: &'lang_name LanguageName,
 2922        cx: &mut App,
 2923    ) -> Option<(
 2924        Arc<LocalLspAdapterDelegate>,
 2925        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2926    )> {
 2927        if worktree.read(cx).is_visible() {
 2928            return None;
 2929        }
 2930
 2931        let worktree_store = self.worktree_store.read(cx);
 2932        let servers = server_tree
 2933            .instances
 2934            .iter()
 2935            .filter(|(worktree_id, _)| {
 2936                worktree_store
 2937                    .worktree_for_id(**worktree_id, cx)
 2938                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2939            })
 2940            .flat_map(|(worktree_id, servers)| {
 2941                servers
 2942                    .roots
 2943                    .iter()
 2944                    .flat_map(|(_, language_servers)| language_servers)
 2945                    .map(move |(_, (server_node, server_languages))| {
 2946                        (worktree_id, server_node, server_languages)
 2947                    })
 2948                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2949                    .map(|(worktree_id, server_node, _)| {
 2950                        (
 2951                            *worktree_id,
 2952                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2953                        )
 2954                    })
 2955            })
 2956            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2957                acc.entry(worktree_id)
 2958                    .or_insert_with(Vec::new)
 2959                    .push(server_node);
 2960                acc
 2961            })
 2962            .into_values()
 2963            .max_by_key(|servers| servers.len())?;
 2964
 2965        let worktree_id = worktree.read(cx).id();
 2966        let apply = move |tree: &mut LanguageServerTree| {
 2967            for server_node in &servers {
 2968                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2969            }
 2970            servers
 2971        };
 2972
 2973        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2974        Some((delegate, apply))
 2975    }
 2976
 2977    pub(crate) fn unregister_old_buffer_from_language_servers(
 2978        &mut self,
 2979        buffer: &Entity<Buffer>,
 2980        old_file: &File,
 2981        cx: &mut App,
 2982    ) {
 2983        let old_path = match old_file.as_local() {
 2984            Some(local) => local.abs_path(cx),
 2985            None => return,
 2986        };
 2987
 2988        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2989            debug_panic!("{old_path:?} is not parseable as an URI");
 2990            return;
 2991        };
 2992        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2993    }
 2994
 2995    pub(crate) fn unregister_buffer_from_language_servers(
 2996        &mut self,
 2997        buffer: &Entity<Buffer>,
 2998        file_url: &lsp::Uri,
 2999        cx: &mut App,
 3000    ) {
 3001        buffer.update(cx, |buffer, cx| {
 3002            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3003
 3004            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3005                if snapshots
 3006                    .as_mut()
 3007                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3008                {
 3009                    language_server.unregister_buffer(file_url.clone());
 3010                }
 3011            }
 3012        });
 3013    }
 3014
 3015    fn buffer_snapshot_for_lsp_version(
 3016        &mut self,
 3017        buffer: &Entity<Buffer>,
 3018        server_id: LanguageServerId,
 3019        version: Option<i32>,
 3020        cx: &App,
 3021    ) -> Result<TextBufferSnapshot> {
 3022        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3023
 3024        if let Some(version) = version {
 3025            let buffer_id = buffer.read(cx).remote_id();
 3026            let snapshots = if let Some(snapshots) = self
 3027                .buffer_snapshots
 3028                .get_mut(&buffer_id)
 3029                .and_then(|m| m.get_mut(&server_id))
 3030            {
 3031                snapshots
 3032            } else if version == 0 {
 3033                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3034                // We detect this case and treat it as if the version was `None`.
 3035                return Ok(buffer.read(cx).text_snapshot());
 3036            } else {
 3037                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3038            };
 3039
 3040            let found_snapshot = snapshots
 3041                    .binary_search_by_key(&version, |e| e.version)
 3042                    .map(|ix| snapshots[ix].snapshot.clone())
 3043                    .map_err(|_| {
 3044                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3045                    })?;
 3046
 3047            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3048            Ok(found_snapshot)
 3049        } else {
 3050            Ok((buffer.read(cx)).text_snapshot())
 3051        }
 3052    }
 3053
 3054    async fn get_server_code_actions_from_action_kinds(
 3055        lsp_store: &WeakEntity<LspStore>,
 3056        language_server_id: LanguageServerId,
 3057        code_action_kinds: Vec<lsp::CodeActionKind>,
 3058        buffer: &Entity<Buffer>,
 3059        cx: &mut AsyncApp,
 3060    ) -> Result<Vec<CodeAction>> {
 3061        let actions = lsp_store
 3062            .update(cx, move |this, cx| {
 3063                let request = GetCodeActions {
 3064                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3065                    kinds: Some(code_action_kinds),
 3066                };
 3067                let server = LanguageServerToQuery::Other(language_server_id);
 3068                this.request_lsp(buffer.clone(), server, request, cx)
 3069            })?
 3070            .await?;
 3071        Ok(actions)
 3072    }
 3073
 3074    pub async fn execute_code_actions_on_server(
 3075        lsp_store: &WeakEntity<LspStore>,
 3076        language_server: &Arc<LanguageServer>,
 3077        actions: Vec<CodeAction>,
 3078        push_to_history: bool,
 3079        project_transaction: &mut ProjectTransaction,
 3080        cx: &mut AsyncApp,
 3081    ) -> anyhow::Result<()> {
 3082        let request_timeout = cx.update(|app| {
 3083            ProjectSettings::get_global(app)
 3084                .global_lsp_settings
 3085                .get_request_timeout()
 3086        });
 3087
 3088        for mut action in actions {
 3089            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3090                .await
 3091                .context("resolving a formatting code action")?;
 3092
 3093            if let Some(edit) = action.lsp_action.edit() {
 3094                if edit.changes.is_none() && edit.document_changes.is_none() {
 3095                    continue;
 3096                }
 3097
 3098                let new = Self::deserialize_workspace_edit(
 3099                    lsp_store.upgrade().context("project dropped")?,
 3100                    edit.clone(),
 3101                    push_to_history,
 3102                    language_server.clone(),
 3103                    cx,
 3104                )
 3105                .await?;
 3106                project_transaction.0.extend(new.0);
 3107            }
 3108
 3109            let Some(command) = action.lsp_action.command() else {
 3110                continue;
 3111            };
 3112
 3113            let server_capabilities = language_server.capabilities();
 3114            let available_commands = server_capabilities
 3115                .execute_command_provider
 3116                .as_ref()
 3117                .map(|options| options.commands.as_slice())
 3118                .unwrap_or_default();
 3119            if !available_commands.contains(&command.command) {
 3120                log::warn!(
 3121                    "Cannot execute a command {} not listed in the language server capabilities",
 3122                    command.command
 3123                );
 3124                continue;
 3125            }
 3126
 3127            lsp_store.update(cx, |lsp_store, _| {
 3128                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3129                    mode.last_workspace_edits_by_language_server
 3130                        .remove(&language_server.server_id());
 3131                }
 3132            })?;
 3133
 3134            language_server
 3135                .request::<lsp::request::ExecuteCommand>(
 3136                    lsp::ExecuteCommandParams {
 3137                        command: command.command.clone(),
 3138                        arguments: command.arguments.clone().unwrap_or_default(),
 3139                        ..Default::default()
 3140                    },
 3141                    request_timeout,
 3142                )
 3143                .await
 3144                .into_response()
 3145                .context("execute command")?;
 3146
 3147            lsp_store.update(cx, |this, _| {
 3148                if let LspStoreMode::Local(mode) = &mut this.mode {
 3149                    project_transaction.0.extend(
 3150                        mode.last_workspace_edits_by_language_server
 3151                            .remove(&language_server.server_id())
 3152                            .unwrap_or_default()
 3153                            .0,
 3154                    )
 3155                }
 3156            })?;
 3157        }
 3158        Ok(())
 3159    }
 3160
 3161    pub async fn deserialize_text_edits(
 3162        this: Entity<LspStore>,
 3163        buffer_to_edit: Entity<Buffer>,
 3164        edits: Vec<lsp::TextEdit>,
 3165        push_to_history: bool,
 3166        _: Arc<CachedLspAdapter>,
 3167        language_server: Arc<LanguageServer>,
 3168        cx: &mut AsyncApp,
 3169    ) -> Result<Option<Transaction>> {
 3170        let edits = this
 3171            .update(cx, |this, cx| {
 3172                this.as_local_mut().unwrap().edits_from_lsp(
 3173                    &buffer_to_edit,
 3174                    edits,
 3175                    language_server.server_id(),
 3176                    None,
 3177                    cx,
 3178                )
 3179            })
 3180            .await?;
 3181
 3182        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3183            buffer.finalize_last_transaction();
 3184            buffer.start_transaction();
 3185            for (range, text) in edits {
 3186                buffer.edit([(range, text)], None, cx);
 3187            }
 3188
 3189            if buffer.end_transaction(cx).is_some() {
 3190                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3191                if !push_to_history {
 3192                    buffer.forget_transaction(transaction.id);
 3193                }
 3194                Some(transaction)
 3195            } else {
 3196                None
 3197            }
 3198        });
 3199
 3200        Ok(transaction)
 3201    }
 3202
 3203    #[allow(clippy::type_complexity)]
 3204    pub fn edits_from_lsp(
 3205        &mut self,
 3206        buffer: &Entity<Buffer>,
 3207        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3208        server_id: LanguageServerId,
 3209        version: Option<i32>,
 3210        cx: &mut Context<LspStore>,
 3211    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3212        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3213        cx.background_spawn(async move {
 3214            let snapshot = snapshot?;
 3215            let mut lsp_edits = lsp_edits
 3216                .into_iter()
 3217                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3218                .collect::<Vec<_>>();
 3219
 3220            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3221
 3222            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3223            let mut edits = Vec::new();
 3224            while let Some((range, mut new_text)) = lsp_edits.next() {
 3225                // Clip invalid ranges provided by the language server.
 3226                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3227                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3228
 3229                // Combine any LSP edits that are adjacent.
 3230                //
 3231                // Also, combine LSP edits that are separated from each other by only
 3232                // a newline. This is important because for some code actions,
 3233                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3234                // are separated by unchanged newline characters.
 3235                //
 3236                // In order for the diffing logic below to work properly, any edits that
 3237                // cancel each other out must be combined into one.
 3238                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3239                    if next_range.start.0 > range.end {
 3240                        if next_range.start.0.row > range.end.row + 1
 3241                            || next_range.start.0.column > 0
 3242                            || snapshot.clip_point_utf16(
 3243                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3244                                Bias::Left,
 3245                            ) > range.end
 3246                        {
 3247                            break;
 3248                        }
 3249                        new_text.push('\n');
 3250                    }
 3251                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3252                    new_text.push_str(next_text);
 3253                    lsp_edits.next();
 3254                }
 3255
 3256                // For multiline edits, perform a diff of the old and new text so that
 3257                // we can identify the changes more precisely, preserving the locations
 3258                // of any anchors positioned in the unchanged regions.
 3259                if range.end.row > range.start.row {
 3260                    let offset = range.start.to_offset(&snapshot);
 3261                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3262                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3263                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3264                        (
 3265                            snapshot.anchor_after(offset + range.start)
 3266                                ..snapshot.anchor_before(offset + range.end),
 3267                            replacement,
 3268                        )
 3269                    }));
 3270                } else if range.end == range.start {
 3271                    let anchor = snapshot.anchor_after(range.start);
 3272                    edits.push((anchor..anchor, new_text.into()));
 3273                } else {
 3274                    let edit_start = snapshot.anchor_after(range.start);
 3275                    let edit_end = snapshot.anchor_before(range.end);
 3276                    edits.push((edit_start..edit_end, new_text.into()));
 3277                }
 3278            }
 3279
 3280            Ok(edits)
 3281        })
 3282    }
 3283
 3284    pub(crate) async fn deserialize_workspace_edit(
 3285        this: Entity<LspStore>,
 3286        edit: lsp::WorkspaceEdit,
 3287        push_to_history: bool,
 3288        language_server: Arc<LanguageServer>,
 3289        cx: &mut AsyncApp,
 3290    ) -> Result<ProjectTransaction> {
 3291        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3292
 3293        let mut operations = Vec::new();
 3294        if let Some(document_changes) = edit.document_changes {
 3295            match document_changes {
 3296                lsp::DocumentChanges::Edits(edits) => {
 3297                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3298                }
 3299                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3300            }
 3301        } else if let Some(changes) = edit.changes {
 3302            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3303                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3304                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3305                        uri,
 3306                        version: None,
 3307                    },
 3308                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3309                })
 3310            }));
 3311        }
 3312
 3313        let mut project_transaction = ProjectTransaction::default();
 3314        for operation in operations {
 3315            match operation {
 3316                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3317                    let abs_path = op
 3318                        .uri
 3319                        .to_file_path()
 3320                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3321
 3322                    if let Some(parent_path) = abs_path.parent() {
 3323                        fs.create_dir(parent_path).await?;
 3324                    }
 3325                    if abs_path.ends_with("/") {
 3326                        fs.create_dir(&abs_path).await?;
 3327                    } else {
 3328                        fs.create_file(
 3329                            &abs_path,
 3330                            op.options
 3331                                .map(|options| fs::CreateOptions {
 3332                                    overwrite: options.overwrite.unwrap_or(false),
 3333                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3334                                })
 3335                                .unwrap_or_default(),
 3336                        )
 3337                        .await?;
 3338                    }
 3339                }
 3340
 3341                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3342                    let source_abs_path = op
 3343                        .old_uri
 3344                        .to_file_path()
 3345                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3346                    let target_abs_path = op
 3347                        .new_uri
 3348                        .to_file_path()
 3349                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3350
 3351                    let options = fs::RenameOptions {
 3352                        overwrite: op
 3353                            .options
 3354                            .as_ref()
 3355                            .and_then(|options| options.overwrite)
 3356                            .unwrap_or(false),
 3357                        ignore_if_exists: op
 3358                            .options
 3359                            .as_ref()
 3360                            .and_then(|options| options.ignore_if_exists)
 3361                            .unwrap_or(false),
 3362                        create_parents: true,
 3363                    };
 3364
 3365                    fs.rename(&source_abs_path, &target_abs_path, options)
 3366                        .await?;
 3367                }
 3368
 3369                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3370                    let abs_path = op
 3371                        .uri
 3372                        .to_file_path()
 3373                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3374                    let options = op
 3375                        .options
 3376                        .map(|options| fs::RemoveOptions {
 3377                            recursive: options.recursive.unwrap_or(false),
 3378                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3379                        })
 3380                        .unwrap_or_default();
 3381                    if abs_path.ends_with("/") {
 3382                        fs.remove_dir(&abs_path, options).await?;
 3383                    } else {
 3384                        fs.remove_file(&abs_path, options).await?;
 3385                    }
 3386                }
 3387
 3388                lsp::DocumentChangeOperation::Edit(op) => {
 3389                    let buffer_to_edit = this
 3390                        .update(cx, |this, cx| {
 3391                            this.open_local_buffer_via_lsp(
 3392                                op.text_document.uri.clone(),
 3393                                language_server.server_id(),
 3394                                cx,
 3395                            )
 3396                        })
 3397                        .await?;
 3398
 3399                    let edits = this
 3400                        .update(cx, |this, cx| {
 3401                            let path = buffer_to_edit.read(cx).project_path(cx);
 3402                            let active_entry = this.active_entry;
 3403                            let is_active_entry = path.is_some_and(|project_path| {
 3404                                this.worktree_store
 3405                                    .read(cx)
 3406                                    .entry_for_path(&project_path, cx)
 3407                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3408                            });
 3409                            let local = this.as_local_mut().unwrap();
 3410
 3411                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3412                            for edit in op.edits {
 3413                                match edit {
 3414                                    Edit::Plain(edit) => {
 3415                                        if !edits.contains(&edit) {
 3416                                            edits.push(edit)
 3417                                        }
 3418                                    }
 3419                                    Edit::Annotated(edit) => {
 3420                                        if !edits.contains(&edit.text_edit) {
 3421                                            edits.push(edit.text_edit)
 3422                                        }
 3423                                    }
 3424                                    Edit::Snippet(edit) => {
 3425                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3426                                        else {
 3427                                            continue;
 3428                                        };
 3429
 3430                                        if is_active_entry {
 3431                                            snippet_edits.push((edit.range, snippet));
 3432                                        } else {
 3433                                            // Since this buffer is not focused, apply a normal edit.
 3434                                            let new_edit = TextEdit {
 3435                                                range: edit.range,
 3436                                                new_text: snippet.text,
 3437                                            };
 3438                                            if !edits.contains(&new_edit) {
 3439                                                edits.push(new_edit);
 3440                                            }
 3441                                        }
 3442                                    }
 3443                                }
 3444                            }
 3445                            if !snippet_edits.is_empty() {
 3446                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3447                                let version = if let Some(buffer_version) = op.text_document.version
 3448                                {
 3449                                    local
 3450                                        .buffer_snapshot_for_lsp_version(
 3451                                            &buffer_to_edit,
 3452                                            language_server.server_id(),
 3453                                            Some(buffer_version),
 3454                                            cx,
 3455                                        )
 3456                                        .ok()
 3457                                        .map(|snapshot| snapshot.version)
 3458                                } else {
 3459                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3460                                };
 3461
 3462                                let most_recent_edit =
 3463                                    version.and_then(|version| version.most_recent());
 3464                                // Check if the edit that triggered that edit has been made by this participant.
 3465
 3466                                if let Some(most_recent_edit) = most_recent_edit {
 3467                                    cx.emit(LspStoreEvent::SnippetEdit {
 3468                                        buffer_id,
 3469                                        edits: snippet_edits,
 3470                                        most_recent_edit,
 3471                                    });
 3472                                }
 3473                            }
 3474
 3475                            local.edits_from_lsp(
 3476                                &buffer_to_edit,
 3477                                edits,
 3478                                language_server.server_id(),
 3479                                op.text_document.version,
 3480                                cx,
 3481                            )
 3482                        })
 3483                        .await?;
 3484
 3485                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3486                        buffer.finalize_last_transaction();
 3487                        buffer.start_transaction();
 3488                        for (range, text) in edits {
 3489                            buffer.edit([(range, text)], None, cx);
 3490                        }
 3491
 3492                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3493                            if push_to_history {
 3494                                buffer.finalize_last_transaction();
 3495                                buffer.get_transaction(transaction_id).cloned()
 3496                            } else {
 3497                                buffer.forget_transaction(transaction_id)
 3498                            }
 3499                        })
 3500                    });
 3501                    if let Some(transaction) = transaction {
 3502                        project_transaction.0.insert(buffer_to_edit, transaction);
 3503                    }
 3504                }
 3505            }
 3506        }
 3507
 3508        Ok(project_transaction)
 3509    }
 3510
 3511    async fn on_lsp_workspace_edit(
 3512        this: WeakEntity<LspStore>,
 3513        params: lsp::ApplyWorkspaceEditParams,
 3514        server_id: LanguageServerId,
 3515        cx: &mut AsyncApp,
 3516    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3517        let this = this.upgrade().context("project project closed")?;
 3518        let language_server = this
 3519            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3520            .context("language server not found")?;
 3521        let transaction = Self::deserialize_workspace_edit(
 3522            this.clone(),
 3523            params.edit,
 3524            true,
 3525            language_server.clone(),
 3526            cx,
 3527        )
 3528        .await
 3529        .log_err();
 3530        this.update(cx, |this, cx| {
 3531            if let Some(transaction) = transaction {
 3532                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3533
 3534                this.as_local_mut()
 3535                    .unwrap()
 3536                    .last_workspace_edits_by_language_server
 3537                    .insert(server_id, transaction);
 3538            }
 3539        });
 3540        Ok(lsp::ApplyWorkspaceEditResponse {
 3541            applied: true,
 3542            failed_change: None,
 3543            failure_reason: None,
 3544        })
 3545    }
 3546
 3547    fn remove_worktree(
 3548        &mut self,
 3549        id_to_remove: WorktreeId,
 3550        cx: &mut Context<LspStore>,
 3551    ) -> Vec<LanguageServerId> {
 3552        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3553        self.diagnostics.remove(&id_to_remove);
 3554        self.prettier_store.update(cx, |prettier_store, cx| {
 3555            prettier_store.remove_worktree(id_to_remove, cx);
 3556        });
 3557
 3558        let mut servers_to_remove = BTreeSet::default();
 3559        let mut servers_to_preserve = HashSet::default();
 3560        for (seed, state) in &self.language_server_ids {
 3561            if seed.worktree_id == id_to_remove {
 3562                servers_to_remove.insert(state.id);
 3563            } else {
 3564                servers_to_preserve.insert(state.id);
 3565            }
 3566        }
 3567        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3568        self.language_server_ids
 3569            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3570        for server_id_to_remove in &servers_to_remove {
 3571            self.language_server_watched_paths
 3572                .remove(server_id_to_remove);
 3573            self.language_server_paths_watched_for_rename
 3574                .remove(server_id_to_remove);
 3575            self.last_workspace_edits_by_language_server
 3576                .remove(server_id_to_remove);
 3577            self.language_servers.remove(server_id_to_remove);
 3578            self.buffer_pull_diagnostics_result_ids
 3579                .remove(server_id_to_remove);
 3580            self.workspace_pull_diagnostics_result_ids
 3581                .remove(server_id_to_remove);
 3582            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3583                buffer_servers.remove(server_id_to_remove);
 3584            }
 3585            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3586        }
 3587        servers_to_remove.into_iter().collect()
 3588    }
 3589
 3590    fn rebuild_watched_paths_inner<'a>(
 3591        &'a self,
 3592        language_server_id: LanguageServerId,
 3593        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3594        cx: &mut Context<LspStore>,
 3595    ) -> LanguageServerWatchedPathsBuilder {
 3596        let worktrees = self
 3597            .worktree_store
 3598            .read(cx)
 3599            .worktrees()
 3600            .filter_map(|worktree| {
 3601                self.language_servers_for_worktree(worktree.read(cx).id())
 3602                    .find(|server| server.server_id() == language_server_id)
 3603                    .map(|_| worktree)
 3604            })
 3605            .collect::<Vec<_>>();
 3606
 3607        let mut worktree_globs = HashMap::default();
 3608        let mut abs_globs = HashMap::default();
 3609        log::trace!(
 3610            "Processing new watcher paths for language server with id {}",
 3611            language_server_id
 3612        );
 3613
 3614        for watcher in watchers {
 3615            if let Some((worktree, literal_prefix, pattern)) =
 3616                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3617            {
 3618                worktree.update(cx, |worktree, _| {
 3619                    if let Some((tree, glob)) =
 3620                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3621                    {
 3622                        tree.add_path_prefix_to_scan(literal_prefix);
 3623                        worktree_globs
 3624                            .entry(tree.id())
 3625                            .or_insert_with(GlobSetBuilder::new)
 3626                            .add(glob);
 3627                    }
 3628                });
 3629            } else {
 3630                let (path, pattern) = match &watcher.glob_pattern {
 3631                    lsp::GlobPattern::String(s) => {
 3632                        let watcher_path = SanitizedPath::new(s);
 3633                        let path = glob_literal_prefix(watcher_path.as_path());
 3634                        let pattern = watcher_path
 3635                            .as_path()
 3636                            .strip_prefix(&path)
 3637                            .map(|p| p.to_string_lossy().into_owned())
 3638                            .unwrap_or_else(|e| {
 3639                                debug_panic!(
 3640                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3641                                    s,
 3642                                    path.display(),
 3643                                    e
 3644                                );
 3645                                watcher_path.as_path().to_string_lossy().into_owned()
 3646                            });
 3647                        (path, pattern)
 3648                    }
 3649                    lsp::GlobPattern::Relative(rp) => {
 3650                        let Ok(mut base_uri) = match &rp.base_uri {
 3651                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3652                            lsp::OneOf::Right(base_uri) => base_uri,
 3653                        }
 3654                        .to_file_path() else {
 3655                            continue;
 3656                        };
 3657
 3658                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3659                        let pattern = Path::new(&rp.pattern)
 3660                            .strip_prefix(&path)
 3661                            .map(|p| p.to_string_lossy().into_owned())
 3662                            .unwrap_or_else(|e| {
 3663                                debug_panic!(
 3664                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3665                                    rp.pattern,
 3666                                    path.display(),
 3667                                    e
 3668                                );
 3669                                rp.pattern.clone()
 3670                            });
 3671                        base_uri.push(path);
 3672                        (base_uri, pattern)
 3673                    }
 3674                };
 3675
 3676                if let Some(glob) = Glob::new(&pattern).log_err() {
 3677                    if !path
 3678                        .components()
 3679                        .any(|c| matches!(c, path::Component::Normal(_)))
 3680                    {
 3681                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3682                        // rather than adding a new watcher for `/`.
 3683                        for worktree in &worktrees {
 3684                            worktree_globs
 3685                                .entry(worktree.read(cx).id())
 3686                                .or_insert_with(GlobSetBuilder::new)
 3687                                .add(glob.clone());
 3688                        }
 3689                    } else {
 3690                        abs_globs
 3691                            .entry(path.into())
 3692                            .or_insert_with(GlobSetBuilder::new)
 3693                            .add(glob);
 3694                    }
 3695                }
 3696            }
 3697        }
 3698
 3699        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3700        for (worktree_id, builder) in worktree_globs {
 3701            if let Ok(globset) = builder.build() {
 3702                watch_builder.watch_worktree(worktree_id, globset);
 3703            }
 3704        }
 3705        for (abs_path, builder) in abs_globs {
 3706            if let Ok(globset) = builder.build() {
 3707                watch_builder.watch_abs_path(abs_path, globset);
 3708            }
 3709        }
 3710        watch_builder
 3711    }
 3712
 3713    fn worktree_and_path_for_file_watcher(
 3714        worktrees: &[Entity<Worktree>],
 3715        watcher: &FileSystemWatcher,
 3716        cx: &App,
 3717    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3718        worktrees.iter().find_map(|worktree| {
 3719            let tree = worktree.read(cx);
 3720            let worktree_root_path = tree.abs_path();
 3721            let path_style = tree.path_style();
 3722            match &watcher.glob_pattern {
 3723                lsp::GlobPattern::String(s) => {
 3724                    let watcher_path = SanitizedPath::new(s);
 3725                    let relative = watcher_path
 3726                        .as_path()
 3727                        .strip_prefix(&worktree_root_path)
 3728                        .ok()?;
 3729                    let literal_prefix = glob_literal_prefix(relative);
 3730                    Some((
 3731                        worktree.clone(),
 3732                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3733                        relative.to_string_lossy().into_owned(),
 3734                    ))
 3735                }
 3736                lsp::GlobPattern::Relative(rp) => {
 3737                    let base_uri = match &rp.base_uri {
 3738                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3739                        lsp::OneOf::Right(base_uri) => base_uri,
 3740                    }
 3741                    .to_file_path()
 3742                    .ok()?;
 3743                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3744                    let mut literal_prefix = relative.to_owned();
 3745                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3746                    Some((
 3747                        worktree.clone(),
 3748                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3749                        rp.pattern.clone(),
 3750                    ))
 3751                }
 3752            }
 3753        })
 3754    }
 3755
 3756    fn rebuild_watched_paths(
 3757        &mut self,
 3758        language_server_id: LanguageServerId,
 3759        cx: &mut Context<LspStore>,
 3760    ) {
 3761        let Some(registrations) = self
 3762            .language_server_dynamic_registrations
 3763            .get(&language_server_id)
 3764        else {
 3765            return;
 3766        };
 3767
 3768        let watch_builder = self.rebuild_watched_paths_inner(
 3769            language_server_id,
 3770            registrations.did_change_watched_files.values().flatten(),
 3771            cx,
 3772        );
 3773        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3774        self.language_server_watched_paths
 3775            .insert(language_server_id, watcher);
 3776
 3777        cx.notify();
 3778    }
 3779
 3780    fn on_lsp_did_change_watched_files(
 3781        &mut self,
 3782        language_server_id: LanguageServerId,
 3783        registration_id: &str,
 3784        params: DidChangeWatchedFilesRegistrationOptions,
 3785        cx: &mut Context<LspStore>,
 3786    ) {
 3787        let registrations = self
 3788            .language_server_dynamic_registrations
 3789            .entry(language_server_id)
 3790            .or_default();
 3791
 3792        registrations
 3793            .did_change_watched_files
 3794            .insert(registration_id.to_string(), params.watchers);
 3795
 3796        self.rebuild_watched_paths(language_server_id, cx);
 3797    }
 3798
 3799    fn on_lsp_unregister_did_change_watched_files(
 3800        &mut self,
 3801        language_server_id: LanguageServerId,
 3802        registration_id: &str,
 3803        cx: &mut Context<LspStore>,
 3804    ) {
 3805        let registrations = self
 3806            .language_server_dynamic_registrations
 3807            .entry(language_server_id)
 3808            .or_default();
 3809
 3810        if registrations
 3811            .did_change_watched_files
 3812            .remove(registration_id)
 3813            .is_some()
 3814        {
 3815            log::info!(
 3816                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3817                language_server_id,
 3818                registration_id
 3819            );
 3820        } else {
 3821            log::warn!(
 3822                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3823                language_server_id,
 3824                registration_id
 3825            );
 3826        }
 3827
 3828        self.rebuild_watched_paths(language_server_id, cx);
 3829    }
 3830
 3831    async fn initialization_options_for_adapter(
 3832        adapter: Arc<dyn LspAdapter>,
 3833        delegate: &Arc<dyn LspAdapterDelegate>,
 3834        cx: &mut AsyncApp,
 3835    ) -> Result<Option<serde_json::Value>> {
 3836        let Some(mut initialization_config) =
 3837            adapter.clone().initialization_options(delegate, cx).await?
 3838        else {
 3839            return Ok(None);
 3840        };
 3841
 3842        for other_adapter in delegate.registered_lsp_adapters() {
 3843            if other_adapter.name() == adapter.name() {
 3844                continue;
 3845            }
 3846            if let Ok(Some(target_config)) = other_adapter
 3847                .clone()
 3848                .additional_initialization_options(adapter.name(), delegate)
 3849                .await
 3850            {
 3851                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3852            }
 3853        }
 3854
 3855        Ok(Some(initialization_config))
 3856    }
 3857
 3858    async fn workspace_configuration_for_adapter(
 3859        adapter: Arc<dyn LspAdapter>,
 3860        delegate: &Arc<dyn LspAdapterDelegate>,
 3861        toolchain: Option<Toolchain>,
 3862        requested_uri: Option<Uri>,
 3863        cx: &mut AsyncApp,
 3864    ) -> Result<serde_json::Value> {
 3865        let mut workspace_config = adapter
 3866            .clone()
 3867            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3868            .await?;
 3869
 3870        for other_adapter in delegate.registered_lsp_adapters() {
 3871            if other_adapter.name() == adapter.name() {
 3872                continue;
 3873            }
 3874            if let Ok(Some(target_config)) = other_adapter
 3875                .clone()
 3876                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3877                .await
 3878            {
 3879                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3880            }
 3881        }
 3882
 3883        Ok(workspace_config)
 3884    }
 3885
 3886    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3887        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3888            Some(server.clone())
 3889        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3890            Some(Arc::clone(server))
 3891        } else {
 3892            None
 3893        }
 3894    }
 3895}
 3896
 3897fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3898    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3899        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3900            language_server_id: server.server_id(),
 3901            name: Some(server.name()),
 3902            message: proto::update_language_server::Variant::MetadataUpdated(
 3903                proto::ServerMetadataUpdated {
 3904                    capabilities: Some(capabilities),
 3905                    binary: Some(proto::LanguageServerBinaryInfo {
 3906                        path: server.binary().path.to_string_lossy().into_owned(),
 3907                        arguments: server
 3908                            .binary()
 3909                            .arguments
 3910                            .iter()
 3911                            .map(|arg| arg.to_string_lossy().into_owned())
 3912                            .collect(),
 3913                    }),
 3914                    configuration: serde_json::to_string(server.configuration()).ok(),
 3915                    workspace_folders: server
 3916                        .workspace_folders()
 3917                        .iter()
 3918                        .map(|uri| uri.to_string())
 3919                        .collect(),
 3920                },
 3921            ),
 3922        });
 3923    }
 3924}
 3925
 3926#[derive(Debug)]
 3927pub struct FormattableBuffer {
 3928    handle: Entity<Buffer>,
 3929    abs_path: Option<PathBuf>,
 3930    env: Option<HashMap<String, String>>,
 3931    ranges: Option<Vec<Range<Anchor>>>,
 3932}
 3933
 3934pub struct RemoteLspStore {
 3935    upstream_client: Option<AnyProtoClient>,
 3936    upstream_project_id: u64,
 3937}
 3938
 3939pub(crate) enum LspStoreMode {
 3940    Local(LocalLspStore),   // ssh host and collab host
 3941    Remote(RemoteLspStore), // collab guest
 3942}
 3943
 3944impl LspStoreMode {
 3945    fn is_local(&self) -> bool {
 3946        matches!(self, LspStoreMode::Local(_))
 3947    }
 3948}
 3949
 3950pub struct LspStore {
 3951    mode: LspStoreMode,
 3952    last_formatting_failure: Option<String>,
 3953    downstream_client: Option<(AnyProtoClient, u64)>,
 3954    nonce: u128,
 3955    buffer_store: Entity<BufferStore>,
 3956    worktree_store: Entity<WorktreeStore>,
 3957    pub languages: Arc<LanguageRegistry>,
 3958    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3959    active_entry: Option<ProjectEntryId>,
 3960    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3961    _maintain_buffer_languages: Task<()>,
 3962    diagnostic_summaries:
 3963        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3964    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3965    semantic_token_config: SemanticTokenConfig,
 3966    lsp_data: HashMap<BufferId, BufferLspData>,
 3967    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3968    next_hint_id: Arc<AtomicUsize>,
 3969}
 3970
 3971#[derive(Debug)]
 3972pub struct BufferLspData {
 3973    buffer_version: Global,
 3974    document_colors: Option<DocumentColorData>,
 3975    code_lens: Option<CodeLensData>,
 3976    semantic_tokens: Option<SemanticTokensData>,
 3977    folding_ranges: Option<FoldingRangeData>,
 3978    document_symbols: Option<DocumentSymbolsData>,
 3979    inlay_hints: BufferInlayHints,
 3980    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3981    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3982}
 3983
 3984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3985struct LspKey {
 3986    request_type: TypeId,
 3987    server_queried: Option<LanguageServerId>,
 3988}
 3989
 3990impl BufferLspData {
 3991    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3992        Self {
 3993            buffer_version: buffer.read(cx).version(),
 3994            document_colors: None,
 3995            code_lens: None,
 3996            semantic_tokens: None,
 3997            folding_ranges: None,
 3998            document_symbols: None,
 3999            inlay_hints: BufferInlayHints::new(buffer, cx),
 4000            lsp_requests: HashMap::default(),
 4001            chunk_lsp_requests: HashMap::default(),
 4002        }
 4003    }
 4004
 4005    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4006        if let Some(document_colors) = &mut self.document_colors {
 4007            document_colors.remove_server_data(for_server);
 4008        }
 4009
 4010        if let Some(code_lens) = &mut self.code_lens {
 4011            code_lens.remove_server_data(for_server);
 4012        }
 4013
 4014        self.inlay_hints.remove_server_data(for_server);
 4015
 4016        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4017            semantic_tokens.remove_server_data(for_server);
 4018        }
 4019
 4020        if let Some(folding_ranges) = &mut self.folding_ranges {
 4021            folding_ranges.ranges.remove(&for_server);
 4022        }
 4023
 4024        if let Some(document_symbols) = &mut self.document_symbols {
 4025            document_symbols.remove_server_data(for_server);
 4026        }
 4027    }
 4028
 4029    #[cfg(any(test, feature = "test-support"))]
 4030    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4031        &self.inlay_hints
 4032    }
 4033}
 4034
 4035#[derive(Debug)]
 4036pub enum LspStoreEvent {
 4037    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4038    LanguageServerRemoved(LanguageServerId),
 4039    LanguageServerUpdate {
 4040        language_server_id: LanguageServerId,
 4041        name: Option<LanguageServerName>,
 4042        message: proto::update_language_server::Variant,
 4043    },
 4044    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4045    LanguageServerPrompt(LanguageServerPromptRequest),
 4046    LanguageDetected {
 4047        buffer: Entity<Buffer>,
 4048        new_language: Option<Arc<Language>>,
 4049    },
 4050    Notification(String),
 4051    RefreshInlayHints {
 4052        server_id: LanguageServerId,
 4053        request_id: Option<usize>,
 4054    },
 4055    RefreshSemanticTokens {
 4056        server_id: LanguageServerId,
 4057        request_id: Option<usize>,
 4058    },
 4059    RefreshCodeLens,
 4060    DiagnosticsUpdated {
 4061        server_id: LanguageServerId,
 4062        paths: Vec<ProjectPath>,
 4063    },
 4064    DiskBasedDiagnosticsStarted {
 4065        language_server_id: LanguageServerId,
 4066    },
 4067    DiskBasedDiagnosticsFinished {
 4068        language_server_id: LanguageServerId,
 4069    },
 4070    SnippetEdit {
 4071        buffer_id: BufferId,
 4072        edits: Vec<(lsp::Range, Snippet)>,
 4073        most_recent_edit: clock::Lamport,
 4074    },
 4075    WorkspaceEditApplied(ProjectTransaction),
 4076}
 4077
 4078#[derive(Clone, Debug, Serialize)]
 4079pub struct LanguageServerStatus {
 4080    pub name: LanguageServerName,
 4081    pub server_version: Option<SharedString>,
 4082    pub server_readable_version: Option<SharedString>,
 4083    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4084    pub has_pending_diagnostic_updates: bool,
 4085    pub progress_tokens: HashSet<ProgressToken>,
 4086    pub worktree: Option<WorktreeId>,
 4087    pub binary: Option<LanguageServerBinary>,
 4088    pub configuration: Option<Value>,
 4089    pub workspace_folders: BTreeSet<Uri>,
 4090    pub process_id: Option<u32>,
 4091}
 4092
 4093#[derive(Clone, Debug)]
 4094struct CoreSymbol {
 4095    pub language_server_name: LanguageServerName,
 4096    pub source_worktree_id: WorktreeId,
 4097    pub source_language_server_id: LanguageServerId,
 4098    pub path: SymbolLocation,
 4099    pub name: String,
 4100    pub kind: lsp::SymbolKind,
 4101    pub range: Range<Unclipped<PointUtf16>>,
 4102    pub container_name: Option<String>,
 4103}
 4104
 4105#[derive(Clone, Debug, PartialEq, Eq)]
 4106pub enum SymbolLocation {
 4107    InProject(ProjectPath),
 4108    OutsideProject {
 4109        abs_path: Arc<Path>,
 4110        signature: [u8; 32],
 4111    },
 4112}
 4113
 4114impl SymbolLocation {
 4115    fn file_name(&self) -> Option<&str> {
 4116        match self {
 4117            Self::InProject(path) => path.path.file_name(),
 4118            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4119        }
 4120    }
 4121}
 4122
 4123impl LspStore {
 4124    pub fn init(client: &AnyProtoClient) {
 4125        client.add_entity_request_handler(Self::handle_lsp_query);
 4126        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4127        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4128        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4129        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4130        client.add_entity_message_handler(Self::handle_start_language_server);
 4131        client.add_entity_message_handler(Self::handle_update_language_server);
 4132        client.add_entity_message_handler(Self::handle_language_server_log);
 4133        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4134        client.add_entity_request_handler(Self::handle_format_buffers);
 4135        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4136        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4137        client.add_entity_request_handler(Self::handle_apply_code_action);
 4138        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4139        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4140        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4141        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4142        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4143        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4144        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4145        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4146        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4147        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4148        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4149        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4150        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4151        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4156
 4157        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4162        client.add_entity_request_handler(
 4163            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4164        );
 4165        client.add_entity_request_handler(
 4166            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4167        );
 4168        client.add_entity_request_handler(
 4169            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4170        );
 4171    }
 4172
 4173    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4174        match &self.mode {
 4175            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4176            _ => None,
 4177        }
 4178    }
 4179
 4180    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4181        match &self.mode {
 4182            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4183            _ => None,
 4184        }
 4185    }
 4186
 4187    pub fn is_buffer_being_formatted(&self, buffer_id: BufferId) -> bool {
 4188        self.as_local()
 4189            .is_some_and(|local| local.buffers_being_formatted.contains(&buffer_id))
 4190    }
 4191
 4192    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4193        match &mut self.mode {
 4194            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4195            _ => None,
 4196        }
 4197    }
 4198
 4199    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4200        match &self.mode {
 4201            LspStoreMode::Remote(RemoteLspStore {
 4202                upstream_client: Some(upstream_client),
 4203                upstream_project_id,
 4204                ..
 4205            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4206
 4207            LspStoreMode::Remote(RemoteLspStore {
 4208                upstream_client: None,
 4209                ..
 4210            }) => None,
 4211            LspStoreMode::Local(_) => None,
 4212        }
 4213    }
 4214
 4215    pub fn new_local(
 4216        buffer_store: Entity<BufferStore>,
 4217        worktree_store: Entity<WorktreeStore>,
 4218        prettier_store: Entity<PrettierStore>,
 4219        toolchain_store: Entity<LocalToolchainStore>,
 4220        environment: Entity<ProjectEnvironment>,
 4221        manifest_tree: Entity<ManifestTree>,
 4222        languages: Arc<LanguageRegistry>,
 4223        http_client: Arc<dyn HttpClient>,
 4224        fs: Arc<dyn Fs>,
 4225        cx: &mut Context<Self>,
 4226    ) -> Self {
 4227        let yarn = YarnPathStore::new(fs.clone(), cx);
 4228        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4229            .detach();
 4230        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4231            .detach();
 4232        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4233            .detach();
 4234        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4235            .detach();
 4236        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4237            .detach();
 4238        subscribe_to_binary_statuses(&languages, cx).detach();
 4239
 4240        let _maintain_workspace_config = {
 4241            let (sender, receiver) = watch::channel();
 4242            (Self::maintain_workspace_config(receiver, cx), sender)
 4243        };
 4244
 4245        Self {
 4246            mode: LspStoreMode::Local(LocalLspStore {
 4247                weak: cx.weak_entity(),
 4248                worktree_store: worktree_store.clone(),
 4249
 4250                supplementary_language_servers: Default::default(),
 4251                languages: languages.clone(),
 4252                language_server_ids: Default::default(),
 4253                language_servers: Default::default(),
 4254                last_workspace_edits_by_language_server: Default::default(),
 4255                language_server_watched_paths: Default::default(),
 4256                language_server_paths_watched_for_rename: Default::default(),
 4257                language_server_dynamic_registrations: Default::default(),
 4258                buffers_being_formatted: Default::default(),
 4259                buffers_to_refresh_hash_set: HashSet::default(),
 4260                buffers_to_refresh_queue: VecDeque::new(),
 4261                _background_diagnostics_worker: Task::ready(()).shared(),
 4262                buffer_snapshots: Default::default(),
 4263                prettier_store,
 4264                environment,
 4265                http_client,
 4266                fs,
 4267                yarn,
 4268                next_diagnostic_group_id: Default::default(),
 4269                diagnostics: Default::default(),
 4270                _subscription: cx.on_app_quit(|this, _| {
 4271                    this.as_local_mut()
 4272                        .unwrap()
 4273                        .shutdown_language_servers_on_quit()
 4274                }),
 4275                lsp_tree: LanguageServerTree::new(
 4276                    manifest_tree,
 4277                    languages.clone(),
 4278                    toolchain_store.clone(),
 4279                ),
 4280                toolchain_store,
 4281                registered_buffers: HashMap::default(),
 4282                buffers_opened_in_servers: HashMap::default(),
 4283                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4284                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4285                restricted_worktrees_tasks: HashMap::default(),
 4286                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4287                    .manifest_file_names(),
 4288            }),
 4289            last_formatting_failure: None,
 4290            downstream_client: None,
 4291            buffer_store,
 4292            worktree_store,
 4293            languages: languages.clone(),
 4294            language_server_statuses: Default::default(),
 4295            nonce: StdRng::from_os_rng().random(),
 4296            diagnostic_summaries: HashMap::default(),
 4297            lsp_server_capabilities: HashMap::default(),
 4298            semantic_token_config: SemanticTokenConfig::new(cx),
 4299            lsp_data: HashMap::default(),
 4300            buffer_reload_tasks: HashMap::default(),
 4301            next_hint_id: Arc::default(),
 4302            active_entry: None,
 4303            _maintain_workspace_config,
 4304            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4305        }
 4306    }
 4307
 4308    fn send_lsp_proto_request<R: LspCommand>(
 4309        &self,
 4310        buffer: Entity<Buffer>,
 4311        client: AnyProtoClient,
 4312        upstream_project_id: u64,
 4313        request: R,
 4314        cx: &mut Context<LspStore>,
 4315    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4316        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4317            return Task::ready(Ok(R::Response::default()));
 4318        }
 4319        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4320        cx.spawn(async move |this, cx| {
 4321            let response = client.request(message).await?;
 4322            let this = this.upgrade().context("project dropped")?;
 4323            request
 4324                .response_from_proto(response, this, buffer, cx.clone())
 4325                .await
 4326        })
 4327    }
 4328
 4329    pub(super) fn new_remote(
 4330        buffer_store: Entity<BufferStore>,
 4331        worktree_store: Entity<WorktreeStore>,
 4332        languages: Arc<LanguageRegistry>,
 4333        upstream_client: AnyProtoClient,
 4334        project_id: u64,
 4335        cx: &mut Context<Self>,
 4336    ) -> Self {
 4337        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4338            .detach();
 4339        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4340            .detach();
 4341        subscribe_to_binary_statuses(&languages, cx).detach();
 4342        let _maintain_workspace_config = {
 4343            let (sender, receiver) = watch::channel();
 4344            (Self::maintain_workspace_config(receiver, cx), sender)
 4345        };
 4346        Self {
 4347            mode: LspStoreMode::Remote(RemoteLspStore {
 4348                upstream_client: Some(upstream_client),
 4349                upstream_project_id: project_id,
 4350            }),
 4351            downstream_client: None,
 4352            last_formatting_failure: None,
 4353            buffer_store,
 4354            worktree_store,
 4355            languages: languages.clone(),
 4356            language_server_statuses: Default::default(),
 4357            nonce: StdRng::from_os_rng().random(),
 4358            diagnostic_summaries: HashMap::default(),
 4359            lsp_server_capabilities: HashMap::default(),
 4360            semantic_token_config: SemanticTokenConfig::new(cx),
 4361            next_hint_id: Arc::default(),
 4362            lsp_data: HashMap::default(),
 4363            buffer_reload_tasks: HashMap::default(),
 4364            active_entry: None,
 4365
 4366            _maintain_workspace_config,
 4367            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4368        }
 4369    }
 4370
 4371    fn on_buffer_store_event(
 4372        &mut self,
 4373        _: Entity<BufferStore>,
 4374        event: &BufferStoreEvent,
 4375        cx: &mut Context<Self>,
 4376    ) {
 4377        match event {
 4378            BufferStoreEvent::BufferAdded(buffer) => {
 4379                self.on_buffer_added(buffer, cx).log_err();
 4380            }
 4381            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4382                let buffer_id = buffer.read(cx).remote_id();
 4383                if let Some(local) = self.as_local_mut()
 4384                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4385                {
 4386                    local.reset_buffer(buffer, old_file, cx);
 4387
 4388                    if local.registered_buffers.contains_key(&buffer_id) {
 4389                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4390                    }
 4391                }
 4392
 4393                self.detect_language_for_buffer(buffer, cx);
 4394                if let Some(local) = self.as_local_mut() {
 4395                    local.initialize_buffer(buffer, cx);
 4396                    if local.registered_buffers.contains_key(&buffer_id) {
 4397                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4398                    }
 4399                }
 4400            }
 4401            _ => {}
 4402        }
 4403    }
 4404
 4405    fn on_worktree_store_event(
 4406        &mut self,
 4407        _: Entity<WorktreeStore>,
 4408        event: &WorktreeStoreEvent,
 4409        cx: &mut Context<Self>,
 4410    ) {
 4411        match event {
 4412            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4413                if !worktree.read(cx).is_local() {
 4414                    return;
 4415                }
 4416                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4417                    worktree::Event::UpdatedEntries(changes) => {
 4418                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4419                    }
 4420                    worktree::Event::UpdatedGitRepositories(_)
 4421                    | worktree::Event::DeletedEntry(_) => {}
 4422                })
 4423                .detach()
 4424            }
 4425            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4426            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4427                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4428            }
 4429            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4430                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4431            }
 4432            WorktreeStoreEvent::WorktreeReleased(..)
 4433            | WorktreeStoreEvent::WorktreeOrderChanged
 4434            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4435            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4436        }
 4437    }
 4438
 4439    fn on_prettier_store_event(
 4440        &mut self,
 4441        _: Entity<PrettierStore>,
 4442        event: &PrettierStoreEvent,
 4443        cx: &mut Context<Self>,
 4444    ) {
 4445        match event {
 4446            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4447                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4448            }
 4449            PrettierStoreEvent::LanguageServerAdded {
 4450                new_server_id,
 4451                name,
 4452                prettier_server,
 4453            } => {
 4454                self.register_supplementary_language_server(
 4455                    *new_server_id,
 4456                    name.clone(),
 4457                    prettier_server.clone(),
 4458                    cx,
 4459                );
 4460            }
 4461        }
 4462    }
 4463
 4464    fn on_toolchain_store_event(
 4465        &mut self,
 4466        _: Entity<LocalToolchainStore>,
 4467        event: &ToolchainStoreEvent,
 4468        _: &mut Context<Self>,
 4469    ) {
 4470        if let ToolchainStoreEvent::ToolchainActivated = event {
 4471            self.request_workspace_config_refresh()
 4472        }
 4473    }
 4474
 4475    fn request_workspace_config_refresh(&mut self) {
 4476        *self._maintain_workspace_config.1.borrow_mut() = ();
 4477    }
 4478
 4479    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4480        self.as_local().map(|local| local.prettier_store.clone())
 4481    }
 4482
 4483    fn on_buffer_event(
 4484        &mut self,
 4485        buffer: Entity<Buffer>,
 4486        event: &language::BufferEvent,
 4487        cx: &mut Context<Self>,
 4488    ) {
 4489        match event {
 4490            language::BufferEvent::Edited { .. } => {
 4491                self.on_buffer_edited(buffer, cx);
 4492            }
 4493
 4494            language::BufferEvent::Saved => {
 4495                self.on_buffer_saved(buffer, cx);
 4496            }
 4497
 4498            language::BufferEvent::Reloaded => {
 4499                self.on_buffer_reloaded(buffer, cx);
 4500            }
 4501
 4502            _ => {}
 4503        }
 4504    }
 4505
 4506    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4507        buffer
 4508            .read(cx)
 4509            .set_language_registry(self.languages.clone());
 4510
 4511        cx.subscribe(buffer, |this, buffer, event, cx| {
 4512            this.on_buffer_event(buffer, event, cx);
 4513        })
 4514        .detach();
 4515
 4516        self.parse_modeline(buffer, cx);
 4517        self.detect_language_for_buffer(buffer, cx);
 4518        if let Some(local) = self.as_local_mut() {
 4519            local.initialize_buffer(buffer, cx);
 4520        }
 4521
 4522        Ok(())
 4523    }
 4524
 4525    pub fn refresh_background_diagnostics_for_buffers(
 4526        &mut self,
 4527        buffers: HashSet<BufferId>,
 4528        cx: &mut Context<Self>,
 4529    ) -> Shared<Task<()>> {
 4530        let Some(local) = self.as_local_mut() else {
 4531            return Task::ready(()).shared();
 4532        };
 4533        for buffer in buffers {
 4534            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4535                local.buffers_to_refresh_queue.push_back(buffer);
 4536                if local.buffers_to_refresh_queue.len() == 1 {
 4537                    local._background_diagnostics_worker =
 4538                        Self::background_diagnostics_worker(cx).shared();
 4539                }
 4540            }
 4541        }
 4542
 4543        local._background_diagnostics_worker.clone()
 4544    }
 4545
 4546    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4547        let buffer_store = self.buffer_store.clone();
 4548        let local = self.as_local_mut()?;
 4549        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4550            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4551            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4552                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4553            }
 4554        }
 4555        None
 4556    }
 4557
 4558    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4559        cx.spawn(async move |this, cx| {
 4560            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4561                task.await.log_err();
 4562            }
 4563        })
 4564    }
 4565
 4566    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4567        if self.parse_modeline(&buffer, cx) {
 4568            self.detect_language_for_buffer(&buffer, cx);
 4569        }
 4570
 4571        let buffer_id = buffer.read(cx).remote_id();
 4572        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4573        self.buffer_reload_tasks.insert(buffer_id, task);
 4574    }
 4575
 4576    pub(crate) fn register_buffer_with_language_servers(
 4577        &mut self,
 4578        buffer: &Entity<Buffer>,
 4579        only_register_servers: HashSet<LanguageServerSelector>,
 4580        ignore_refcounts: bool,
 4581        cx: &mut Context<Self>,
 4582    ) -> OpenLspBufferHandle {
 4583        let buffer_id = buffer.read(cx).remote_id();
 4584        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4585        if let Some(local) = self.as_local_mut() {
 4586            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4587            if !ignore_refcounts {
 4588                *refcount += 1;
 4589            }
 4590
 4591            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4592            // 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
 4593            // 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
 4594            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4595            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4596                return handle;
 4597            };
 4598            if !file.is_local() {
 4599                return handle;
 4600            }
 4601
 4602            if ignore_refcounts || *refcount == 1 {
 4603                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4604            }
 4605            if !ignore_refcounts {
 4606                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4607                    let refcount = {
 4608                        let local = lsp_store.as_local_mut().unwrap();
 4609                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4610                            debug_panic!("bad refcounting");
 4611                            return;
 4612                        };
 4613
 4614                        *refcount -= 1;
 4615                        *refcount
 4616                    };
 4617                    if refcount == 0 {
 4618                        lsp_store.lsp_data.remove(&buffer_id);
 4619                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4620                        let local = lsp_store.as_local_mut().unwrap();
 4621                        local.registered_buffers.remove(&buffer_id);
 4622
 4623                        local.buffers_opened_in_servers.remove(&buffer_id);
 4624                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4625                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4626
 4627                            let buffer_abs_path = file.abs_path(cx);
 4628                            for (_, buffer_pull_diagnostics_result_ids) in
 4629                                &mut local.buffer_pull_diagnostics_result_ids
 4630                            {
 4631                                buffer_pull_diagnostics_result_ids.retain(
 4632                                    |_, buffer_result_ids| {
 4633                                        buffer_result_ids.remove(&buffer_abs_path);
 4634                                        !buffer_result_ids.is_empty()
 4635                                    },
 4636                                );
 4637                            }
 4638
 4639                            let diagnostic_updates = local
 4640                                .language_servers
 4641                                .keys()
 4642                                .cloned()
 4643                                .map(|server_id| DocumentDiagnosticsUpdate {
 4644                                    diagnostics: DocumentDiagnostics {
 4645                                        document_abs_path: buffer_abs_path.clone(),
 4646                                        version: None,
 4647                                        diagnostics: Vec::new(),
 4648                                    },
 4649                                    result_id: None,
 4650                                    registration_id: None,
 4651                                    server_id,
 4652                                    disk_based_sources: Cow::Borrowed(&[]),
 4653                                })
 4654                                .collect::<Vec<_>>();
 4655
 4656                            lsp_store
 4657                                .merge_diagnostic_entries(
 4658                                    diagnostic_updates,
 4659                                    |_, diagnostic, _| {
 4660                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4661                                    },
 4662                                    cx,
 4663                                )
 4664                                .context("Clearing diagnostics for the closed buffer")
 4665                                .log_err();
 4666                        }
 4667                    }
 4668                })
 4669                .detach();
 4670            }
 4671        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4672            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4673            cx.background_spawn(async move {
 4674                upstream_client
 4675                    .request(proto::RegisterBufferWithLanguageServers {
 4676                        project_id: upstream_project_id,
 4677                        buffer_id,
 4678                        only_servers: only_register_servers
 4679                            .into_iter()
 4680                            .map(|selector| {
 4681                                let selector = match selector {
 4682                                    LanguageServerSelector::Id(language_server_id) => {
 4683                                        proto::language_server_selector::Selector::ServerId(
 4684                                            language_server_id.to_proto(),
 4685                                        )
 4686                                    }
 4687                                    LanguageServerSelector::Name(language_server_name) => {
 4688                                        proto::language_server_selector::Selector::Name(
 4689                                            language_server_name.to_string(),
 4690                                        )
 4691                                    }
 4692                                };
 4693                                proto::LanguageServerSelector {
 4694                                    selector: Some(selector),
 4695                                }
 4696                            })
 4697                            .collect(),
 4698                    })
 4699                    .await
 4700            })
 4701            .detach();
 4702        } else {
 4703            // Our remote connection got closed
 4704        }
 4705        handle
 4706    }
 4707
 4708    fn maintain_buffer_languages(
 4709        languages: Arc<LanguageRegistry>,
 4710        cx: &mut Context<Self>,
 4711    ) -> Task<()> {
 4712        let mut subscription = languages.subscribe();
 4713        let mut prev_reload_count = languages.reload_count();
 4714        cx.spawn(async move |this, cx| {
 4715            while let Some(()) = subscription.next().await {
 4716                if let Some(this) = this.upgrade() {
 4717                    // If the language registry has been reloaded, then remove and
 4718                    // re-assign the languages on all open buffers.
 4719                    let reload_count = languages.reload_count();
 4720                    if reload_count > prev_reload_count {
 4721                        prev_reload_count = reload_count;
 4722                        this.update(cx, |this, cx| {
 4723                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4724                                for buffer in buffer_store.buffers() {
 4725                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4726                                    {
 4727                                        buffer.update(cx, |buffer, cx| {
 4728                                            buffer.set_language_async(None, cx)
 4729                                        });
 4730                                        if let Some(local) = this.as_local_mut() {
 4731                                            local.reset_buffer(&buffer, &f, cx);
 4732
 4733                                            if local
 4734                                                .registered_buffers
 4735                                                .contains_key(&buffer.read(cx).remote_id())
 4736                                                && let Some(file_url) =
 4737                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4738                                            {
 4739                                                local.unregister_buffer_from_language_servers(
 4740                                                    &buffer, &file_url, cx,
 4741                                                );
 4742                                            }
 4743                                        }
 4744                                    }
 4745                                }
 4746                            });
 4747                        });
 4748                    }
 4749
 4750                    this.update(cx, |this, cx| {
 4751                        let mut plain_text_buffers = Vec::new();
 4752                        let mut buffers_with_unknown_injections = Vec::new();
 4753                        for handle in this.buffer_store.read(cx).buffers() {
 4754                            let buffer = handle.read(cx);
 4755                            if buffer.language().is_none()
 4756                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4757                            {
 4758                                plain_text_buffers.push(handle);
 4759                            } else if buffer.contains_unknown_injections() {
 4760                                buffers_with_unknown_injections.push(handle);
 4761                            }
 4762                        }
 4763
 4764                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4765                        // and reused later in the invisible worktrees.
 4766                        plain_text_buffers.sort_by_key(|buffer| {
 4767                            Reverse(
 4768                                File::from_dyn(buffer.read(cx).file())
 4769                                    .map(|file| file.worktree.read(cx).is_visible()),
 4770                            )
 4771                        });
 4772
 4773                        for buffer in plain_text_buffers {
 4774                            this.detect_language_for_buffer(&buffer, cx);
 4775                            if let Some(local) = this.as_local_mut() {
 4776                                local.initialize_buffer(&buffer, cx);
 4777                                if local
 4778                                    .registered_buffers
 4779                                    .contains_key(&buffer.read(cx).remote_id())
 4780                                {
 4781                                    local.register_buffer_with_language_servers(
 4782                                        &buffer,
 4783                                        HashSet::default(),
 4784                                        cx,
 4785                                    );
 4786                                }
 4787                            }
 4788                        }
 4789
 4790                        for buffer in buffers_with_unknown_injections {
 4791                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4792                        }
 4793                    });
 4794                }
 4795            }
 4796        })
 4797    }
 4798
 4799    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4800        let buffer = buffer_handle.read(cx);
 4801        let content = buffer.as_rope();
 4802
 4803        let modeline_settings = {
 4804            let settings_store = cx.global::<SettingsStore>();
 4805            let modeline_lines = settings_store
 4806                .raw_user_settings()
 4807                .and_then(|s| s.content.modeline_lines)
 4808                .or(settings_store.raw_default_settings().modeline_lines)
 4809                .unwrap_or(5);
 4810
 4811            const MAX_MODELINE_BYTES: usize = 1024;
 4812
 4813            let first_bytes =
 4814                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4815            let mut first_lines = Vec::new();
 4816            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4817            for _ in 0..modeline_lines {
 4818                if let Some(line) = lines.next() {
 4819                    first_lines.push(line.to_string());
 4820                } else {
 4821                    break;
 4822                }
 4823            }
 4824            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4825
 4826            let last_start =
 4827                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4828            let mut last_lines = Vec::new();
 4829            let mut lines = content
 4830                .reversed_chunks_in_range(last_start..content.len())
 4831                .lines();
 4832            for _ in 0..modeline_lines {
 4833                if let Some(line) = lines.next() {
 4834                    last_lines.push(line.to_string());
 4835                } else {
 4836                    break;
 4837                }
 4838            }
 4839            let last_lines_ref: Vec<_> =
 4840                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4841            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4842        };
 4843
 4844        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4845
 4846        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4847    }
 4848
 4849    fn detect_language_for_buffer(
 4850        &mut self,
 4851        buffer_handle: &Entity<Buffer>,
 4852        cx: &mut Context<Self>,
 4853    ) -> Option<language::AvailableLanguage> {
 4854        // If the buffer has a language, set it and start the language server if we haven't already.
 4855        let buffer = buffer_handle.read(cx);
 4856        let file = buffer.file()?;
 4857        let content = buffer.as_rope();
 4858        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4859
 4860        let available_language = if let Some(ModelineSettings {
 4861            mode: Some(mode_name),
 4862            ..
 4863        }) = modeline_settings
 4864        {
 4865            self.languages
 4866                .available_language_for_modeline_name(mode_name)
 4867        } else {
 4868            self.languages.language_for_file(file, Some(content), cx)
 4869        };
 4870        if let Some(available_language) = &available_language {
 4871            if let Some(Ok(Ok(new_language))) = self
 4872                .languages
 4873                .load_language(available_language)
 4874                .now_or_never()
 4875            {
 4876                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4877            }
 4878        } else {
 4879            cx.emit(LspStoreEvent::LanguageDetected {
 4880                buffer: buffer_handle.clone(),
 4881                new_language: None,
 4882            });
 4883        }
 4884
 4885        available_language
 4886    }
 4887
 4888    pub(crate) fn set_language_for_buffer(
 4889        &mut self,
 4890        buffer_entity: &Entity<Buffer>,
 4891        new_language: Arc<Language>,
 4892        cx: &mut Context<Self>,
 4893    ) {
 4894        let buffer = buffer_entity.read(cx);
 4895        let buffer_file = buffer.file().cloned();
 4896        let buffer_id = buffer.remote_id();
 4897        if let Some(local_store) = self.as_local_mut()
 4898            && local_store.registered_buffers.contains_key(&buffer_id)
 4899            && let Some(abs_path) =
 4900                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4901            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4902        {
 4903            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4904        }
 4905        buffer_entity.update(cx, |buffer, cx| {
 4906            if buffer
 4907                .language()
 4908                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4909            {
 4910                buffer.set_language_async(Some(new_language.clone()), cx);
 4911            }
 4912        });
 4913
 4914        let settings = LanguageSettings::resolve(
 4915            Some(&buffer_entity.read(cx)),
 4916            Some(&new_language.name()),
 4917            cx,
 4918        )
 4919        .into_owned();
 4920        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4921
 4922        let worktree_id = if let Some(file) = buffer_file {
 4923            let worktree = file.worktree.clone();
 4924
 4925            if let Some(local) = self.as_local_mut()
 4926                && local.registered_buffers.contains_key(&buffer_id)
 4927            {
 4928                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4929            }
 4930            Some(worktree.read(cx).id())
 4931        } else {
 4932            None
 4933        };
 4934
 4935        if settings.prettier.allowed
 4936            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4937        {
 4938            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4939            if let Some(prettier_store) = prettier_store {
 4940                prettier_store.update(cx, |prettier_store, cx| {
 4941                    prettier_store.install_default_prettier(
 4942                        worktree_id,
 4943                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4944                        cx,
 4945                    )
 4946                })
 4947            }
 4948        }
 4949
 4950        cx.emit(LspStoreEvent::LanguageDetected {
 4951            buffer: buffer_entity.clone(),
 4952            new_language: Some(new_language),
 4953        })
 4954    }
 4955
 4956    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4957        self.buffer_store.clone()
 4958    }
 4959
 4960    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4961        self.active_entry = active_entry;
 4962    }
 4963
 4964    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4965        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4966            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4967        {
 4968            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4969                summaries
 4970                    .iter()
 4971                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4972            });
 4973            if let Some(summary) = summaries.next() {
 4974                client
 4975                    .send(proto::UpdateDiagnosticSummary {
 4976                        project_id: downstream_project_id,
 4977                        worktree_id: worktree.id().to_proto(),
 4978                        summary: Some(summary),
 4979                        more_summaries: summaries.collect(),
 4980                    })
 4981                    .log_err();
 4982            }
 4983        }
 4984    }
 4985
 4986    fn is_capable_for_proto_request<R>(
 4987        &self,
 4988        buffer: &Entity<Buffer>,
 4989        request: &R,
 4990        cx: &App,
 4991    ) -> bool
 4992    where
 4993        R: LspCommand,
 4994    {
 4995        self.check_if_capable_for_proto_request(
 4996            buffer,
 4997            |capabilities| {
 4998                request.check_capabilities(AdapterServerCapabilities {
 4999                    server_capabilities: capabilities.clone(),
 5000                    code_action_kinds: None,
 5001                })
 5002            },
 5003            cx,
 5004        )
 5005    }
 5006
 5007    fn check_if_capable_for_proto_request<F>(
 5008        &self,
 5009        buffer: &Entity<Buffer>,
 5010        check: F,
 5011        cx: &App,
 5012    ) -> bool
 5013    where
 5014        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5015    {
 5016        let Some(language) = buffer.read(cx).language().cloned() else {
 5017            return false;
 5018        };
 5019        let registered_language_servers = self
 5020            .languages
 5021            .lsp_adapters(&language.name())
 5022            .into_iter()
 5023            .map(|lsp_adapter| lsp_adapter.name())
 5024            .collect::<HashSet<_>>();
 5025        self.language_server_statuses
 5026            .iter()
 5027            .filter_map(|(server_id, server_status)| {
 5028                // Include servers that are either registered for this language OR
 5029                // available to be loaded (for SSH remote mode where adapters like
 5030                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5031                // but only loaded on the server side)
 5032                let is_relevant = registered_language_servers.contains(&server_status.name)
 5033                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5034                is_relevant.then_some(server_id)
 5035            })
 5036            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5037            .any(check)
 5038    }
 5039
 5040    fn all_capable_for_proto_request<F>(
 5041        &self,
 5042        buffer: &Entity<Buffer>,
 5043        mut check: F,
 5044        cx: &App,
 5045    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5046    where
 5047        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5048    {
 5049        let Some(language) = buffer.read(cx).language().cloned() else {
 5050            return Vec::default();
 5051        };
 5052        let registered_language_servers = self
 5053            .languages
 5054            .lsp_adapters(&language.name())
 5055            .into_iter()
 5056            .map(|lsp_adapter| lsp_adapter.name())
 5057            .collect::<HashSet<_>>();
 5058        self.language_server_statuses
 5059            .iter()
 5060            .filter_map(|(server_id, server_status)| {
 5061                // Include servers that are either registered for this language OR
 5062                // available to be loaded (for SSH remote mode where adapters like
 5063                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5064                // but only loaded on the server side)
 5065                let is_relevant = registered_language_servers.contains(&server_status.name)
 5066                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5067                is_relevant.then_some((server_id, &server_status.name))
 5068            })
 5069            .filter_map(|(server_id, server_name)| {
 5070                self.lsp_server_capabilities
 5071                    .get(server_id)
 5072                    .map(|c| (server_id, server_name, c))
 5073            })
 5074            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5075            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5076            .collect()
 5077    }
 5078
 5079    pub fn request_lsp<R>(
 5080        &mut self,
 5081        buffer: Entity<Buffer>,
 5082        server: LanguageServerToQuery,
 5083        request: R,
 5084        cx: &mut Context<Self>,
 5085    ) -> Task<Result<R::Response>>
 5086    where
 5087        R: LspCommand,
 5088        <R::LspRequest as lsp::request::Request>::Result: Send,
 5089        <R::LspRequest as lsp::request::Request>::Params: Send,
 5090    {
 5091        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5092            return self.send_lsp_proto_request(
 5093                buffer,
 5094                upstream_client,
 5095                upstream_project_id,
 5096                request,
 5097                cx,
 5098            );
 5099        }
 5100
 5101        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5102            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5103                local
 5104                    .language_servers_for_buffer(buffer, cx)
 5105                    .find(|(_, server)| {
 5106                        request.check_capabilities(server.adapter_server_capabilities())
 5107                    })
 5108                    .map(|(_, server)| server.clone())
 5109            }),
 5110            LanguageServerToQuery::Other(id) => self
 5111                .language_server_for_local_buffer(buffer, id, cx)
 5112                .and_then(|(_, server)| {
 5113                    request
 5114                        .check_capabilities(server.adapter_server_capabilities())
 5115                        .then(|| Arc::clone(server))
 5116                }),
 5117        }) else {
 5118            return Task::ready(Ok(Default::default()));
 5119        };
 5120
 5121        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5122
 5123        let Some(file) = file else {
 5124            return Task::ready(Ok(Default::default()));
 5125        };
 5126
 5127        let lsp_params = match request.to_lsp_params_or_response(
 5128            &file.abs_path(cx),
 5129            buffer.read(cx),
 5130            &language_server,
 5131            cx,
 5132        ) {
 5133            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5134            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5135            Err(err) => {
 5136                let message = format!(
 5137                    "{} via {} failed: {}",
 5138                    request.display_name(),
 5139                    language_server.name(),
 5140                    err
 5141                );
 5142                // rust-analyzer likes to error with this when its still loading up
 5143                if !message.ends_with("content modified") {
 5144                    log::warn!("{message}");
 5145                }
 5146                return Task::ready(Err(anyhow!(message)));
 5147            }
 5148        };
 5149
 5150        let status = request.status();
 5151        let request_timeout = ProjectSettings::get_global(cx)
 5152            .global_lsp_settings
 5153            .get_request_timeout();
 5154
 5155        cx.spawn(async move |this, cx| {
 5156            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5157
 5158            let id = lsp_request.id();
 5159            let _cleanup = if status.is_some() {
 5160                cx.update(|cx| {
 5161                    this.update(cx, |this, cx| {
 5162                        this.on_lsp_work_start(
 5163                            language_server.server_id(),
 5164                            ProgressToken::Number(id),
 5165                            LanguageServerProgress {
 5166                                is_disk_based_diagnostics_progress: false,
 5167                                is_cancellable: false,
 5168                                title: None,
 5169                                message: status.clone(),
 5170                                percentage: None,
 5171                                last_update_at: cx.background_executor().now(),
 5172                            },
 5173                            cx,
 5174                        );
 5175                    })
 5176                })
 5177                .log_err();
 5178
 5179                Some(defer(|| {
 5180                    cx.update(|cx| {
 5181                        this.update(cx, |this, cx| {
 5182                            this.on_lsp_work_end(
 5183                                language_server.server_id(),
 5184                                ProgressToken::Number(id),
 5185                                cx,
 5186                            );
 5187                        })
 5188                    })
 5189                    .log_err();
 5190                }))
 5191            } else {
 5192                None
 5193            };
 5194
 5195            let result = lsp_request.await.into_response();
 5196
 5197            let response = result.map_err(|err| {
 5198                let message = format!(
 5199                    "{} via {} failed: {}",
 5200                    request.display_name(),
 5201                    language_server.name(),
 5202                    err
 5203                );
 5204                // rust-analyzer likes to error with this when its still loading up
 5205                if !message.ends_with("content modified") {
 5206                    log::warn!("{message}");
 5207                }
 5208                anyhow::anyhow!(message)
 5209            })?;
 5210
 5211            request
 5212                .response_from_lsp(
 5213                    response,
 5214                    this.upgrade().context("no app context")?,
 5215                    buffer,
 5216                    language_server.server_id(),
 5217                    cx.clone(),
 5218                )
 5219                .await
 5220        })
 5221    }
 5222
 5223    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5224        let mut language_formatters_to_check = Vec::new();
 5225        for buffer in self.buffer_store.read(cx).buffers() {
 5226            let buffer = buffer.read(cx);
 5227            let settings = LanguageSettings::for_buffer(buffer, cx);
 5228            if buffer.language().is_some() {
 5229                let buffer_file = File::from_dyn(buffer.file());
 5230                language_formatters_to_check.push((
 5231                    buffer_file.map(|f| f.worktree_id(cx)),
 5232                    settings.into_owned(),
 5233                ));
 5234            }
 5235        }
 5236
 5237        self.request_workspace_config_refresh();
 5238
 5239        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5240            prettier_store.update(cx, |prettier_store, cx| {
 5241                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5242            })
 5243        }
 5244
 5245        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5246            .global_lsp_settings
 5247            .semantic_token_rules
 5248            .clone();
 5249        self.semantic_token_config
 5250            .update_rules(new_semantic_token_rules);
 5251        // Always clear cached stylizers so that changes to language-specific
 5252        // semantic token rules (e.g. from extension install/uninstall) are
 5253        // picked up. Stylizers are recreated lazily, so this is cheap.
 5254        self.semantic_token_config.clear_stylizers();
 5255
 5256        let new_global_semantic_tokens_mode =
 5257            all_language_settings(None, cx).defaults.semantic_tokens;
 5258        if self
 5259            .semantic_token_config
 5260            .update_global_mode(new_global_semantic_tokens_mode)
 5261        {
 5262            self.restart_all_language_servers(cx);
 5263        }
 5264
 5265        cx.notify();
 5266    }
 5267
 5268    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5269        let buffer_store = self.buffer_store.clone();
 5270        let Some(local) = self.as_local_mut() else {
 5271            return;
 5272        };
 5273        let mut adapters = BTreeMap::default();
 5274        let get_adapter = {
 5275            let languages = local.languages.clone();
 5276            let environment = local.environment.clone();
 5277            let weak = local.weak.clone();
 5278            let worktree_store = local.worktree_store.clone();
 5279            let http_client = local.http_client.clone();
 5280            let fs = local.fs.clone();
 5281            move |worktree_id, cx: &mut App| {
 5282                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5283                Some(LocalLspAdapterDelegate::new(
 5284                    languages.clone(),
 5285                    &environment,
 5286                    weak.clone(),
 5287                    &worktree,
 5288                    http_client.clone(),
 5289                    fs.clone(),
 5290                    cx,
 5291                ))
 5292            }
 5293        };
 5294
 5295        let mut messages_to_report = Vec::new();
 5296        let (new_tree, to_stop) = {
 5297            let mut rebase = local.lsp_tree.rebase();
 5298            let buffers = buffer_store
 5299                .read(cx)
 5300                .buffers()
 5301                .filter_map(|buffer| {
 5302                    let raw_buffer = buffer.read(cx);
 5303                    if !local
 5304                        .registered_buffers
 5305                        .contains_key(&raw_buffer.remote_id())
 5306                    {
 5307                        return None;
 5308                    }
 5309                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5310                    let language = raw_buffer.language().cloned()?;
 5311                    Some((file, language, raw_buffer.remote_id()))
 5312                })
 5313                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5314            for (file, language, buffer_id) in buffers {
 5315                let worktree_id = file.worktree_id(cx);
 5316                let Some(worktree) = local
 5317                    .worktree_store
 5318                    .read(cx)
 5319                    .worktree_for_id(worktree_id, cx)
 5320                else {
 5321                    continue;
 5322                };
 5323
 5324                if let Some((_, apply)) = local.reuse_existing_language_server(
 5325                    rebase.server_tree(),
 5326                    &worktree,
 5327                    &language.name(),
 5328                    cx,
 5329                ) {
 5330                    (apply)(rebase.server_tree());
 5331                } else if let Some(lsp_delegate) = adapters
 5332                    .entry(worktree_id)
 5333                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5334                    .clone()
 5335                {
 5336                    let delegate =
 5337                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5338                    let path = file
 5339                        .path()
 5340                        .parent()
 5341                        .map(Arc::from)
 5342                        .unwrap_or_else(|| file.path().clone());
 5343                    let worktree_path = ProjectPath { worktree_id, path };
 5344                    let abs_path = file.abs_path(cx);
 5345                    let nodes = rebase
 5346                        .walk(
 5347                            worktree_path,
 5348                            language.name(),
 5349                            language.manifest(),
 5350                            delegate.clone(),
 5351                            cx,
 5352                        )
 5353                        .collect::<Vec<_>>();
 5354                    for node in nodes {
 5355                        let server_id = node.server_id_or_init(|disposition| {
 5356                            let path = &disposition.path;
 5357                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5358                            let key = LanguageServerSeed {
 5359                                worktree_id,
 5360                                name: disposition.server_name.clone(),
 5361                                settings: LanguageServerSeedSettings {
 5362                                    binary: disposition.settings.binary.clone(),
 5363                                    initialization_options: disposition
 5364                                        .settings
 5365                                        .initialization_options
 5366                                        .clone(),
 5367                                },
 5368                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5369                                    path.worktree_id,
 5370                                    &path.path,
 5371                                    language.name(),
 5372                                ),
 5373                            };
 5374                            local.language_server_ids.remove(&key);
 5375
 5376                            let server_id = local.get_or_insert_language_server(
 5377                                &worktree,
 5378                                lsp_delegate.clone(),
 5379                                disposition,
 5380                                &language.name(),
 5381                                cx,
 5382                            );
 5383                            if let Some(state) = local.language_servers.get(&server_id)
 5384                                && let Ok(uri) = uri
 5385                            {
 5386                                state.add_workspace_folder(uri);
 5387                            };
 5388                            server_id
 5389                        });
 5390
 5391                        if let Some(language_server_id) = server_id {
 5392                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5393                                language_server_id,
 5394                                name: node.name(),
 5395                                message:
 5396                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5397                                        proto::RegisteredForBuffer {
 5398                                            buffer_abs_path: abs_path
 5399                                                .to_string_lossy()
 5400                                                .into_owned(),
 5401                                            buffer_id: buffer_id.to_proto(),
 5402                                        },
 5403                                    ),
 5404                            });
 5405                        }
 5406                    }
 5407                } else {
 5408                    continue;
 5409                }
 5410            }
 5411            rebase.finish()
 5412        };
 5413        for message in messages_to_report {
 5414            cx.emit(message);
 5415        }
 5416        local.lsp_tree = new_tree;
 5417        for (id, _) in to_stop {
 5418            self.stop_local_language_server(id, cx).detach();
 5419        }
 5420    }
 5421
 5422    pub fn apply_code_action(
 5423        &self,
 5424        buffer_handle: Entity<Buffer>,
 5425        mut action: CodeAction,
 5426        push_to_history: bool,
 5427        cx: &mut Context<Self>,
 5428    ) -> Task<Result<ProjectTransaction>> {
 5429        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5430            let request = proto::ApplyCodeAction {
 5431                project_id,
 5432                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5433                action: Some(Self::serialize_code_action(&action)),
 5434            };
 5435            let buffer_store = self.buffer_store();
 5436            cx.spawn(async move |_, cx| {
 5437                let response = upstream_client
 5438                    .request(request)
 5439                    .await?
 5440                    .transaction
 5441                    .context("missing transaction")?;
 5442
 5443                buffer_store
 5444                    .update(cx, |buffer_store, cx| {
 5445                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5446                    })
 5447                    .await
 5448            })
 5449        } else if self.mode.is_local() {
 5450            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5451                let request_timeout = ProjectSettings::get_global(cx)
 5452                    .global_lsp_settings
 5453                    .get_request_timeout();
 5454                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5455                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5456            }) else {
 5457                return Task::ready(Ok(ProjectTransaction::default()));
 5458            };
 5459
 5460            cx.spawn(async move |this, cx| {
 5461                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5462                    .await
 5463                    .context("resolving a code action")?;
 5464                if let Some(edit) = action.lsp_action.edit()
 5465                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5466                        return LocalLspStore::deserialize_workspace_edit(
 5467                            this.upgrade().context("no app present")?,
 5468                            edit.clone(),
 5469                            push_to_history,
 5470
 5471                            lang_server.clone(),
 5472                            cx,
 5473                        )
 5474                        .await;
 5475                    }
 5476
 5477                let Some(command) = action.lsp_action.command() else {
 5478                    return Ok(ProjectTransaction::default())
 5479                };
 5480
 5481                let server_capabilities = lang_server.capabilities();
 5482                let available_commands = server_capabilities
 5483                    .execute_command_provider
 5484                    .as_ref()
 5485                    .map(|options| options.commands.as_slice())
 5486                    .unwrap_or_default();
 5487
 5488                if !available_commands.contains(&command.command) {
 5489                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5490                    return Ok(ProjectTransaction::default())
 5491                }
 5492
 5493                let request_timeout = cx.update(|app|
 5494                    ProjectSettings::get_global(app)
 5495                    .global_lsp_settings
 5496                    .get_request_timeout()
 5497                );
 5498
 5499                this.update(cx, |this, _| {
 5500                    this.as_local_mut()
 5501                        .unwrap()
 5502                        .last_workspace_edits_by_language_server
 5503                        .remove(&lang_server.server_id());
 5504                })?;
 5505
 5506                let _result = lang_server
 5507                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5508                        command: command.command.clone(),
 5509                        arguments: command.arguments.clone().unwrap_or_default(),
 5510                        ..lsp::ExecuteCommandParams::default()
 5511                    }, request_timeout)
 5512                    .await.into_response()
 5513                    .context("execute command")?;
 5514
 5515                return this.update(cx, |this, _| {
 5516                    this.as_local_mut()
 5517                        .unwrap()
 5518                        .last_workspace_edits_by_language_server
 5519                        .remove(&lang_server.server_id())
 5520                        .unwrap_or_default()
 5521                });
 5522            })
 5523        } else {
 5524            Task::ready(Err(anyhow!("no upstream client and not local")))
 5525        }
 5526    }
 5527
 5528    pub fn apply_code_action_kind(
 5529        &mut self,
 5530        buffers: HashSet<Entity<Buffer>>,
 5531        kind: CodeActionKind,
 5532        push_to_history: bool,
 5533        cx: &mut Context<Self>,
 5534    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5535        if self.as_local().is_some() {
 5536            cx.spawn(async move |lsp_store, cx| {
 5537                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5538                let result = LocalLspStore::execute_code_action_kind_locally(
 5539                    lsp_store.clone(),
 5540                    buffers,
 5541                    kind,
 5542                    push_to_history,
 5543                    cx,
 5544                )
 5545                .await;
 5546                lsp_store.update(cx, |lsp_store, _| {
 5547                    lsp_store.update_last_formatting_failure(&result);
 5548                })?;
 5549                result
 5550            })
 5551        } else if let Some((client, project_id)) = self.upstream_client() {
 5552            let buffer_store = self.buffer_store();
 5553            cx.spawn(async move |lsp_store, cx| {
 5554                let result = client
 5555                    .request(proto::ApplyCodeActionKind {
 5556                        project_id,
 5557                        kind: kind.as_str().to_owned(),
 5558                        buffer_ids: buffers
 5559                            .iter()
 5560                            .map(|buffer| {
 5561                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5562                            })
 5563                            .collect(),
 5564                    })
 5565                    .await
 5566                    .and_then(|result| result.transaction.context("missing transaction"));
 5567                lsp_store.update(cx, |lsp_store, _| {
 5568                    lsp_store.update_last_formatting_failure(&result);
 5569                })?;
 5570
 5571                let transaction_response = result?;
 5572                buffer_store
 5573                    .update(cx, |buffer_store, cx| {
 5574                        buffer_store.deserialize_project_transaction(
 5575                            transaction_response,
 5576                            push_to_history,
 5577                            cx,
 5578                        )
 5579                    })
 5580                    .await
 5581            })
 5582        } else {
 5583            Task::ready(Ok(ProjectTransaction::default()))
 5584        }
 5585    }
 5586
 5587    pub fn resolved_hint(
 5588        &mut self,
 5589        buffer_id: BufferId,
 5590        id: InlayId,
 5591        cx: &mut Context<Self>,
 5592    ) -> Option<ResolvedHint> {
 5593        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5594
 5595        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5596        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5597        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5598        let (server_id, resolve_data) = match &hint.resolve_state {
 5599            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5600            ResolveState::Resolving => {
 5601                return Some(ResolvedHint::Resolving(
 5602                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5603                ));
 5604            }
 5605            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5606        };
 5607
 5608        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5609        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5610        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5611            id,
 5612            cx.spawn(async move |lsp_store, cx| {
 5613                let resolved_hint = resolve_task.await;
 5614                lsp_store
 5615                    .update(cx, |lsp_store, _| {
 5616                        if let Some(old_inlay_hint) = lsp_store
 5617                            .lsp_data
 5618                            .get_mut(&buffer_id)
 5619                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5620                        {
 5621                            match resolved_hint {
 5622                                Ok(resolved_hint) => {
 5623                                    *old_inlay_hint = resolved_hint;
 5624                                }
 5625                                Err(e) => {
 5626                                    old_inlay_hint.resolve_state =
 5627                                        ResolveState::CanResolve(server_id, resolve_data);
 5628                                    log::error!("Inlay hint resolve failed: {e:#}");
 5629                                }
 5630                            }
 5631                        }
 5632                    })
 5633                    .ok();
 5634            })
 5635            .shared(),
 5636        );
 5637        debug_assert!(
 5638            previous_task.is_none(),
 5639            "Did not change hint's resolve state after spawning its resolve"
 5640        );
 5641        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5642        None
 5643    }
 5644
 5645    pub(crate) fn linked_edits(
 5646        &mut self,
 5647        buffer: &Entity<Buffer>,
 5648        position: Anchor,
 5649        cx: &mut Context<Self>,
 5650    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5651        let snapshot = buffer.read(cx).snapshot();
 5652        let scope = snapshot.language_scope_at(position);
 5653        let Some(server_id) = self
 5654            .as_local()
 5655            .and_then(|local| {
 5656                buffer.update(cx, |buffer, cx| {
 5657                    local
 5658                        .language_servers_for_buffer(buffer, cx)
 5659                        .filter(|(_, server)| {
 5660                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5661                        })
 5662                        .filter(|(adapter, _)| {
 5663                            scope
 5664                                .as_ref()
 5665                                .map(|scope| scope.language_allowed(&adapter.name))
 5666                                .unwrap_or(true)
 5667                        })
 5668                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5669                        .next()
 5670                })
 5671            })
 5672            .or_else(|| {
 5673                self.upstream_client()
 5674                    .is_some()
 5675                    .then_some(LanguageServerToQuery::FirstCapable)
 5676            })
 5677            .filter(|_| {
 5678                maybe!({
 5679                    buffer.read(cx).language_at(position)?;
 5680                    Some(
 5681                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5682                            .linked_edits,
 5683                    )
 5684                }) == Some(true)
 5685            })
 5686        else {
 5687            return Task::ready(Ok(Vec::new()));
 5688        };
 5689
 5690        self.request_lsp(
 5691            buffer.clone(),
 5692            server_id,
 5693            LinkedEditingRange { position },
 5694            cx,
 5695        )
 5696    }
 5697
 5698    fn apply_on_type_formatting(
 5699        &mut self,
 5700        buffer: Entity<Buffer>,
 5701        position: Anchor,
 5702        trigger: String,
 5703        cx: &mut Context<Self>,
 5704    ) -> Task<Result<Option<Transaction>>> {
 5705        if let Some((client, project_id)) = self.upstream_client() {
 5706            if !self.check_if_capable_for_proto_request(
 5707                &buffer,
 5708                |capabilities| {
 5709                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5710                },
 5711                cx,
 5712            ) {
 5713                return Task::ready(Ok(None));
 5714            }
 5715            let request = proto::OnTypeFormatting {
 5716                project_id,
 5717                buffer_id: buffer.read(cx).remote_id().into(),
 5718                position: Some(serialize_anchor(&position)),
 5719                trigger,
 5720                version: serialize_version(&buffer.read(cx).version()),
 5721            };
 5722            cx.background_spawn(async move {
 5723                client
 5724                    .request(request)
 5725                    .await?
 5726                    .transaction
 5727                    .map(language::proto::deserialize_transaction)
 5728                    .transpose()
 5729            })
 5730        } else if let Some(local) = self.as_local_mut() {
 5731            let buffer_id = buffer.read(cx).remote_id();
 5732            local.buffers_being_formatted.insert(buffer_id);
 5733            cx.spawn(async move |this, cx| {
 5734                let _cleanup = defer({
 5735                    let this = this.clone();
 5736                    let mut cx = cx.clone();
 5737                    move || {
 5738                        this.update(&mut cx, |this, _| {
 5739                            if let Some(local) = this.as_local_mut() {
 5740                                local.buffers_being_formatted.remove(&buffer_id);
 5741                            }
 5742                        })
 5743                        .ok();
 5744                    }
 5745                });
 5746
 5747                buffer
 5748                    .update(cx, |buffer, _| {
 5749                        buffer.wait_for_edits(Some(position.timestamp()))
 5750                    })
 5751                    .await?;
 5752                this.update(cx, |this, cx| {
 5753                    let position = position.to_point_utf16(buffer.read(cx));
 5754                    this.on_type_format(buffer, position, trigger, false, cx)
 5755                })?
 5756                .await
 5757            })
 5758        } else {
 5759            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5760        }
 5761    }
 5762
 5763    pub fn on_type_format<T: ToPointUtf16>(
 5764        &mut self,
 5765        buffer: Entity<Buffer>,
 5766        position: T,
 5767        trigger: String,
 5768        push_to_history: bool,
 5769        cx: &mut Context<Self>,
 5770    ) -> Task<Result<Option<Transaction>>> {
 5771        let position = position.to_point_utf16(buffer.read(cx));
 5772        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5773    }
 5774
 5775    fn on_type_format_impl(
 5776        &mut self,
 5777        buffer: Entity<Buffer>,
 5778        position: PointUtf16,
 5779        trigger: String,
 5780        push_to_history: bool,
 5781        cx: &mut Context<Self>,
 5782    ) -> Task<Result<Option<Transaction>>> {
 5783        let options = buffer.update(cx, |buffer, cx| {
 5784            lsp_command::lsp_formatting_options(
 5785                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5786            )
 5787        });
 5788
 5789        cx.spawn(async move |this, cx| {
 5790            if let Some(waiter) =
 5791                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5792            {
 5793                waiter.await?;
 5794            }
 5795            cx.update(|cx| {
 5796                this.update(cx, |this, cx| {
 5797                    this.request_lsp(
 5798                        buffer.clone(),
 5799                        LanguageServerToQuery::FirstCapable,
 5800                        OnTypeFormatting {
 5801                            position,
 5802                            trigger,
 5803                            options,
 5804                            push_to_history,
 5805                        },
 5806                        cx,
 5807                    )
 5808                })
 5809            })?
 5810            .await
 5811        })
 5812    }
 5813
 5814    pub fn definitions(
 5815        &mut self,
 5816        buffer: &Entity<Buffer>,
 5817        position: PointUtf16,
 5818        cx: &mut Context<Self>,
 5819    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5820        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5821            let request = GetDefinitions { position };
 5822            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5823                return Task::ready(Ok(None));
 5824            }
 5825
 5826            let request_timeout = ProjectSettings::get_global(cx)
 5827                .global_lsp_settings
 5828                .get_request_timeout();
 5829
 5830            let request_task = upstream_client.request_lsp(
 5831                project_id,
 5832                None,
 5833                request_timeout,
 5834                cx.background_executor().clone(),
 5835                request.to_proto(project_id, buffer.read(cx)),
 5836            );
 5837            let buffer = buffer.clone();
 5838            cx.spawn(async move |weak_lsp_store, cx| {
 5839                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5840                    return Ok(None);
 5841                };
 5842                let Some(responses) = request_task.await? else {
 5843                    return Ok(None);
 5844                };
 5845                let actions = join_all(responses.payload.into_iter().map(|response| {
 5846                    GetDefinitions { position }.response_from_proto(
 5847                        response.response,
 5848                        lsp_store.clone(),
 5849                        buffer.clone(),
 5850                        cx.clone(),
 5851                    )
 5852                }))
 5853                .await;
 5854
 5855                Ok(Some(
 5856                    actions
 5857                        .into_iter()
 5858                        .collect::<Result<Vec<Vec<_>>>>()?
 5859                        .into_iter()
 5860                        .flatten()
 5861                        .dedup()
 5862                        .collect(),
 5863                ))
 5864            })
 5865        } else {
 5866            let definitions_task = self.request_multiple_lsp_locally(
 5867                buffer,
 5868                Some(position),
 5869                GetDefinitions { position },
 5870                cx,
 5871            );
 5872            cx.background_spawn(async move {
 5873                Ok(Some(
 5874                    definitions_task
 5875                        .await
 5876                        .into_iter()
 5877                        .flat_map(|(_, definitions)| definitions)
 5878                        .dedup()
 5879                        .collect(),
 5880                ))
 5881            })
 5882        }
 5883    }
 5884
 5885    pub fn declarations(
 5886        &mut self,
 5887        buffer: &Entity<Buffer>,
 5888        position: PointUtf16,
 5889        cx: &mut Context<Self>,
 5890    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5891        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5892            let request = GetDeclarations { position };
 5893            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5894                return Task::ready(Ok(None));
 5895            }
 5896            let request_timeout = ProjectSettings::get_global(cx)
 5897                .global_lsp_settings
 5898                .get_request_timeout();
 5899            let request_task = upstream_client.request_lsp(
 5900                project_id,
 5901                None,
 5902                request_timeout,
 5903                cx.background_executor().clone(),
 5904                request.to_proto(project_id, buffer.read(cx)),
 5905            );
 5906            let buffer = buffer.clone();
 5907            cx.spawn(async move |weak_lsp_store, cx| {
 5908                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5909                    return Ok(None);
 5910                };
 5911                let Some(responses) = request_task.await? else {
 5912                    return Ok(None);
 5913                };
 5914                let actions = join_all(responses.payload.into_iter().map(|response| {
 5915                    GetDeclarations { position }.response_from_proto(
 5916                        response.response,
 5917                        lsp_store.clone(),
 5918                        buffer.clone(),
 5919                        cx.clone(),
 5920                    )
 5921                }))
 5922                .await;
 5923
 5924                Ok(Some(
 5925                    actions
 5926                        .into_iter()
 5927                        .collect::<Result<Vec<Vec<_>>>>()?
 5928                        .into_iter()
 5929                        .flatten()
 5930                        .dedup()
 5931                        .collect(),
 5932                ))
 5933            })
 5934        } else {
 5935            let declarations_task = self.request_multiple_lsp_locally(
 5936                buffer,
 5937                Some(position),
 5938                GetDeclarations { position },
 5939                cx,
 5940            );
 5941            cx.background_spawn(async move {
 5942                Ok(Some(
 5943                    declarations_task
 5944                        .await
 5945                        .into_iter()
 5946                        .flat_map(|(_, declarations)| declarations)
 5947                        .dedup()
 5948                        .collect(),
 5949                ))
 5950            })
 5951        }
 5952    }
 5953
 5954    pub fn type_definitions(
 5955        &mut self,
 5956        buffer: &Entity<Buffer>,
 5957        position: PointUtf16,
 5958        cx: &mut Context<Self>,
 5959    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5960        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5961            let request = GetTypeDefinitions { position };
 5962            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5963                return Task::ready(Ok(None));
 5964            }
 5965            let request_timeout = ProjectSettings::get_global(cx)
 5966                .global_lsp_settings
 5967                .get_request_timeout();
 5968            let request_task = upstream_client.request_lsp(
 5969                project_id,
 5970                None,
 5971                request_timeout,
 5972                cx.background_executor().clone(),
 5973                request.to_proto(project_id, buffer.read(cx)),
 5974            );
 5975            let buffer = buffer.clone();
 5976            cx.spawn(async move |weak_lsp_store, cx| {
 5977                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5978                    return Ok(None);
 5979                };
 5980                let Some(responses) = request_task.await? else {
 5981                    return Ok(None);
 5982                };
 5983                let actions = join_all(responses.payload.into_iter().map(|response| {
 5984                    GetTypeDefinitions { position }.response_from_proto(
 5985                        response.response,
 5986                        lsp_store.clone(),
 5987                        buffer.clone(),
 5988                        cx.clone(),
 5989                    )
 5990                }))
 5991                .await;
 5992
 5993                Ok(Some(
 5994                    actions
 5995                        .into_iter()
 5996                        .collect::<Result<Vec<Vec<_>>>>()?
 5997                        .into_iter()
 5998                        .flatten()
 5999                        .dedup()
 6000                        .collect(),
 6001                ))
 6002            })
 6003        } else {
 6004            let type_definitions_task = self.request_multiple_lsp_locally(
 6005                buffer,
 6006                Some(position),
 6007                GetTypeDefinitions { position },
 6008                cx,
 6009            );
 6010            cx.background_spawn(async move {
 6011                Ok(Some(
 6012                    type_definitions_task
 6013                        .await
 6014                        .into_iter()
 6015                        .flat_map(|(_, type_definitions)| type_definitions)
 6016                        .dedup()
 6017                        .collect(),
 6018                ))
 6019            })
 6020        }
 6021    }
 6022
 6023    pub fn implementations(
 6024        &mut self,
 6025        buffer: &Entity<Buffer>,
 6026        position: PointUtf16,
 6027        cx: &mut Context<Self>,
 6028    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6029        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6030            let request = GetImplementations { position };
 6031            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6032                return Task::ready(Ok(None));
 6033            }
 6034
 6035            let request_timeout = ProjectSettings::get_global(cx)
 6036                .global_lsp_settings
 6037                .get_request_timeout();
 6038            let request_task = upstream_client.request_lsp(
 6039                project_id,
 6040                None,
 6041                request_timeout,
 6042                cx.background_executor().clone(),
 6043                request.to_proto(project_id, buffer.read(cx)),
 6044            );
 6045            let buffer = buffer.clone();
 6046            cx.spawn(async move |weak_lsp_store, cx| {
 6047                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6048                    return Ok(None);
 6049                };
 6050                let Some(responses) = request_task.await? else {
 6051                    return Ok(None);
 6052                };
 6053                let actions = join_all(responses.payload.into_iter().map(|response| {
 6054                    GetImplementations { position }.response_from_proto(
 6055                        response.response,
 6056                        lsp_store.clone(),
 6057                        buffer.clone(),
 6058                        cx.clone(),
 6059                    )
 6060                }))
 6061                .await;
 6062
 6063                Ok(Some(
 6064                    actions
 6065                        .into_iter()
 6066                        .collect::<Result<Vec<Vec<_>>>>()?
 6067                        .into_iter()
 6068                        .flatten()
 6069                        .dedup()
 6070                        .collect(),
 6071                ))
 6072            })
 6073        } else {
 6074            let implementations_task = self.request_multiple_lsp_locally(
 6075                buffer,
 6076                Some(position),
 6077                GetImplementations { position },
 6078                cx,
 6079            );
 6080            cx.background_spawn(async move {
 6081                Ok(Some(
 6082                    implementations_task
 6083                        .await
 6084                        .into_iter()
 6085                        .flat_map(|(_, implementations)| implementations)
 6086                        .dedup()
 6087                        .collect(),
 6088                ))
 6089            })
 6090        }
 6091    }
 6092
 6093    pub fn references(
 6094        &mut self,
 6095        buffer: &Entity<Buffer>,
 6096        position: PointUtf16,
 6097        cx: &mut Context<Self>,
 6098    ) -> Task<Result<Option<Vec<Location>>>> {
 6099        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6100            let request = GetReferences { position };
 6101            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6102                return Task::ready(Ok(None));
 6103            }
 6104
 6105            let request_timeout = ProjectSettings::get_global(cx)
 6106                .global_lsp_settings
 6107                .get_request_timeout();
 6108            let request_task = upstream_client.request_lsp(
 6109                project_id,
 6110                None,
 6111                request_timeout,
 6112                cx.background_executor().clone(),
 6113                request.to_proto(project_id, buffer.read(cx)),
 6114            );
 6115            let buffer = buffer.clone();
 6116            cx.spawn(async move |weak_lsp_store, cx| {
 6117                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6118                    return Ok(None);
 6119                };
 6120                let Some(responses) = request_task.await? else {
 6121                    return Ok(None);
 6122                };
 6123
 6124                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6125                    GetReferences { position }.response_from_proto(
 6126                        lsp_response.response,
 6127                        lsp_store.clone(),
 6128                        buffer.clone(),
 6129                        cx.clone(),
 6130                    )
 6131                }))
 6132                .await
 6133                .into_iter()
 6134                .collect::<Result<Vec<Vec<_>>>>()?
 6135                .into_iter()
 6136                .flatten()
 6137                .dedup()
 6138                .collect();
 6139                Ok(Some(locations))
 6140            })
 6141        } else {
 6142            let references_task = self.request_multiple_lsp_locally(
 6143                buffer,
 6144                Some(position),
 6145                GetReferences { position },
 6146                cx,
 6147            );
 6148            cx.background_spawn(async move {
 6149                Ok(Some(
 6150                    references_task
 6151                        .await
 6152                        .into_iter()
 6153                        .flat_map(|(_, references)| references)
 6154                        .dedup()
 6155                        .collect(),
 6156                ))
 6157            })
 6158        }
 6159    }
 6160
 6161    pub fn code_actions(
 6162        &mut self,
 6163        buffer: &Entity<Buffer>,
 6164        range: Range<Anchor>,
 6165        kinds: Option<Vec<CodeActionKind>>,
 6166        cx: &mut Context<Self>,
 6167    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6168        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6169            let request = GetCodeActions {
 6170                range: range.clone(),
 6171                kinds: kinds.clone(),
 6172            };
 6173            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6174                return Task::ready(Ok(None));
 6175            }
 6176            let request_timeout = ProjectSettings::get_global(cx)
 6177                .global_lsp_settings
 6178                .get_request_timeout();
 6179            let request_task = upstream_client.request_lsp(
 6180                project_id,
 6181                None,
 6182                request_timeout,
 6183                cx.background_executor().clone(),
 6184                request.to_proto(project_id, buffer.read(cx)),
 6185            );
 6186            let buffer = buffer.clone();
 6187            cx.spawn(async move |weak_lsp_store, cx| {
 6188                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6189                    return Ok(None);
 6190                };
 6191                let Some(responses) = request_task.await? else {
 6192                    return Ok(None);
 6193                };
 6194                let actions = join_all(responses.payload.into_iter().map(|response| {
 6195                    GetCodeActions {
 6196                        range: range.clone(),
 6197                        kinds: kinds.clone(),
 6198                    }
 6199                    .response_from_proto(
 6200                        response.response,
 6201                        lsp_store.clone(),
 6202                        buffer.clone(),
 6203                        cx.clone(),
 6204                    )
 6205                }))
 6206                .await;
 6207
 6208                Ok(Some(
 6209                    actions
 6210                        .into_iter()
 6211                        .collect::<Result<Vec<Vec<_>>>>()?
 6212                        .into_iter()
 6213                        .flatten()
 6214                        .collect(),
 6215                ))
 6216            })
 6217        } else {
 6218            let all_actions_task = self.request_multiple_lsp_locally(
 6219                buffer,
 6220                Some(range.start),
 6221                GetCodeActions { range, kinds },
 6222                cx,
 6223            );
 6224            cx.background_spawn(async move {
 6225                Ok(Some(
 6226                    all_actions_task
 6227                        .await
 6228                        .into_iter()
 6229                        .flat_map(|(_, actions)| actions)
 6230                        .collect(),
 6231                ))
 6232            })
 6233        }
 6234    }
 6235
 6236    #[inline(never)]
 6237    pub fn completions(
 6238        &self,
 6239        buffer: &Entity<Buffer>,
 6240        position: PointUtf16,
 6241        context: CompletionContext,
 6242        cx: &mut Context<Self>,
 6243    ) -> Task<Result<Vec<CompletionResponse>>> {
 6244        let language_registry = self.languages.clone();
 6245
 6246        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6247            let snapshot = buffer.read(cx).snapshot();
 6248            let offset = position.to_offset(&snapshot);
 6249            let scope = snapshot.language_scope_at(offset);
 6250            let capable_lsps = self.all_capable_for_proto_request(
 6251                buffer,
 6252                |server_name, capabilities| {
 6253                    capabilities.completion_provider.is_some()
 6254                        && scope
 6255                            .as_ref()
 6256                            .map(|scope| scope.language_allowed(server_name))
 6257                            .unwrap_or(true)
 6258                },
 6259                cx,
 6260            );
 6261            if capable_lsps.is_empty() {
 6262                return Task::ready(Ok(Vec::new()));
 6263            }
 6264
 6265            let language = buffer.read(cx).language().cloned();
 6266
 6267            let buffer = buffer.clone();
 6268
 6269            cx.spawn(async move |this, cx| {
 6270                let requests = join_all(
 6271                    capable_lsps
 6272                        .into_iter()
 6273                        .map(|(id, server_name)| {
 6274                            let request = GetCompletions {
 6275                                position,
 6276                                context: context.clone(),
 6277                                server_id: Some(id),
 6278                            };
 6279                            let buffer = buffer.clone();
 6280                            let language = language.clone();
 6281                            let lsp_adapter = language.as_ref().and_then(|language| {
 6282                                let adapters = language_registry.lsp_adapters(&language.name());
 6283                                adapters
 6284                                    .iter()
 6285                                    .find(|adapter| adapter.name() == server_name)
 6286                                    .or_else(|| adapters.first())
 6287                                    .cloned()
 6288                            });
 6289                            let upstream_client = upstream_client.clone();
 6290                            let response = this
 6291                                .update(cx, |this, cx| {
 6292                                    this.send_lsp_proto_request(
 6293                                        buffer,
 6294                                        upstream_client,
 6295                                        project_id,
 6296                                        request,
 6297                                        cx,
 6298                                    )
 6299                                })
 6300                                .log_err();
 6301                            async move {
 6302                                let response = response?.await.log_err()?;
 6303
 6304                                let completions = populate_labels_for_completions(
 6305                                    response.completions,
 6306                                    language,
 6307                                    lsp_adapter,
 6308                                )
 6309                                .await;
 6310
 6311                                Some(CompletionResponse {
 6312                                    completions,
 6313                                    display_options: CompletionDisplayOptions::default(),
 6314                                    is_incomplete: response.is_incomplete,
 6315                                })
 6316                            }
 6317                        })
 6318                        .collect::<Vec<_>>(),
 6319                );
 6320                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6321            })
 6322        } else if let Some(local) = self.as_local() {
 6323            let snapshot = buffer.read(cx).snapshot();
 6324            let offset = position.to_offset(&snapshot);
 6325            let scope = snapshot.language_scope_at(offset);
 6326            let language = snapshot.language().cloned();
 6327            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6328                .completions
 6329                .clone();
 6330            if !completion_settings.lsp {
 6331                return Task::ready(Ok(Vec::new()));
 6332            }
 6333
 6334            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6335                local
 6336                    .language_servers_for_buffer(buffer, cx)
 6337                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6338                    .filter(|(adapter, _)| {
 6339                        scope
 6340                            .as_ref()
 6341                            .map(|scope| scope.language_allowed(&adapter.name))
 6342                            .unwrap_or(true)
 6343                    })
 6344                    .map(|(_, server)| server.server_id())
 6345                    .collect()
 6346            });
 6347
 6348            let buffer = buffer.clone();
 6349            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6350            let lsp_timeout = if lsp_timeout > 0 {
 6351                Some(Duration::from_millis(lsp_timeout))
 6352            } else {
 6353                None
 6354            };
 6355            cx.spawn(async move |this,  cx| {
 6356                let mut tasks = Vec::with_capacity(server_ids.len());
 6357                this.update(cx, |lsp_store, cx| {
 6358                    for server_id in server_ids {
 6359                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6360                        let lsp_timeout = lsp_timeout
 6361                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6362                        let mut timeout = cx.background_spawn(async move {
 6363                            match lsp_timeout {
 6364                                Some(lsp_timeout) => {
 6365                                    lsp_timeout.await;
 6366                                    true
 6367                                },
 6368                                None => false,
 6369                            }
 6370                        }).fuse();
 6371                        let mut lsp_request = lsp_store.request_lsp(
 6372                            buffer.clone(),
 6373                            LanguageServerToQuery::Other(server_id),
 6374                            GetCompletions {
 6375                                position,
 6376                                context: context.clone(),
 6377                                server_id: Some(server_id),
 6378                            },
 6379                            cx,
 6380                        ).fuse();
 6381                        let new_task = cx.background_spawn(async move {
 6382                            select_biased! {
 6383                                response = lsp_request => anyhow::Ok(Some(response?)),
 6384                                timeout_happened = timeout => {
 6385                                    if timeout_happened {
 6386                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6387                                        Ok(None)
 6388                                    } else {
 6389                                        let completions = lsp_request.await?;
 6390                                        Ok(Some(completions))
 6391                                    }
 6392                                },
 6393                            }
 6394                        });
 6395                        tasks.push((lsp_adapter, new_task));
 6396                    }
 6397                })?;
 6398
 6399                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6400                    let completion_response = task.await.ok()??;
 6401                    let completions = populate_labels_for_completions(
 6402                            completion_response.completions,
 6403                            language.clone(),
 6404                            lsp_adapter,
 6405                        )
 6406                        .await;
 6407                    Some(CompletionResponse {
 6408                        completions,
 6409                        display_options: CompletionDisplayOptions::default(),
 6410                        is_incomplete: completion_response.is_incomplete,
 6411                    })
 6412                });
 6413
 6414                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6415
 6416                Ok(responses.into_iter().flatten().collect())
 6417            })
 6418        } else {
 6419            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6420        }
 6421    }
 6422
 6423    pub fn resolve_completions(
 6424        &self,
 6425        buffer: Entity<Buffer>,
 6426        completion_indices: Vec<usize>,
 6427        completions: Rc<RefCell<Box<[Completion]>>>,
 6428        cx: &mut Context<Self>,
 6429    ) -> Task<Result<bool>> {
 6430        let client = self.upstream_client();
 6431        let buffer_id = buffer.read(cx).remote_id();
 6432        let buffer_snapshot = buffer.read(cx).snapshot();
 6433
 6434        if !self.check_if_capable_for_proto_request(
 6435            &buffer,
 6436            GetCompletions::can_resolve_completions,
 6437            cx,
 6438        ) {
 6439            return Task::ready(Ok(false));
 6440        }
 6441        cx.spawn(async move |lsp_store, cx| {
 6442            let request_timeout = cx.update(|app| {
 6443                ProjectSettings::get_global(app)
 6444                    .global_lsp_settings
 6445                    .get_request_timeout()
 6446            });
 6447
 6448            let mut did_resolve = false;
 6449            if let Some((client, project_id)) = client {
 6450                for completion_index in completion_indices {
 6451                    let server_id = {
 6452                        let completion = &completions.borrow()[completion_index];
 6453                        completion.source.server_id()
 6454                    };
 6455                    if let Some(server_id) = server_id {
 6456                        if Self::resolve_completion_remote(
 6457                            project_id,
 6458                            server_id,
 6459                            buffer_id,
 6460                            completions.clone(),
 6461                            completion_index,
 6462                            client.clone(),
 6463                        )
 6464                        .await
 6465                        .log_err()
 6466                        .is_some()
 6467                        {
 6468                            did_resolve = true;
 6469                        }
 6470                    } else {
 6471                        resolve_word_completion(
 6472                            &buffer_snapshot,
 6473                            &mut completions.borrow_mut()[completion_index],
 6474                        );
 6475                    }
 6476                }
 6477            } else {
 6478                for completion_index in completion_indices {
 6479                    let server_id = {
 6480                        let completion = &completions.borrow()[completion_index];
 6481                        completion.source.server_id()
 6482                    };
 6483                    if let Some(server_id) = server_id {
 6484                        let server_and_adapter = lsp_store
 6485                            .read_with(cx, |lsp_store, _| {
 6486                                let server = lsp_store.language_server_for_id(server_id)?;
 6487                                let adapter =
 6488                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6489                                Some((server, adapter))
 6490                            })
 6491                            .ok()
 6492                            .flatten();
 6493                        let Some((server, adapter)) = server_and_adapter else {
 6494                            continue;
 6495                        };
 6496
 6497                        let resolved = Self::resolve_completion_local(
 6498                            server,
 6499                            completions.clone(),
 6500                            completion_index,
 6501                            request_timeout,
 6502                        )
 6503                        .await
 6504                        .log_err()
 6505                        .is_some();
 6506                        if resolved {
 6507                            Self::regenerate_completion_labels(
 6508                                adapter,
 6509                                &buffer_snapshot,
 6510                                completions.clone(),
 6511                                completion_index,
 6512                            )
 6513                            .await
 6514                            .log_err();
 6515                            did_resolve = true;
 6516                        }
 6517                    } else {
 6518                        resolve_word_completion(
 6519                            &buffer_snapshot,
 6520                            &mut completions.borrow_mut()[completion_index],
 6521                        );
 6522                    }
 6523                }
 6524            }
 6525
 6526            Ok(did_resolve)
 6527        })
 6528    }
 6529
 6530    async fn resolve_completion_local(
 6531        server: Arc<lsp::LanguageServer>,
 6532        completions: Rc<RefCell<Box<[Completion]>>>,
 6533        completion_index: usize,
 6534        request_timeout: Duration,
 6535    ) -> Result<()> {
 6536        let server_id = server.server_id();
 6537        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6538            return Ok(());
 6539        }
 6540
 6541        let request = {
 6542            let completion = &completions.borrow()[completion_index];
 6543            match &completion.source {
 6544                CompletionSource::Lsp {
 6545                    lsp_completion,
 6546                    resolved,
 6547                    server_id: completion_server_id,
 6548                    ..
 6549                } => {
 6550                    if *resolved {
 6551                        return Ok(());
 6552                    }
 6553                    anyhow::ensure!(
 6554                        server_id == *completion_server_id,
 6555                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6556                    );
 6557                    server.request::<lsp::request::ResolveCompletionItem>(
 6558                        *lsp_completion.clone(),
 6559                        request_timeout,
 6560                    )
 6561                }
 6562                CompletionSource::BufferWord { .. }
 6563                | CompletionSource::Dap { .. }
 6564                | CompletionSource::Custom => {
 6565                    return Ok(());
 6566                }
 6567            }
 6568        };
 6569        let resolved_completion = request
 6570            .await
 6571            .into_response()
 6572            .context("resolve completion")?;
 6573
 6574        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6575        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6576
 6577        let mut completions = completions.borrow_mut();
 6578        let completion = &mut completions[completion_index];
 6579        if let CompletionSource::Lsp {
 6580            lsp_completion,
 6581            resolved,
 6582            server_id: completion_server_id,
 6583            ..
 6584        } = &mut completion.source
 6585        {
 6586            if *resolved {
 6587                return Ok(());
 6588            }
 6589            anyhow::ensure!(
 6590                server_id == *completion_server_id,
 6591                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6592            );
 6593            **lsp_completion = resolved_completion;
 6594            *resolved = true;
 6595        }
 6596        Ok(())
 6597    }
 6598
 6599    async fn regenerate_completion_labels(
 6600        adapter: Arc<CachedLspAdapter>,
 6601        snapshot: &BufferSnapshot,
 6602        completions: Rc<RefCell<Box<[Completion]>>>,
 6603        completion_index: usize,
 6604    ) -> Result<()> {
 6605        let completion_item = completions.borrow()[completion_index]
 6606            .source
 6607            .lsp_completion(true)
 6608            .map(Cow::into_owned);
 6609        if let Some(lsp_documentation) = completion_item
 6610            .as_ref()
 6611            .and_then(|completion_item| completion_item.documentation.clone())
 6612        {
 6613            let mut completions = completions.borrow_mut();
 6614            let completion = &mut completions[completion_index];
 6615            completion.documentation = Some(lsp_documentation.into());
 6616        } else {
 6617            let mut completions = completions.borrow_mut();
 6618            let completion = &mut completions[completion_index];
 6619            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6620        }
 6621
 6622        let mut new_label = match completion_item {
 6623            Some(completion_item) => {
 6624                // Some language servers always return `detail` lazily via resolve, regardless of
 6625                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6626                // See: https://github.com/yioneko/vtsls/issues/213
 6627                let language = snapshot.language();
 6628                match language {
 6629                    Some(language) => {
 6630                        adapter
 6631                            .labels_for_completions(
 6632                                std::slice::from_ref(&completion_item),
 6633                                language,
 6634                            )
 6635                            .await?
 6636                    }
 6637                    None => Vec::new(),
 6638                }
 6639                .pop()
 6640                .flatten()
 6641                .unwrap_or_else(|| {
 6642                    CodeLabel::fallback_for_completion(
 6643                        &completion_item,
 6644                        language.map(|language| language.as_ref()),
 6645                    )
 6646                })
 6647            }
 6648            None => CodeLabel::plain(
 6649                completions.borrow()[completion_index].new_text.clone(),
 6650                None,
 6651            ),
 6652        };
 6653        ensure_uniform_list_compatible_label(&mut new_label);
 6654
 6655        let mut completions = completions.borrow_mut();
 6656        let completion = &mut completions[completion_index];
 6657        if completion.label.filter_text() == new_label.filter_text() {
 6658            completion.label = new_label;
 6659        } else {
 6660            log::error!(
 6661                "Resolved completion changed display label from {} to {}. \
 6662                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6663                completion.label.text(),
 6664                new_label.text(),
 6665                completion.label.filter_text(),
 6666                new_label.filter_text()
 6667            );
 6668        }
 6669
 6670        Ok(())
 6671    }
 6672
 6673    async fn resolve_completion_remote(
 6674        project_id: u64,
 6675        server_id: LanguageServerId,
 6676        buffer_id: BufferId,
 6677        completions: Rc<RefCell<Box<[Completion]>>>,
 6678        completion_index: usize,
 6679        client: AnyProtoClient,
 6680    ) -> Result<()> {
 6681        let lsp_completion = {
 6682            let completion = &completions.borrow()[completion_index];
 6683            match &completion.source {
 6684                CompletionSource::Lsp {
 6685                    lsp_completion,
 6686                    resolved,
 6687                    server_id: completion_server_id,
 6688                    ..
 6689                } => {
 6690                    anyhow::ensure!(
 6691                        server_id == *completion_server_id,
 6692                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6693                    );
 6694                    if *resolved {
 6695                        return Ok(());
 6696                    }
 6697                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6698                }
 6699                CompletionSource::Custom
 6700                | CompletionSource::Dap { .. }
 6701                | CompletionSource::BufferWord { .. } => {
 6702                    return Ok(());
 6703                }
 6704            }
 6705        };
 6706        let request = proto::ResolveCompletionDocumentation {
 6707            project_id,
 6708            language_server_id: server_id.0 as u64,
 6709            lsp_completion,
 6710            buffer_id: buffer_id.into(),
 6711        };
 6712
 6713        let response = client
 6714            .request(request)
 6715            .await
 6716            .context("completion documentation resolve proto request")?;
 6717        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6718
 6719        let documentation = if response.documentation.is_empty() {
 6720            CompletionDocumentation::Undocumented
 6721        } else if response.documentation_is_markdown {
 6722            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6723        } else if response.documentation.lines().count() <= 1 {
 6724            CompletionDocumentation::SingleLine(response.documentation.into())
 6725        } else {
 6726            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6727        };
 6728
 6729        let mut completions = completions.borrow_mut();
 6730        let completion = &mut completions[completion_index];
 6731        completion.documentation = Some(documentation);
 6732        if let CompletionSource::Lsp {
 6733            insert_range,
 6734            lsp_completion,
 6735            resolved,
 6736            server_id: completion_server_id,
 6737            lsp_defaults: _,
 6738        } = &mut completion.source
 6739        {
 6740            let completion_insert_range = response
 6741                .old_insert_start
 6742                .and_then(deserialize_anchor)
 6743                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6744            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6745
 6746            if *resolved {
 6747                return Ok(());
 6748            }
 6749            anyhow::ensure!(
 6750                server_id == *completion_server_id,
 6751                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6752            );
 6753            **lsp_completion = resolved_lsp_completion;
 6754            *resolved = true;
 6755        }
 6756
 6757        let replace_range = response
 6758            .old_replace_start
 6759            .and_then(deserialize_anchor)
 6760            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6761        if let Some((old_replace_start, old_replace_end)) = replace_range
 6762            && !response.new_text.is_empty()
 6763        {
 6764            completion.new_text = response.new_text;
 6765            completion.replace_range = old_replace_start..old_replace_end;
 6766        }
 6767
 6768        Ok(())
 6769    }
 6770
 6771    pub fn apply_additional_edits_for_completion(
 6772        &self,
 6773        buffer_handle: Entity<Buffer>,
 6774        completions: Rc<RefCell<Box<[Completion]>>>,
 6775        completion_index: usize,
 6776        push_to_history: bool,
 6777        all_commit_ranges: Vec<Range<language::Anchor>>,
 6778        cx: &mut Context<Self>,
 6779    ) -> Task<Result<Option<Transaction>>> {
 6780        if let Some((client, project_id)) = self.upstream_client() {
 6781            let buffer = buffer_handle.read(cx);
 6782            let buffer_id = buffer.remote_id();
 6783            cx.spawn(async move |_, cx| {
 6784                let request = {
 6785                    let completion = completions.borrow()[completion_index].clone();
 6786                    proto::ApplyCompletionAdditionalEdits {
 6787                        project_id,
 6788                        buffer_id: buffer_id.into(),
 6789                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6790                            replace_range: completion.replace_range,
 6791                            new_text: completion.new_text,
 6792                            source: completion.source,
 6793                        })),
 6794                        all_commit_ranges: all_commit_ranges
 6795                            .iter()
 6796                            .cloned()
 6797                            .map(language::proto::serialize_anchor_range)
 6798                            .collect(),
 6799                    }
 6800                };
 6801
 6802                let Some(transaction) = client.request(request).await?.transaction else {
 6803                    return Ok(None);
 6804                };
 6805
 6806                let transaction = language::proto::deserialize_transaction(transaction)?;
 6807                buffer_handle
 6808                    .update(cx, |buffer, _| {
 6809                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6810                    })
 6811                    .await?;
 6812                if push_to_history {
 6813                    buffer_handle.update(cx, |buffer, _| {
 6814                        buffer.push_transaction(transaction.clone(), Instant::now());
 6815                        buffer.finalize_last_transaction();
 6816                    });
 6817                }
 6818                Ok(Some(transaction))
 6819            })
 6820        } else {
 6821            let request_timeout = ProjectSettings::get_global(cx)
 6822                .global_lsp_settings
 6823                .get_request_timeout();
 6824
 6825            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6826                let completion = &completions.borrow()[completion_index];
 6827                let server_id = completion.source.server_id()?;
 6828                Some(
 6829                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6830                        .1
 6831                        .clone(),
 6832                )
 6833            }) else {
 6834                return Task::ready(Ok(None));
 6835            };
 6836
 6837            cx.spawn(async move |this, cx| {
 6838                Self::resolve_completion_local(
 6839                    server.clone(),
 6840                    completions.clone(),
 6841                    completion_index,
 6842                    request_timeout,
 6843                )
 6844                .await
 6845                .context("resolving completion")?;
 6846                let completion = completions.borrow()[completion_index].clone();
 6847                let additional_text_edits = completion
 6848                    .source
 6849                    .lsp_completion(true)
 6850                    .as_ref()
 6851                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6852                if let Some(edits) = additional_text_edits {
 6853                    let edits = this
 6854                        .update(cx, |this, cx| {
 6855                            this.as_local_mut().unwrap().edits_from_lsp(
 6856                                &buffer_handle,
 6857                                edits,
 6858                                server.server_id(),
 6859                                None,
 6860                                cx,
 6861                            )
 6862                        })?
 6863                        .await?;
 6864
 6865                    buffer_handle.update(cx, |buffer, cx| {
 6866                        buffer.finalize_last_transaction();
 6867                        buffer.start_transaction();
 6868
 6869                        for (range, text) in edits {
 6870                            let primary = &completion.replace_range;
 6871
 6872                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6873                            // and the primary completion is just an insertion (empty range), then this is likely
 6874                            // an auto-import scenario and should not be considered overlapping
 6875                            // https://github.com/zed-industries/zed/issues/26136
 6876                            let is_file_start_auto_import = {
 6877                                let snapshot = buffer.snapshot();
 6878                                let primary_start_point = primary.start.to_point(&snapshot);
 6879                                let range_start_point = range.start.to_point(&snapshot);
 6880
 6881                                let result = primary_start_point.row == 0
 6882                                    && primary_start_point.column == 0
 6883                                    && range_start_point.row == 0
 6884                                    && range_start_point.column == 0;
 6885
 6886                                result
 6887                            };
 6888
 6889                            let has_overlap = if is_file_start_auto_import {
 6890                                false
 6891                            } else {
 6892                                all_commit_ranges.iter().any(|commit_range| {
 6893                                    let start_within =
 6894                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6895                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6896                                    let end_within =
 6897                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6898                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6899                                    start_within || end_within
 6900                                })
 6901                            };
 6902
 6903                            //Skip additional edits which overlap with the primary completion edit
 6904                            //https://github.com/zed-industries/zed/pull/1871
 6905                            if !has_overlap {
 6906                                buffer.edit([(range, text)], None, cx);
 6907                            }
 6908                        }
 6909
 6910                        let transaction = if buffer.end_transaction(cx).is_some() {
 6911                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6912                            if !push_to_history {
 6913                                buffer.forget_transaction(transaction.id);
 6914                            }
 6915                            Some(transaction)
 6916                        } else {
 6917                            None
 6918                        };
 6919                        Ok(transaction)
 6920                    })
 6921                } else {
 6922                    Ok(None)
 6923                }
 6924            })
 6925        }
 6926    }
 6927
 6928    pub fn pull_diagnostics(
 6929        &mut self,
 6930        buffer: Entity<Buffer>,
 6931        cx: &mut Context<Self>,
 6932    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6933        let buffer_id = buffer.read(cx).remote_id();
 6934
 6935        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6936            let mut suitable_capabilities = None;
 6937            // Are we capable for proto request?
 6938            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6939                &buffer,
 6940                |capabilities| {
 6941                    if let Some(caps) = &capabilities.diagnostic_provider {
 6942                        suitable_capabilities = Some(caps.clone());
 6943                        true
 6944                    } else {
 6945                        false
 6946                    }
 6947                },
 6948                cx,
 6949            );
 6950            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6951            let Some(dynamic_caps) = suitable_capabilities else {
 6952                return Task::ready(Ok(None));
 6953            };
 6954            assert!(any_server_has_diagnostics_provider);
 6955
 6956            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6957            let request = GetDocumentDiagnostics {
 6958                previous_result_id: None,
 6959                identifier,
 6960                registration_id: None,
 6961            };
 6962            let request_timeout = ProjectSettings::get_global(cx)
 6963                .global_lsp_settings
 6964                .get_request_timeout();
 6965            let request_task = client.request_lsp(
 6966                upstream_project_id,
 6967                None,
 6968                request_timeout,
 6969                cx.background_executor().clone(),
 6970                request.to_proto(upstream_project_id, buffer.read(cx)),
 6971            );
 6972            cx.background_spawn(async move {
 6973                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6974                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6975                // Do not attempt to further process the dummy responses here.
 6976                let _response = request_task.await?;
 6977                Ok(None)
 6978            })
 6979        } else {
 6980            let servers = buffer.update(cx, |buffer, cx| {
 6981                self.running_language_servers_for_local_buffer(buffer, cx)
 6982                    .map(|(_, server)| server.clone())
 6983                    .collect::<Vec<_>>()
 6984            });
 6985
 6986            let pull_diagnostics = servers
 6987                .into_iter()
 6988                .flat_map(|server| {
 6989                    let result = maybe!({
 6990                        let local = self.as_local()?;
 6991                        let server_id = server.server_id();
 6992                        let providers_with_identifiers = local
 6993                            .language_server_dynamic_registrations
 6994                            .get(&server_id)
 6995                            .into_iter()
 6996                            .flat_map(|registrations| registrations.diagnostics.clone())
 6997                            .collect::<Vec<_>>();
 6998                        Some(
 6999                            providers_with_identifiers
 7000                                .into_iter()
 7001                                .map(|(registration_id, dynamic_caps)| {
 7002                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7003                                    let registration_id = registration_id.map(SharedString::from);
 7004                                    let result_id = self.result_id_for_buffer_pull(
 7005                                        server_id,
 7006                                        buffer_id,
 7007                                        &registration_id,
 7008                                        cx,
 7009                                    );
 7010                                    self.request_lsp(
 7011                                        buffer.clone(),
 7012                                        LanguageServerToQuery::Other(server_id),
 7013                                        GetDocumentDiagnostics {
 7014                                            previous_result_id: result_id,
 7015                                            registration_id,
 7016                                            identifier,
 7017                                        },
 7018                                        cx,
 7019                                    )
 7020                                })
 7021                                .collect::<Vec<_>>(),
 7022                        )
 7023                    });
 7024
 7025                    result.unwrap_or_default()
 7026                })
 7027                .collect::<Vec<_>>();
 7028
 7029            cx.background_spawn(async move {
 7030                let mut responses = Vec::new();
 7031                for diagnostics in join_all(pull_diagnostics).await {
 7032                    responses.extend(diagnostics?);
 7033                }
 7034                Ok(Some(responses))
 7035            })
 7036        }
 7037    }
 7038
 7039    pub fn applicable_inlay_chunks(
 7040        &mut self,
 7041        buffer: &Entity<Buffer>,
 7042        ranges: &[Range<text::Anchor>],
 7043        cx: &mut Context<Self>,
 7044    ) -> Vec<Range<BufferRow>> {
 7045        let buffer_snapshot = buffer.read(cx).snapshot();
 7046        let ranges = ranges
 7047            .iter()
 7048            .map(|range| range.to_point(&buffer_snapshot))
 7049            .collect::<Vec<_>>();
 7050
 7051        self.latest_lsp_data(buffer, cx)
 7052            .inlay_hints
 7053            .applicable_chunks(ranges.as_slice())
 7054            .map(|chunk| chunk.row_range())
 7055            .collect()
 7056    }
 7057
 7058    pub fn invalidate_inlay_hints<'a>(
 7059        &'a mut self,
 7060        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7061    ) {
 7062        for buffer_id in for_buffers {
 7063            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7064                lsp_data.inlay_hints.clear();
 7065            }
 7066        }
 7067    }
 7068
 7069    pub fn inlay_hints(
 7070        &mut self,
 7071        invalidate: InvalidationStrategy,
 7072        buffer: Entity<Buffer>,
 7073        ranges: Vec<Range<text::Anchor>>,
 7074        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7075        cx: &mut Context<Self>,
 7076    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7077        let next_hint_id = self.next_hint_id.clone();
 7078        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7079        let query_version = lsp_data.buffer_version.clone();
 7080        let mut lsp_refresh_requested = false;
 7081        let for_server = if let InvalidationStrategy::RefreshRequested {
 7082            server_id,
 7083            request_id,
 7084        } = invalidate
 7085        {
 7086            let invalidated = lsp_data
 7087                .inlay_hints
 7088                .invalidate_for_server_refresh(server_id, request_id);
 7089            lsp_refresh_requested = invalidated;
 7090            Some(server_id)
 7091        } else {
 7092            None
 7093        };
 7094        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7095        let known_chunks = known_chunks
 7096            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7097            .map(|(_, known_chunks)| known_chunks)
 7098            .unwrap_or_default();
 7099
 7100        let buffer_snapshot = buffer.read(cx).snapshot();
 7101        let ranges = ranges
 7102            .iter()
 7103            .map(|range| range.to_point(&buffer_snapshot))
 7104            .collect::<Vec<_>>();
 7105
 7106        let mut hint_fetch_tasks = Vec::new();
 7107        let mut cached_inlay_hints = None;
 7108        let mut ranges_to_query = None;
 7109        let applicable_chunks = existing_inlay_hints
 7110            .applicable_chunks(ranges.as_slice())
 7111            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7112            .collect::<Vec<_>>();
 7113        if applicable_chunks.is_empty() {
 7114            return HashMap::default();
 7115        }
 7116
 7117        for row_chunk in applicable_chunks {
 7118            match (
 7119                existing_inlay_hints
 7120                    .cached_hints(&row_chunk)
 7121                    .filter(|_| !lsp_refresh_requested)
 7122                    .cloned(),
 7123                existing_inlay_hints
 7124                    .fetched_hints(&row_chunk)
 7125                    .as_ref()
 7126                    .filter(|_| !lsp_refresh_requested)
 7127                    .cloned(),
 7128            ) {
 7129                (None, None) => {
 7130                    let chunk_range = row_chunk.anchor_range();
 7131                    ranges_to_query
 7132                        .get_or_insert_with(Vec::new)
 7133                        .push((row_chunk, chunk_range));
 7134                }
 7135                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7136                (Some(cached_hints), None) => {
 7137                    for (server_id, cached_hints) in cached_hints {
 7138                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7139                            cached_inlay_hints
 7140                                .get_or_insert_with(HashMap::default)
 7141                                .entry(row_chunk.row_range())
 7142                                .or_insert_with(HashMap::default)
 7143                                .entry(server_id)
 7144                                .or_insert_with(Vec::new)
 7145                                .extend(cached_hints);
 7146                        }
 7147                    }
 7148                }
 7149                (Some(cached_hints), Some(fetched_hints)) => {
 7150                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7151                    for (server_id, cached_hints) in cached_hints {
 7152                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7153                            cached_inlay_hints
 7154                                .get_or_insert_with(HashMap::default)
 7155                                .entry(row_chunk.row_range())
 7156                                .or_insert_with(HashMap::default)
 7157                                .entry(server_id)
 7158                                .or_insert_with(Vec::new)
 7159                                .extend(cached_hints);
 7160                        }
 7161                    }
 7162                }
 7163            }
 7164        }
 7165
 7166        if hint_fetch_tasks.is_empty()
 7167            && ranges_to_query
 7168                .as_ref()
 7169                .is_none_or(|ranges| ranges.is_empty())
 7170            && let Some(cached_inlay_hints) = cached_inlay_hints
 7171        {
 7172            cached_inlay_hints
 7173                .into_iter()
 7174                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7175                .collect()
 7176        } else {
 7177            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7178                // When a server refresh was requested, other servers' cached hints
 7179                // are unaffected by the refresh and must be included in the result.
 7180                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7181                // removes all visible hints but only adds back the requesting
 7182                // server's new hints, permanently losing other servers' hints.
 7183                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7184                    lsp_data
 7185                        .inlay_hints
 7186                        .cached_hints(&chunk)
 7187                        .cloned()
 7188                        .unwrap_or_default()
 7189                } else {
 7190                    HashMap::default()
 7191                };
 7192
 7193                let next_hint_id = next_hint_id.clone();
 7194                let buffer = buffer.clone();
 7195                let query_version = query_version.clone();
 7196                let new_inlay_hints = cx
 7197                    .spawn(async move |lsp_store, cx| {
 7198                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7199                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7200                        })?;
 7201                        new_fetch_task
 7202                            .await
 7203                            .and_then(|new_hints_by_server| {
 7204                                lsp_store.update(cx, |lsp_store, cx| {
 7205                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7206                                    let update_cache = lsp_data.buffer_version == query_version;
 7207                                    if new_hints_by_server.is_empty() {
 7208                                        if update_cache {
 7209                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7210                                        }
 7211                                        other_servers_cached
 7212                                    } else {
 7213                                        let mut result = other_servers_cached;
 7214                                        for (server_id, new_hints) in new_hints_by_server {
 7215                                            let new_hints = new_hints
 7216                                                .into_iter()
 7217                                                .map(|new_hint| {
 7218                                                    (
 7219                                                        InlayId::Hint(next_hint_id.fetch_add(
 7220                                                            1,
 7221                                                            atomic::Ordering::AcqRel,
 7222                                                        )),
 7223                                                        new_hint,
 7224                                                    )
 7225                                                })
 7226                                                .collect::<Vec<_>>();
 7227                                            if update_cache {
 7228                                                lsp_data.inlay_hints.insert_new_hints(
 7229                                                    chunk,
 7230                                                    server_id,
 7231                                                    new_hints.clone(),
 7232                                                );
 7233                                            }
 7234                                            result.insert(server_id, new_hints);
 7235                                        }
 7236                                        result
 7237                                    }
 7238                                })
 7239                            })
 7240                            .map_err(Arc::new)
 7241                    })
 7242                    .shared();
 7243
 7244                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7245                *fetch_task = Some(new_inlay_hints.clone());
 7246                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7247            }
 7248
 7249            cached_inlay_hints
 7250                .unwrap_or_default()
 7251                .into_iter()
 7252                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7253                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7254                    (
 7255                        chunk.row_range(),
 7256                        cx.spawn(async move |_, _| {
 7257                            hints_fetch.await.map_err(|e| {
 7258                                if e.error_code() != ErrorCode::Internal {
 7259                                    anyhow!(e.error_code())
 7260                                } else {
 7261                                    anyhow!("{e:#}")
 7262                                }
 7263                            })
 7264                        }),
 7265                    )
 7266                }))
 7267                .collect()
 7268        }
 7269    }
 7270
 7271    fn fetch_inlay_hints(
 7272        &mut self,
 7273        for_server: Option<LanguageServerId>,
 7274        buffer: &Entity<Buffer>,
 7275        range: Range<Anchor>,
 7276        cx: &mut Context<Self>,
 7277    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7278        let request = InlayHints {
 7279            range: range.clone(),
 7280        };
 7281        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7282            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7283                return Task::ready(Ok(HashMap::default()));
 7284            }
 7285            let request_timeout = ProjectSettings::get_global(cx)
 7286                .global_lsp_settings
 7287                .get_request_timeout();
 7288            let request_task = upstream_client.request_lsp(
 7289                project_id,
 7290                for_server.map(|id| id.to_proto()),
 7291                request_timeout,
 7292                cx.background_executor().clone(),
 7293                request.to_proto(project_id, buffer.read(cx)),
 7294            );
 7295            let buffer = buffer.clone();
 7296            cx.spawn(async move |weak_lsp_store, cx| {
 7297                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7298                    return Ok(HashMap::default());
 7299                };
 7300                let Some(responses) = request_task.await? else {
 7301                    return Ok(HashMap::default());
 7302                };
 7303
 7304                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7305                    let lsp_store = lsp_store.clone();
 7306                    let buffer = buffer.clone();
 7307                    let cx = cx.clone();
 7308                    let request = request.clone();
 7309                    async move {
 7310                        (
 7311                            LanguageServerId::from_proto(response.server_id),
 7312                            request
 7313                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7314                                .await,
 7315                        )
 7316                    }
 7317                }))
 7318                .await;
 7319
 7320                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7321                let mut has_errors = false;
 7322                let inlay_hints = inlay_hints
 7323                    .into_iter()
 7324                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7325                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7326                        Err(e) => {
 7327                            has_errors = true;
 7328                            log::error!("{e:#}");
 7329                            None
 7330                        }
 7331                    })
 7332                    .map(|(server_id, mut new_hints)| {
 7333                        new_hints.retain(|hint| {
 7334                            hint.position.is_valid(&buffer_snapshot)
 7335                                && range.start.is_valid(&buffer_snapshot)
 7336                                && range.end.is_valid(&buffer_snapshot)
 7337                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7338                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7339                        });
 7340                        (server_id, new_hints)
 7341                    })
 7342                    .collect::<HashMap<_, _>>();
 7343                anyhow::ensure!(
 7344                    !has_errors || !inlay_hints.is_empty(),
 7345                    "Failed to fetch inlay hints"
 7346                );
 7347                Ok(inlay_hints)
 7348            })
 7349        } else {
 7350            let inlay_hints_task = match for_server {
 7351                Some(server_id) => {
 7352                    let server_task = self.request_lsp(
 7353                        buffer.clone(),
 7354                        LanguageServerToQuery::Other(server_id),
 7355                        request,
 7356                        cx,
 7357                    );
 7358                    cx.background_spawn(async move {
 7359                        let mut responses = Vec::new();
 7360                        match server_task.await {
 7361                            Ok(response) => responses.push((server_id, response)),
 7362                            // rust-analyzer likes to error with this when its still loading up
 7363                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7364                            Err(e) => log::error!(
 7365                                "Error handling response for inlay hints request: {e:#}"
 7366                            ),
 7367                        }
 7368                        responses
 7369                    })
 7370                }
 7371                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7372            };
 7373            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7374            cx.background_spawn(async move {
 7375                Ok(inlay_hints_task
 7376                    .await
 7377                    .into_iter()
 7378                    .map(|(server_id, mut new_hints)| {
 7379                        new_hints.retain(|hint| {
 7380                            hint.position.is_valid(&buffer_snapshot)
 7381                                && range.start.is_valid(&buffer_snapshot)
 7382                                && range.end.is_valid(&buffer_snapshot)
 7383                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7384                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7385                        });
 7386                        (server_id, new_hints)
 7387                    })
 7388                    .collect())
 7389            })
 7390        }
 7391    }
 7392
 7393    fn diagnostic_registration_exists(
 7394        &self,
 7395        server_id: LanguageServerId,
 7396        registration_id: &Option<SharedString>,
 7397    ) -> bool {
 7398        let Some(local) = self.as_local() else {
 7399            return false;
 7400        };
 7401        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7402        else {
 7403            return false;
 7404        };
 7405        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7406        registrations.diagnostics.contains_key(&registration_key)
 7407    }
 7408
 7409    pub fn pull_diagnostics_for_buffer(
 7410        &mut self,
 7411        buffer: Entity<Buffer>,
 7412        cx: &mut Context<Self>,
 7413    ) -> Task<anyhow::Result<()>> {
 7414        let diagnostics = self.pull_diagnostics(buffer, cx);
 7415        cx.spawn(async move |lsp_store, cx| {
 7416            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7417                return Ok(());
 7418            };
 7419            lsp_store.update(cx, |lsp_store, cx| {
 7420                if lsp_store.as_local().is_none() {
 7421                    return;
 7422                }
 7423
 7424                let mut unchanged_buffers = HashMap::default();
 7425                let server_diagnostics_updates = diagnostics
 7426                    .into_iter()
 7427                    .filter_map(|diagnostics_set| match diagnostics_set {
 7428                        LspPullDiagnostics::Response {
 7429                            server_id,
 7430                            uri,
 7431                            diagnostics,
 7432                            registration_id,
 7433                        } => Some((server_id, uri, diagnostics, registration_id)),
 7434                        LspPullDiagnostics::Default => None,
 7435                    })
 7436                    .filter(|(server_id, _, _, registration_id)| {
 7437                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7438                    })
 7439                    .fold(
 7440                        HashMap::default(),
 7441                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7442                            let (result_id, diagnostics) = match diagnostics {
 7443                                PulledDiagnostics::Unchanged { result_id } => {
 7444                                    unchanged_buffers
 7445                                        .entry(new_registration_id.clone())
 7446                                        .or_insert_with(HashSet::default)
 7447                                        .insert(uri.clone());
 7448                                    (Some(result_id), Vec::new())
 7449                                }
 7450                                PulledDiagnostics::Changed {
 7451                                    result_id,
 7452                                    diagnostics,
 7453                                } => (result_id, diagnostics),
 7454                            };
 7455                            let disk_based_sources = Cow::Owned(
 7456                                lsp_store
 7457                                    .language_server_adapter_for_id(server_id)
 7458                                    .as_ref()
 7459                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7460                                    .unwrap_or(&[])
 7461                                    .to_vec(),
 7462                            );
 7463                            acc.entry(server_id)
 7464                                .or_insert_with(HashMap::default)
 7465                                .entry(new_registration_id.clone())
 7466                                .or_insert_with(Vec::new)
 7467                                .push(DocumentDiagnosticsUpdate {
 7468                                    server_id,
 7469                                    diagnostics: lsp::PublishDiagnosticsParams {
 7470                                        uri,
 7471                                        diagnostics,
 7472                                        version: None,
 7473                                    },
 7474                                    result_id: result_id.map(SharedString::new),
 7475                                    disk_based_sources,
 7476                                    registration_id: new_registration_id,
 7477                                });
 7478                            acc
 7479                        },
 7480                    );
 7481
 7482                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7483                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7484                        lsp_store
 7485                            .merge_lsp_diagnostics(
 7486                                DiagnosticSourceKind::Pulled,
 7487                                diagnostic_updates,
 7488                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7489                                    DiagnosticSourceKind::Pulled => {
 7490                                        old_diagnostic.registration_id != registration_id
 7491                                            || unchanged_buffers
 7492                                                .get(&old_diagnostic.registration_id)
 7493                                                .is_some_and(|unchanged_buffers| {
 7494                                                    unchanged_buffers.contains(&document_uri)
 7495                                                })
 7496                                    }
 7497                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7498                                        true
 7499                                    }
 7500                                },
 7501                                cx,
 7502                            )
 7503                            .log_err();
 7504                    }
 7505                }
 7506            })
 7507        })
 7508    }
 7509
 7510    pub fn signature_help<T: ToPointUtf16>(
 7511        &mut self,
 7512        buffer: &Entity<Buffer>,
 7513        position: T,
 7514        cx: &mut Context<Self>,
 7515    ) -> Task<Option<Vec<SignatureHelp>>> {
 7516        let position = position.to_point_utf16(buffer.read(cx));
 7517
 7518        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7519            let request = GetSignatureHelp { position };
 7520            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7521                return Task::ready(None);
 7522            }
 7523            let request_timeout = ProjectSettings::get_global(cx)
 7524                .global_lsp_settings
 7525                .get_request_timeout();
 7526            let request_task = client.request_lsp(
 7527                upstream_project_id,
 7528                None,
 7529                request_timeout,
 7530                cx.background_executor().clone(),
 7531                request.to_proto(upstream_project_id, buffer.read(cx)),
 7532            );
 7533            let buffer = buffer.clone();
 7534            cx.spawn(async move |weak_lsp_store, cx| {
 7535                let lsp_store = weak_lsp_store.upgrade()?;
 7536                let signatures = join_all(
 7537                    request_task
 7538                        .await
 7539                        .log_err()
 7540                        .flatten()
 7541                        .map(|response| response.payload)
 7542                        .unwrap_or_default()
 7543                        .into_iter()
 7544                        .map(|response| {
 7545                            let response = GetSignatureHelp { position }.response_from_proto(
 7546                                response.response,
 7547                                lsp_store.clone(),
 7548                                buffer.clone(),
 7549                                cx.clone(),
 7550                            );
 7551                            async move { response.await.log_err().flatten() }
 7552                        }),
 7553                )
 7554                .await
 7555                .into_iter()
 7556                .flatten()
 7557                .collect();
 7558                Some(signatures)
 7559            })
 7560        } else {
 7561            let all_actions_task = self.request_multiple_lsp_locally(
 7562                buffer,
 7563                Some(position),
 7564                GetSignatureHelp { position },
 7565                cx,
 7566            );
 7567            cx.background_spawn(async move {
 7568                Some(
 7569                    all_actions_task
 7570                        .await
 7571                        .into_iter()
 7572                        .flat_map(|(_, actions)| actions)
 7573                        .collect::<Vec<_>>(),
 7574                )
 7575            })
 7576        }
 7577    }
 7578
 7579    pub fn hover(
 7580        &mut self,
 7581        buffer: &Entity<Buffer>,
 7582        position: PointUtf16,
 7583        cx: &mut Context<Self>,
 7584    ) -> Task<Option<Vec<Hover>>> {
 7585        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7586            let request = GetHover { position };
 7587            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7588                return Task::ready(None);
 7589            }
 7590            let request_timeout = ProjectSettings::get_global(cx)
 7591                .global_lsp_settings
 7592                .get_request_timeout();
 7593            let request_task = client.request_lsp(
 7594                upstream_project_id,
 7595                None,
 7596                request_timeout,
 7597                cx.background_executor().clone(),
 7598                request.to_proto(upstream_project_id, buffer.read(cx)),
 7599            );
 7600            let buffer = buffer.clone();
 7601            cx.spawn(async move |weak_lsp_store, cx| {
 7602                let lsp_store = weak_lsp_store.upgrade()?;
 7603                let hovers = join_all(
 7604                    request_task
 7605                        .await
 7606                        .log_err()
 7607                        .flatten()
 7608                        .map(|response| response.payload)
 7609                        .unwrap_or_default()
 7610                        .into_iter()
 7611                        .map(|response| {
 7612                            let response = GetHover { position }.response_from_proto(
 7613                                response.response,
 7614                                lsp_store.clone(),
 7615                                buffer.clone(),
 7616                                cx.clone(),
 7617                            );
 7618                            async move {
 7619                                response
 7620                                    .await
 7621                                    .log_err()
 7622                                    .flatten()
 7623                                    .and_then(remove_empty_hover_blocks)
 7624                            }
 7625                        }),
 7626                )
 7627                .await
 7628                .into_iter()
 7629                .flatten()
 7630                .collect();
 7631                Some(hovers)
 7632            })
 7633        } else {
 7634            let all_actions_task = self.request_multiple_lsp_locally(
 7635                buffer,
 7636                Some(position),
 7637                GetHover { position },
 7638                cx,
 7639            );
 7640            cx.background_spawn(async move {
 7641                Some(
 7642                    all_actions_task
 7643                        .await
 7644                        .into_iter()
 7645                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7646                        .collect::<Vec<Hover>>(),
 7647                )
 7648            })
 7649        }
 7650    }
 7651
 7652    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7653        let language_registry = self.languages.clone();
 7654
 7655        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7656            let request = upstream_client.request(proto::GetProjectSymbols {
 7657                project_id: *project_id,
 7658                query: query.to_string(),
 7659            });
 7660            cx.foreground_executor().spawn(async move {
 7661                let response = request.await?;
 7662                let mut symbols = Vec::new();
 7663                let core_symbols = response
 7664                    .symbols
 7665                    .into_iter()
 7666                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7667                    .collect::<Vec<_>>();
 7668                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7669                    .await;
 7670                Ok(symbols)
 7671            })
 7672        } else if let Some(local) = self.as_local() {
 7673            struct WorkspaceSymbolsResult {
 7674                server_id: LanguageServerId,
 7675                lsp_adapter: Arc<CachedLspAdapter>,
 7676                worktree: WeakEntity<Worktree>,
 7677                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7678            }
 7679
 7680            let mut requests = Vec::new();
 7681            let mut requested_servers = BTreeSet::new();
 7682            let request_timeout = ProjectSettings::get_global(cx)
 7683                .global_lsp_settings
 7684                .get_request_timeout();
 7685
 7686            for (seed, state) in local.language_server_ids.iter() {
 7687                let Some(worktree_handle) = self
 7688                    .worktree_store
 7689                    .read(cx)
 7690                    .worktree_for_id(seed.worktree_id, cx)
 7691                else {
 7692                    continue;
 7693                };
 7694
 7695                let worktree = worktree_handle.read(cx);
 7696                if !worktree.is_visible() {
 7697                    continue;
 7698                }
 7699
 7700                if !requested_servers.insert(state.id) {
 7701                    continue;
 7702                }
 7703
 7704                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7705                    Some(LanguageServerState::Running {
 7706                        adapter, server, ..
 7707                    }) => (adapter.clone(), server),
 7708
 7709                    _ => continue,
 7710                };
 7711
 7712                let supports_workspace_symbol_request =
 7713                    match server.capabilities().workspace_symbol_provider {
 7714                        Some(OneOf::Left(supported)) => supported,
 7715                        Some(OneOf::Right(_)) => true,
 7716                        None => false,
 7717                    };
 7718
 7719                if !supports_workspace_symbol_request {
 7720                    continue;
 7721                }
 7722
 7723                let worktree_handle = worktree_handle.clone();
 7724                let server_id = server.server_id();
 7725                requests.push(
 7726                    server
 7727                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7728                            lsp::WorkspaceSymbolParams {
 7729                                query: query.to_string(),
 7730                                ..Default::default()
 7731                            },
 7732                            request_timeout,
 7733                        )
 7734                        .map(move |response| {
 7735                            let lsp_symbols = response
 7736                                .into_response()
 7737                                .context("workspace symbols request")
 7738                                .log_err()
 7739                                .flatten()
 7740                                .map(|symbol_response| match symbol_response {
 7741                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7742                                        flat_responses
 7743                                            .into_iter()
 7744                                            .map(|lsp_symbol| {
 7745                                                (
 7746                                                    lsp_symbol.name,
 7747                                                    lsp_symbol.kind,
 7748                                                    lsp_symbol.location,
 7749                                                    lsp_symbol.container_name,
 7750                                                )
 7751                                            })
 7752                                            .collect::<Vec<_>>()
 7753                                    }
 7754                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7755                                        nested_responses
 7756                                            .into_iter()
 7757                                            .filter_map(|lsp_symbol| {
 7758                                                let location = match lsp_symbol.location {
 7759                                                    OneOf::Left(location) => location,
 7760                                                    OneOf::Right(_) => {
 7761                                                        log::error!(
 7762                                                            "Unexpected: client capabilities \
 7763                                                            forbid symbol resolutions in \
 7764                                                            workspace.symbol.resolveSupport"
 7765                                                        );
 7766                                                        return None;
 7767                                                    }
 7768                                                };
 7769                                                Some((
 7770                                                    lsp_symbol.name,
 7771                                                    lsp_symbol.kind,
 7772                                                    location,
 7773                                                    lsp_symbol.container_name,
 7774                                                ))
 7775                                            })
 7776                                            .collect::<Vec<_>>()
 7777                                    }
 7778                                })
 7779                                .unwrap_or_default();
 7780
 7781                            WorkspaceSymbolsResult {
 7782                                server_id,
 7783                                lsp_adapter,
 7784                                worktree: worktree_handle.downgrade(),
 7785                                lsp_symbols,
 7786                            }
 7787                        }),
 7788                );
 7789            }
 7790
 7791            cx.spawn(async move |this, cx| {
 7792                let responses = futures::future::join_all(requests).await;
 7793                let this = match this.upgrade() {
 7794                    Some(this) => this,
 7795                    None => return Ok(Vec::new()),
 7796                };
 7797
 7798                let mut symbols = Vec::new();
 7799                for result in responses {
 7800                    let core_symbols = this.update(cx, |this, cx| {
 7801                        result
 7802                            .lsp_symbols
 7803                            .into_iter()
 7804                            .filter_map(
 7805                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7806                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7807                                    let source_worktree = result.worktree.upgrade()?;
 7808                                    let source_worktree_id = source_worktree.read(cx).id();
 7809
 7810                                    let path = if let Some((tree, rel_path)) =
 7811                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7812                                    {
 7813                                        let worktree_id = tree.read(cx).id();
 7814                                        SymbolLocation::InProject(ProjectPath {
 7815                                            worktree_id,
 7816                                            path: rel_path,
 7817                                        })
 7818                                    } else {
 7819                                        SymbolLocation::OutsideProject {
 7820                                            signature: this.symbol_signature(&abs_path),
 7821                                            abs_path: abs_path.into(),
 7822                                        }
 7823                                    };
 7824
 7825                                    Some(CoreSymbol {
 7826                                        source_language_server_id: result.server_id,
 7827                                        language_server_name: result.lsp_adapter.name.clone(),
 7828                                        source_worktree_id,
 7829                                        path,
 7830                                        kind: symbol_kind,
 7831                                        name: collapse_newlines(&symbol_name, ""),
 7832                                        range: range_from_lsp(symbol_location.range),
 7833                                        container_name: container_name
 7834                                            .map(|c| collapse_newlines(&c, "")),
 7835                                    })
 7836                                },
 7837                            )
 7838                            .collect::<Vec<_>>()
 7839                    });
 7840
 7841                    populate_labels_for_symbols(
 7842                        core_symbols,
 7843                        &language_registry,
 7844                        Some(result.lsp_adapter),
 7845                        &mut symbols,
 7846                    )
 7847                    .await;
 7848                }
 7849
 7850                Ok(symbols)
 7851            })
 7852        } else {
 7853            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7854        }
 7855    }
 7856
 7857    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7858        let mut summary = DiagnosticSummary::default();
 7859        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7860            summary.error_count += path_summary.error_count;
 7861            summary.warning_count += path_summary.warning_count;
 7862        }
 7863        summary
 7864    }
 7865
 7866    /// Returns the diagnostic summary for a specific project path.
 7867    pub fn diagnostic_summary_for_path(
 7868        &self,
 7869        project_path: &ProjectPath,
 7870        _: &App,
 7871    ) -> DiagnosticSummary {
 7872        if let Some(summaries) = self
 7873            .diagnostic_summaries
 7874            .get(&project_path.worktree_id)
 7875            .and_then(|map| map.get(&project_path.path))
 7876        {
 7877            let (error_count, warning_count) = summaries.iter().fold(
 7878                (0, 0),
 7879                |(error_count, warning_count), (_language_server_id, summary)| {
 7880                    (
 7881                        error_count + summary.error_count,
 7882                        warning_count + summary.warning_count,
 7883                    )
 7884                },
 7885            );
 7886
 7887            DiagnosticSummary {
 7888                error_count,
 7889                warning_count,
 7890            }
 7891        } else {
 7892            DiagnosticSummary::default()
 7893        }
 7894    }
 7895
 7896    pub fn diagnostic_summaries<'a>(
 7897        &'a self,
 7898        include_ignored: bool,
 7899        cx: &'a App,
 7900    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7901        self.worktree_store
 7902            .read(cx)
 7903            .visible_worktrees(cx)
 7904            .filter_map(|worktree| {
 7905                let worktree = worktree.read(cx);
 7906                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7907            })
 7908            .flat_map(move |(worktree, summaries)| {
 7909                let worktree_id = worktree.id();
 7910                summaries
 7911                    .iter()
 7912                    .filter(move |(path, _)| {
 7913                        include_ignored
 7914                            || worktree
 7915                                .entry_for_path(path.as_ref())
 7916                                .is_some_and(|entry| !entry.is_ignored)
 7917                    })
 7918                    .flat_map(move |(path, summaries)| {
 7919                        summaries.iter().map(move |(server_id, summary)| {
 7920                            (
 7921                                ProjectPath {
 7922                                    worktree_id,
 7923                                    path: path.clone(),
 7924                                },
 7925                                *server_id,
 7926                                *summary,
 7927                            )
 7928                        })
 7929                    })
 7930            })
 7931    }
 7932
 7933    pub fn on_buffer_edited(
 7934        &mut self,
 7935        buffer: Entity<Buffer>,
 7936        cx: &mut Context<Self>,
 7937    ) -> Option<()> {
 7938        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7939            Some(
 7940                self.as_local()?
 7941                    .language_servers_for_buffer(buffer, cx)
 7942                    .map(|i| i.1.clone())
 7943                    .collect(),
 7944            )
 7945        })?;
 7946
 7947        let buffer = buffer.read(cx);
 7948        let file = File::from_dyn(buffer.file())?;
 7949        let abs_path = file.as_local()?.abs_path(cx);
 7950        let uri = lsp::Uri::from_file_path(&abs_path)
 7951            .ok()
 7952            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7953            .log_err()?;
 7954        let next_snapshot = buffer.text_snapshot();
 7955        for language_server in language_servers {
 7956            let language_server = language_server.clone();
 7957
 7958            let buffer_snapshots = self
 7959                .as_local_mut()?
 7960                .buffer_snapshots
 7961                .get_mut(&buffer.remote_id())
 7962                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7963            let previous_snapshot = buffer_snapshots.last()?;
 7964
 7965            let build_incremental_change = || {
 7966                buffer
 7967                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7968                        previous_snapshot.snapshot.version(),
 7969                    )
 7970                    .map(|edit| {
 7971                        let edit_start = edit.new.start.0;
 7972                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7973                        let new_text = next_snapshot
 7974                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7975                            .collect();
 7976                        lsp::TextDocumentContentChangeEvent {
 7977                            range: Some(lsp::Range::new(
 7978                                point_to_lsp(edit_start),
 7979                                point_to_lsp(edit_end),
 7980                            )),
 7981                            range_length: None,
 7982                            text: new_text,
 7983                        }
 7984                    })
 7985                    .collect()
 7986            };
 7987
 7988            let document_sync_kind = language_server
 7989                .capabilities()
 7990                .text_document_sync
 7991                .as_ref()
 7992                .and_then(|sync| match sync {
 7993                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7994                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7995                });
 7996
 7997            let content_changes: Vec<_> = match document_sync_kind {
 7998                Some(lsp::TextDocumentSyncKind::FULL) => {
 7999                    vec![lsp::TextDocumentContentChangeEvent {
 8000                        range: None,
 8001                        range_length: None,
 8002                        text: next_snapshot.text(),
 8003                    }]
 8004                }
 8005                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8006                _ => {
 8007                    #[cfg(any(test, feature = "test-support"))]
 8008                    {
 8009                        build_incremental_change()
 8010                    }
 8011
 8012                    #[cfg(not(any(test, feature = "test-support")))]
 8013                    {
 8014                        continue;
 8015                    }
 8016                }
 8017            };
 8018
 8019            let next_version = previous_snapshot.version + 1;
 8020            buffer_snapshots.push(LspBufferSnapshot {
 8021                version: next_version,
 8022                snapshot: next_snapshot.clone(),
 8023            });
 8024
 8025            language_server
 8026                .notify::<lsp::notification::DidChangeTextDocument>(
 8027                    lsp::DidChangeTextDocumentParams {
 8028                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8029                            uri.clone(),
 8030                            next_version,
 8031                        ),
 8032                        content_changes,
 8033                    },
 8034                )
 8035                .ok();
 8036            self.pull_workspace_diagnostics(language_server.server_id());
 8037        }
 8038
 8039        None
 8040    }
 8041
 8042    pub fn on_buffer_saved(
 8043        &mut self,
 8044        buffer: Entity<Buffer>,
 8045        cx: &mut Context<Self>,
 8046    ) -> Option<()> {
 8047        let file = File::from_dyn(buffer.read(cx).file())?;
 8048        let worktree_id = file.worktree_id(cx);
 8049        let abs_path = file.as_local()?.abs_path(cx);
 8050        let text_document = lsp::TextDocumentIdentifier {
 8051            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8052        };
 8053        let local = self.as_local()?;
 8054
 8055        for server in local.language_servers_for_worktree(worktree_id) {
 8056            if let Some(include_text) = include_text(server.as_ref()) {
 8057                let text = if include_text {
 8058                    Some(buffer.read(cx).text())
 8059                } else {
 8060                    None
 8061                };
 8062                server
 8063                    .notify::<lsp::notification::DidSaveTextDocument>(
 8064                        lsp::DidSaveTextDocumentParams {
 8065                            text_document: text_document.clone(),
 8066                            text,
 8067                        },
 8068                    )
 8069                    .ok();
 8070            }
 8071        }
 8072
 8073        let language_servers = buffer.update(cx, |buffer, cx| {
 8074            local.language_server_ids_for_buffer(buffer, cx)
 8075        });
 8076        for language_server_id in language_servers {
 8077            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8078        }
 8079
 8080        None
 8081    }
 8082
 8083    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8084        maybe!(async move {
 8085            let mut refreshed_servers = HashSet::default();
 8086            let servers = lsp_store
 8087                .update(cx, |lsp_store, cx| {
 8088                    let local = lsp_store.as_local()?;
 8089
 8090                    let servers = local
 8091                        .language_server_ids
 8092                        .iter()
 8093                        .filter_map(|(seed, state)| {
 8094                            let worktree = lsp_store
 8095                                .worktree_store
 8096                                .read(cx)
 8097                                .worktree_for_id(seed.worktree_id, cx);
 8098                            let delegate: Arc<dyn LspAdapterDelegate> =
 8099                                worktree.map(|worktree| {
 8100                                    LocalLspAdapterDelegate::new(
 8101                                        local.languages.clone(),
 8102                                        &local.environment,
 8103                                        cx.weak_entity(),
 8104                                        &worktree,
 8105                                        local.http_client.clone(),
 8106                                        local.fs.clone(),
 8107                                        cx,
 8108                                    )
 8109                                })?;
 8110                            let server_id = state.id;
 8111
 8112                            let states = local.language_servers.get(&server_id)?;
 8113
 8114                            match states {
 8115                                LanguageServerState::Starting { .. } => None,
 8116                                LanguageServerState::Running {
 8117                                    adapter, server, ..
 8118                                } => {
 8119                                    let adapter = adapter.clone();
 8120                                    let server = server.clone();
 8121                                    refreshed_servers.insert(server.name());
 8122                                    let toolchain = seed.toolchain.clone();
 8123                                    Some(cx.spawn(async move |_, cx| {
 8124                                        let settings =
 8125                                            LocalLspStore::workspace_configuration_for_adapter(
 8126                                                adapter.adapter.clone(),
 8127                                                &delegate,
 8128                                                toolchain,
 8129                                                None,
 8130                                                cx,
 8131                                            )
 8132                                            .await
 8133                                            .ok()?;
 8134                                        server
 8135                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8136                                                lsp::DidChangeConfigurationParams { settings },
 8137                                            )
 8138                                            .ok()?;
 8139                                        Some(())
 8140                                    }))
 8141                                }
 8142                            }
 8143                        })
 8144                        .collect::<Vec<_>>();
 8145
 8146                    Some(servers)
 8147                })
 8148                .ok()
 8149                .flatten()?;
 8150
 8151            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8152            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8153            // to stop and unregister its language server wrapper.
 8154            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8155            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8156            let _: Vec<Option<()>> = join_all(servers).await;
 8157
 8158            Some(())
 8159        })
 8160        .await;
 8161    }
 8162
 8163    fn maintain_workspace_config(
 8164        external_refresh_requests: watch::Receiver<()>,
 8165        cx: &mut Context<Self>,
 8166    ) -> Task<Result<()>> {
 8167        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8168        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8169
 8170        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8171            *settings_changed_tx.borrow_mut() = ();
 8172        });
 8173
 8174        let mut joint_future =
 8175            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8176        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8177        // - 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).
 8178        // - 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.
 8179        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8180        // - 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,
 8181        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8182        cx.spawn(async move |this, cx| {
 8183            while let Some(()) = joint_future.next().await {
 8184                this.update(cx, |this, cx| {
 8185                    this.refresh_server_tree(cx);
 8186                })
 8187                .ok();
 8188
 8189                Self::refresh_workspace_configurations(&this, cx).await;
 8190            }
 8191
 8192            drop(settings_observation);
 8193            anyhow::Ok(())
 8194        })
 8195    }
 8196
 8197    pub fn running_language_servers_for_local_buffer<'a>(
 8198        &'a self,
 8199        buffer: &Buffer,
 8200        cx: &mut App,
 8201    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8202        let local = self.as_local();
 8203        let language_server_ids = local
 8204            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8205            .unwrap_or_default();
 8206
 8207        language_server_ids
 8208            .into_iter()
 8209            .filter_map(
 8210                move |server_id| match local?.language_servers.get(&server_id)? {
 8211                    LanguageServerState::Running {
 8212                        adapter, server, ..
 8213                    } => Some((adapter, server)),
 8214                    _ => None,
 8215                },
 8216            )
 8217    }
 8218
 8219    pub fn language_servers_for_local_buffer(
 8220        &self,
 8221        buffer: &Buffer,
 8222        cx: &mut App,
 8223    ) -> Vec<LanguageServerId> {
 8224        let local = self.as_local();
 8225        local
 8226            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8227            .unwrap_or_default()
 8228    }
 8229
 8230    pub fn language_server_for_local_buffer<'a>(
 8231        &'a self,
 8232        buffer: &'a Buffer,
 8233        server_id: LanguageServerId,
 8234        cx: &'a mut App,
 8235    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8236        self.as_local()?
 8237            .language_servers_for_buffer(buffer, cx)
 8238            .find(|(_, s)| s.server_id() == server_id)
 8239    }
 8240
 8241    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8242        self.diagnostic_summaries.remove(&id_to_remove);
 8243        if let Some(local) = self.as_local_mut() {
 8244            let to_remove = local.remove_worktree(id_to_remove, cx);
 8245            for server in to_remove {
 8246                self.language_server_statuses.remove(&server);
 8247            }
 8248        }
 8249    }
 8250
 8251    fn invalidate_diagnostic_summaries_for_removed_entries(
 8252        &mut self,
 8253        worktree_id: WorktreeId,
 8254        changes: &UpdatedEntriesSet,
 8255        cx: &mut Context<Self>,
 8256    ) {
 8257        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8258            return;
 8259        };
 8260
 8261        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8262        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8263        let downstream = self.downstream_client.clone();
 8264
 8265        for (path, _, _) in changes
 8266            .iter()
 8267            .filter(|(_, _, change)| *change == PathChange::Removed)
 8268        {
 8269            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8270                for (server_id, _) in &summaries_by_server_id {
 8271                    cleared_server_ids.insert(*server_id);
 8272                    if let Some((client, project_id)) = &downstream {
 8273                        client
 8274                            .send(proto::UpdateDiagnosticSummary {
 8275                                project_id: *project_id,
 8276                                worktree_id: worktree_id.to_proto(),
 8277                                summary: Some(proto::DiagnosticSummary {
 8278                                    path: path.as_ref().to_proto(),
 8279                                    language_server_id: server_id.0 as u64,
 8280                                    error_count: 0,
 8281                                    warning_count: 0,
 8282                                }),
 8283                                more_summaries: Vec::new(),
 8284                            })
 8285                            .ok();
 8286                    }
 8287                }
 8288                cleared_paths.push(ProjectPath {
 8289                    worktree_id,
 8290                    path: path.clone(),
 8291                });
 8292            }
 8293        }
 8294
 8295        if !cleared_paths.is_empty() {
 8296            for server_id in cleared_server_ids {
 8297                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8298                    server_id,
 8299                    paths: cleared_paths.clone(),
 8300                });
 8301            }
 8302        }
 8303    }
 8304
 8305    pub fn shared(
 8306        &mut self,
 8307        project_id: u64,
 8308        downstream_client: AnyProtoClient,
 8309        _: &mut Context<Self>,
 8310    ) {
 8311        self.downstream_client = Some((downstream_client.clone(), project_id));
 8312
 8313        for (server_id, status) in &self.language_server_statuses {
 8314            if let Some(server) = self.language_server_for_id(*server_id) {
 8315                downstream_client
 8316                    .send(proto::StartLanguageServer {
 8317                        project_id,
 8318                        server: Some(proto::LanguageServer {
 8319                            id: server_id.to_proto(),
 8320                            name: status.name.to_string(),
 8321                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8322                        }),
 8323                        capabilities: serde_json::to_string(&server.capabilities())
 8324                            .expect("serializing server LSP capabilities"),
 8325                    })
 8326                    .log_err();
 8327            }
 8328        }
 8329    }
 8330
 8331    pub fn disconnected_from_host(&mut self) {
 8332        self.downstream_client.take();
 8333    }
 8334
 8335    pub fn disconnected_from_ssh_remote(&mut self) {
 8336        if let LspStoreMode::Remote(RemoteLspStore {
 8337            upstream_client, ..
 8338        }) = &mut self.mode
 8339        {
 8340            upstream_client.take();
 8341        }
 8342    }
 8343
 8344    pub(crate) fn set_language_server_statuses_from_proto(
 8345        &mut self,
 8346        project: WeakEntity<Project>,
 8347        language_servers: Vec<proto::LanguageServer>,
 8348        server_capabilities: Vec<String>,
 8349        cx: &mut Context<Self>,
 8350    ) {
 8351        let lsp_logs = cx
 8352            .try_global::<GlobalLogStore>()
 8353            .map(|lsp_store| lsp_store.0.clone());
 8354
 8355        self.language_server_statuses = language_servers
 8356            .into_iter()
 8357            .zip(server_capabilities)
 8358            .map(|(server, server_capabilities)| {
 8359                let server_id = LanguageServerId(server.id as usize);
 8360                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8361                    self.lsp_server_capabilities
 8362                        .insert(server_id, server_capabilities);
 8363                }
 8364
 8365                let name = LanguageServerName::from_proto(server.name);
 8366                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8367
 8368                if let Some(lsp_logs) = &lsp_logs {
 8369                    lsp_logs.update(cx, |lsp_logs, cx| {
 8370                        lsp_logs.add_language_server(
 8371                            // Only remote clients get their language servers set from proto
 8372                            LanguageServerKind::Remote {
 8373                                project: project.clone(),
 8374                            },
 8375                            server_id,
 8376                            Some(name.clone()),
 8377                            worktree,
 8378                            None,
 8379                            cx,
 8380                        );
 8381                    });
 8382                }
 8383
 8384                (
 8385                    server_id,
 8386                    LanguageServerStatus {
 8387                        name,
 8388                        server_version: None,
 8389                        server_readable_version: None,
 8390                        pending_work: Default::default(),
 8391                        has_pending_diagnostic_updates: false,
 8392                        progress_tokens: Default::default(),
 8393                        worktree,
 8394                        binary: None,
 8395                        configuration: None,
 8396                        workspace_folders: BTreeSet::new(),
 8397                        process_id: None,
 8398                    },
 8399                )
 8400            })
 8401            .collect();
 8402    }
 8403
 8404    #[cfg(feature = "test-support")]
 8405    pub fn update_diagnostic_entries(
 8406        &mut self,
 8407        server_id: LanguageServerId,
 8408        abs_path: PathBuf,
 8409        result_id: Option<SharedString>,
 8410        version: Option<i32>,
 8411        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8412        cx: &mut Context<Self>,
 8413    ) -> anyhow::Result<()> {
 8414        self.merge_diagnostic_entries(
 8415            vec![DocumentDiagnosticsUpdate {
 8416                diagnostics: DocumentDiagnostics {
 8417                    diagnostics,
 8418                    document_abs_path: abs_path,
 8419                    version,
 8420                },
 8421                result_id,
 8422                server_id,
 8423                disk_based_sources: Cow::Borrowed(&[]),
 8424                registration_id: None,
 8425            }],
 8426            |_, _, _| false,
 8427            cx,
 8428        )?;
 8429        Ok(())
 8430    }
 8431
 8432    pub fn merge_diagnostic_entries<'a>(
 8433        &mut self,
 8434        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8435        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8436        cx: &mut Context<Self>,
 8437    ) -> anyhow::Result<()> {
 8438        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8439        let mut updated_diagnostics_paths = HashMap::default();
 8440        for mut update in diagnostic_updates {
 8441            let abs_path = &update.diagnostics.document_abs_path;
 8442            let server_id = update.server_id;
 8443            let Some((worktree, relative_path)) =
 8444                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8445            else {
 8446                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8447                return Ok(());
 8448            };
 8449
 8450            let worktree_id = worktree.read(cx).id();
 8451            let project_path = ProjectPath {
 8452                worktree_id,
 8453                path: relative_path,
 8454            };
 8455
 8456            let document_uri = lsp::Uri::from_file_path(abs_path)
 8457                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8458            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8459                let snapshot = buffer_handle.read(cx).snapshot();
 8460                let buffer = buffer_handle.read(cx);
 8461                let reused_diagnostics = buffer
 8462                    .buffer_diagnostics(Some(server_id))
 8463                    .iter()
 8464                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8465                    .map(|v| {
 8466                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8467                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8468                        DiagnosticEntry {
 8469                            range: start..end,
 8470                            diagnostic: v.diagnostic.clone(),
 8471                        }
 8472                    })
 8473                    .collect::<Vec<_>>();
 8474
 8475                self.as_local_mut()
 8476                    .context("cannot merge diagnostics on a remote LspStore")?
 8477                    .update_buffer_diagnostics(
 8478                        &buffer_handle,
 8479                        server_id,
 8480                        Some(update.registration_id),
 8481                        update.result_id,
 8482                        update.diagnostics.version,
 8483                        update.diagnostics.diagnostics.clone(),
 8484                        reused_diagnostics.clone(),
 8485                        cx,
 8486                    )?;
 8487
 8488                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8489            } else if let Some(local) = self.as_local() {
 8490                let reused_diagnostics = local
 8491                    .diagnostics
 8492                    .get(&worktree_id)
 8493                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8494                    .and_then(|diagnostics_by_server_id| {
 8495                        diagnostics_by_server_id
 8496                            .binary_search_by_key(&server_id, |e| e.0)
 8497                            .ok()
 8498                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8499                    })
 8500                    .into_iter()
 8501                    .flatten()
 8502                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8503
 8504                update
 8505                    .diagnostics
 8506                    .diagnostics
 8507                    .extend(reused_diagnostics.cloned());
 8508            }
 8509
 8510            let updated = worktree.update(cx, |worktree, cx| {
 8511                self.update_worktree_diagnostics(
 8512                    worktree.id(),
 8513                    server_id,
 8514                    project_path.path.clone(),
 8515                    update.diagnostics.diagnostics,
 8516                    cx,
 8517                )
 8518            })?;
 8519            match updated {
 8520                ControlFlow::Continue(new_summary) => {
 8521                    if let Some((project_id, new_summary)) = new_summary {
 8522                        match &mut diagnostics_summary {
 8523                            Some(diagnostics_summary) => {
 8524                                diagnostics_summary
 8525                                    .more_summaries
 8526                                    .push(proto::DiagnosticSummary {
 8527                                        path: project_path.path.as_ref().to_proto(),
 8528                                        language_server_id: server_id.0 as u64,
 8529                                        error_count: new_summary.error_count,
 8530                                        warning_count: new_summary.warning_count,
 8531                                    })
 8532                            }
 8533                            None => {
 8534                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8535                                    project_id,
 8536                                    worktree_id: worktree_id.to_proto(),
 8537                                    summary: Some(proto::DiagnosticSummary {
 8538                                        path: project_path.path.as_ref().to_proto(),
 8539                                        language_server_id: server_id.0 as u64,
 8540                                        error_count: new_summary.error_count,
 8541                                        warning_count: new_summary.warning_count,
 8542                                    }),
 8543                                    more_summaries: Vec::new(),
 8544                                })
 8545                            }
 8546                        }
 8547                    }
 8548                    updated_diagnostics_paths
 8549                        .entry(server_id)
 8550                        .or_insert_with(Vec::new)
 8551                        .push(project_path);
 8552                }
 8553                ControlFlow::Break(()) => {}
 8554            }
 8555        }
 8556
 8557        if let Some((diagnostics_summary, (downstream_client, _))) =
 8558            diagnostics_summary.zip(self.downstream_client.as_ref())
 8559        {
 8560            downstream_client.send(diagnostics_summary).log_err();
 8561        }
 8562        for (server_id, paths) in updated_diagnostics_paths {
 8563            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8564        }
 8565        Ok(())
 8566    }
 8567
 8568    fn update_worktree_diagnostics(
 8569        &mut self,
 8570        worktree_id: WorktreeId,
 8571        server_id: LanguageServerId,
 8572        path_in_worktree: Arc<RelPath>,
 8573        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8574        _: &mut Context<Worktree>,
 8575    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8576        let local = match &mut self.mode {
 8577            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8578            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8579        };
 8580
 8581        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8582        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8583        let summaries_by_server_id = summaries_for_tree
 8584            .entry(path_in_worktree.clone())
 8585            .or_default();
 8586
 8587        let old_summary = summaries_by_server_id
 8588            .remove(&server_id)
 8589            .unwrap_or_default();
 8590
 8591        let new_summary = DiagnosticSummary::new(&diagnostics);
 8592        if diagnostics.is_empty() {
 8593            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8594            {
 8595                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8596                    diagnostics_by_server_id.remove(ix);
 8597                }
 8598                if diagnostics_by_server_id.is_empty() {
 8599                    diagnostics_for_tree.remove(&path_in_worktree);
 8600                }
 8601            }
 8602        } else {
 8603            summaries_by_server_id.insert(server_id, new_summary);
 8604            let diagnostics_by_server_id = diagnostics_for_tree
 8605                .entry(path_in_worktree.clone())
 8606                .or_default();
 8607            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8608                Ok(ix) => {
 8609                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8610                }
 8611                Err(ix) => {
 8612                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8613                }
 8614            }
 8615        }
 8616
 8617        if !old_summary.is_empty() || !new_summary.is_empty() {
 8618            if let Some((_, project_id)) = &self.downstream_client {
 8619                Ok(ControlFlow::Continue(Some((
 8620                    *project_id,
 8621                    proto::DiagnosticSummary {
 8622                        path: path_in_worktree.to_proto(),
 8623                        language_server_id: server_id.0 as u64,
 8624                        error_count: new_summary.error_count as u32,
 8625                        warning_count: new_summary.warning_count as u32,
 8626                    },
 8627                ))))
 8628            } else {
 8629                Ok(ControlFlow::Continue(None))
 8630            }
 8631        } else {
 8632            Ok(ControlFlow::Break(()))
 8633        }
 8634    }
 8635
 8636    pub fn open_buffer_for_symbol(
 8637        &mut self,
 8638        symbol: &Symbol,
 8639        cx: &mut Context<Self>,
 8640    ) -> Task<Result<Entity<Buffer>>> {
 8641        if let Some((client, project_id)) = self.upstream_client() {
 8642            let request = client.request(proto::OpenBufferForSymbol {
 8643                project_id,
 8644                symbol: Some(Self::serialize_symbol(symbol)),
 8645            });
 8646            cx.spawn(async move |this, cx| {
 8647                let response = request.await?;
 8648                let buffer_id = BufferId::new(response.buffer_id)?;
 8649                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8650                    .await
 8651            })
 8652        } else if let Some(local) = self.as_local() {
 8653            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8654                seed.worktree_id == symbol.source_worktree_id
 8655                    && state.id == symbol.source_language_server_id
 8656                    && symbol.language_server_name == seed.name
 8657            });
 8658            if !is_valid {
 8659                return Task::ready(Err(anyhow!(
 8660                    "language server for worktree and language not found"
 8661                )));
 8662            };
 8663
 8664            let symbol_abs_path = match &symbol.path {
 8665                SymbolLocation::InProject(project_path) => self
 8666                    .worktree_store
 8667                    .read(cx)
 8668                    .absolutize(&project_path, cx)
 8669                    .context("no such worktree"),
 8670                SymbolLocation::OutsideProject {
 8671                    abs_path,
 8672                    signature: _,
 8673                } => Ok(abs_path.to_path_buf()),
 8674            };
 8675            let symbol_abs_path = match symbol_abs_path {
 8676                Ok(abs_path) => abs_path,
 8677                Err(err) => return Task::ready(Err(err)),
 8678            };
 8679            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8680                uri
 8681            } else {
 8682                return Task::ready(Err(anyhow!("invalid symbol path")));
 8683            };
 8684
 8685            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8686        } else {
 8687            Task::ready(Err(anyhow!("no upstream client or local store")))
 8688        }
 8689    }
 8690
 8691    pub(crate) fn open_local_buffer_via_lsp(
 8692        &mut self,
 8693        abs_path: lsp::Uri,
 8694        language_server_id: LanguageServerId,
 8695        cx: &mut Context<Self>,
 8696    ) -> Task<Result<Entity<Buffer>>> {
 8697        let path_style = self.worktree_store.read(cx).path_style();
 8698        cx.spawn(async move |lsp_store, cx| {
 8699            // Escape percent-encoded string.
 8700            let current_scheme = abs_path.scheme().to_owned();
 8701            // Uri is immutable, so we can't modify the scheme
 8702
 8703            let abs_path = abs_path
 8704                .to_file_path_ext(path_style)
 8705                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8706            let p = abs_path.clone();
 8707            let yarn_worktree = lsp_store
 8708                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8709                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8710                        cx.spawn(async move |this, cx| {
 8711                            let t = this
 8712                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8713                                .ok()?;
 8714                            t.await
 8715                        })
 8716                    }),
 8717                    None => Task::ready(None),
 8718                })?
 8719                .await;
 8720            let (worktree_root_target, known_relative_path) =
 8721                if let Some((zip_root, relative_path)) = yarn_worktree {
 8722                    (zip_root, Some(relative_path))
 8723                } else {
 8724                    (Arc::<Path>::from(abs_path.as_path()), None)
 8725                };
 8726            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8727                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8728                    worktree_store.find_worktree(&worktree_root_target, cx)
 8729                })
 8730            })?;
 8731            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8732                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8733                (result.0, relative_path, None)
 8734            } else {
 8735                let worktree = lsp_store
 8736                    .update(cx, |lsp_store, cx| {
 8737                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8738                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8739                        })
 8740                    })?
 8741                    .await?;
 8742                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8743                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8744                    lsp_store
 8745                        .update(cx, |lsp_store, cx| {
 8746                            if let Some(local) = lsp_store.as_local_mut() {
 8747                                local.register_language_server_for_invisible_worktree(
 8748                                    &worktree,
 8749                                    language_server_id,
 8750                                    cx,
 8751                                )
 8752                            }
 8753                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8754                                Some(status) => status.worktree,
 8755                                None => None,
 8756                            }
 8757                        })
 8758                        .ok()
 8759                        .flatten()
 8760                        .zip(Some(worktree_root.clone()))
 8761                } else {
 8762                    None
 8763                };
 8764                let relative_path = if let Some(known_path) = known_relative_path {
 8765                    known_path
 8766                } else {
 8767                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8768                        .into_arc()
 8769                };
 8770                (worktree, relative_path, source_ws)
 8771            };
 8772            let project_path = ProjectPath {
 8773                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8774                path: relative_path,
 8775            };
 8776            let buffer = lsp_store
 8777                .update(cx, |lsp_store, cx| {
 8778                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8779                        buffer_store.open_buffer(project_path, cx)
 8780                    })
 8781                })?
 8782                .await?;
 8783            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8784            if let Some((source_ws, worktree_root)) = source_ws {
 8785                buffer.update(cx, |buffer, cx| {
 8786                    let settings = WorktreeSettings::get(
 8787                        Some(
 8788                            (&ProjectPath {
 8789                                worktree_id: source_ws,
 8790                                path: Arc::from(RelPath::empty()),
 8791                            })
 8792                                .into(),
 8793                        ),
 8794                        cx,
 8795                    );
 8796                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8797                    if is_read_only {
 8798                        buffer.set_capability(Capability::ReadOnly, cx);
 8799                    }
 8800                });
 8801            }
 8802            Ok(buffer)
 8803        })
 8804    }
 8805
 8806    fn local_lsp_servers_for_buffer(
 8807        &self,
 8808        buffer: &Entity<Buffer>,
 8809        cx: &mut Context<Self>,
 8810    ) -> Vec<LanguageServerId> {
 8811        let Some(local) = self.as_local() else {
 8812            return Vec::new();
 8813        };
 8814
 8815        let snapshot = buffer.read(cx).snapshot();
 8816
 8817        buffer.update(cx, |buffer, cx| {
 8818            local
 8819                .language_servers_for_buffer(buffer, cx)
 8820                .map(|(_, server)| server.server_id())
 8821                .filter(|server_id| {
 8822                    self.as_local().is_none_or(|local| {
 8823                        local
 8824                            .buffers_opened_in_servers
 8825                            .get(&snapshot.remote_id())
 8826                            .is_some_and(|servers| servers.contains(server_id))
 8827                    })
 8828                })
 8829                .collect()
 8830        })
 8831    }
 8832
 8833    fn request_multiple_lsp_locally<P, R>(
 8834        &mut self,
 8835        buffer: &Entity<Buffer>,
 8836        position: Option<P>,
 8837        request: R,
 8838        cx: &mut Context<Self>,
 8839    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8840    where
 8841        P: ToOffset,
 8842        R: LspCommand + Clone,
 8843        <R::LspRequest as lsp::request::Request>::Result: Send,
 8844        <R::LspRequest as lsp::request::Request>::Params: Send,
 8845    {
 8846        let Some(local) = self.as_local() else {
 8847            return Task::ready(Vec::new());
 8848        };
 8849
 8850        let snapshot = buffer.read(cx).snapshot();
 8851        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8852
 8853        let server_ids = buffer.update(cx, |buffer, cx| {
 8854            local
 8855                .language_servers_for_buffer(buffer, cx)
 8856                .filter(|(adapter, _)| {
 8857                    scope
 8858                        .as_ref()
 8859                        .map(|scope| scope.language_allowed(&adapter.name))
 8860                        .unwrap_or(true)
 8861                })
 8862                .map(|(_, server)| server.server_id())
 8863                .filter(|server_id| {
 8864                    self.as_local().is_none_or(|local| {
 8865                        local
 8866                            .buffers_opened_in_servers
 8867                            .get(&snapshot.remote_id())
 8868                            .is_some_and(|servers| servers.contains(server_id))
 8869                    })
 8870                })
 8871                .collect::<Vec<_>>()
 8872        });
 8873
 8874        let mut response_results = server_ids
 8875            .into_iter()
 8876            .map(|server_id| {
 8877                let task = self.request_lsp(
 8878                    buffer.clone(),
 8879                    LanguageServerToQuery::Other(server_id),
 8880                    request.clone(),
 8881                    cx,
 8882                );
 8883                async move { (server_id, task.await) }
 8884            })
 8885            .collect::<FuturesUnordered<_>>();
 8886
 8887        cx.background_spawn(async move {
 8888            let mut responses = Vec::with_capacity(response_results.len());
 8889            while let Some((server_id, response_result)) = response_results.next().await {
 8890                match response_result {
 8891                    Ok(response) => responses.push((server_id, response)),
 8892                    // rust-analyzer likes to error with this when its still loading up
 8893                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8894                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8895                }
 8896            }
 8897            responses
 8898        })
 8899    }
 8900
 8901    async fn handle_lsp_get_completions(
 8902        this: Entity<Self>,
 8903        envelope: TypedEnvelope<proto::GetCompletions>,
 8904        mut cx: AsyncApp,
 8905    ) -> Result<proto::GetCompletionsResponse> {
 8906        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8907
 8908        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8909        let buffer_handle = this.update(&mut cx, |this, cx| {
 8910            this.buffer_store.read(cx).get_existing(buffer_id)
 8911        })?;
 8912        let request = GetCompletions::from_proto(
 8913            envelope.payload,
 8914            this.clone(),
 8915            buffer_handle.clone(),
 8916            cx.clone(),
 8917        )
 8918        .await?;
 8919
 8920        let server_to_query = match request.server_id {
 8921            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8922            None => LanguageServerToQuery::FirstCapable,
 8923        };
 8924
 8925        let response = this
 8926            .update(&mut cx, |this, cx| {
 8927                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8928            })
 8929            .await?;
 8930        this.update(&mut cx, |this, cx| {
 8931            Ok(GetCompletions::response_to_proto(
 8932                response,
 8933                this,
 8934                sender_id,
 8935                &buffer_handle.read(cx).version(),
 8936                cx,
 8937            ))
 8938        })
 8939    }
 8940
 8941    async fn handle_lsp_command<T: LspCommand>(
 8942        this: Entity<Self>,
 8943        envelope: TypedEnvelope<T::ProtoRequest>,
 8944        mut cx: AsyncApp,
 8945    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8946    where
 8947        <T::LspRequest as lsp::request::Request>::Params: Send,
 8948        <T::LspRequest as lsp::request::Request>::Result: Send,
 8949    {
 8950        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8951        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8952        let buffer_handle = this.update(&mut cx, |this, cx| {
 8953            this.buffer_store.read(cx).get_existing(buffer_id)
 8954        })?;
 8955        let request = T::from_proto(
 8956            envelope.payload,
 8957            this.clone(),
 8958            buffer_handle.clone(),
 8959            cx.clone(),
 8960        )
 8961        .await?;
 8962        let response = this
 8963            .update(&mut cx, |this, cx| {
 8964                this.request_lsp(
 8965                    buffer_handle.clone(),
 8966                    LanguageServerToQuery::FirstCapable,
 8967                    request,
 8968                    cx,
 8969                )
 8970            })
 8971            .await?;
 8972        this.update(&mut cx, |this, cx| {
 8973            Ok(T::response_to_proto(
 8974                response,
 8975                this,
 8976                sender_id,
 8977                &buffer_handle.read(cx).version(),
 8978                cx,
 8979            ))
 8980        })
 8981    }
 8982
 8983    async fn handle_lsp_query(
 8984        lsp_store: Entity<Self>,
 8985        envelope: TypedEnvelope<proto::LspQuery>,
 8986        mut cx: AsyncApp,
 8987    ) -> Result<proto::Ack> {
 8988        use proto::lsp_query::Request;
 8989        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8990        let lsp_query = envelope.payload;
 8991        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8992        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8993        match lsp_query.request.context("invalid LSP query request")? {
 8994            Request::GetReferences(get_references) => {
 8995                let position = get_references.position.clone().and_then(deserialize_anchor);
 8996                Self::query_lsp_locally::<GetReferences>(
 8997                    lsp_store,
 8998                    server_id,
 8999                    sender_id,
 9000                    lsp_request_id,
 9001                    get_references,
 9002                    position,
 9003                    &mut cx,
 9004                )
 9005                .await?;
 9006            }
 9007            Request::GetDocumentColor(get_document_color) => {
 9008                Self::query_lsp_locally::<GetDocumentColor>(
 9009                    lsp_store,
 9010                    server_id,
 9011                    sender_id,
 9012                    lsp_request_id,
 9013                    get_document_color,
 9014                    None,
 9015                    &mut cx,
 9016                )
 9017                .await?;
 9018            }
 9019            Request::GetFoldingRanges(get_folding_ranges) => {
 9020                Self::query_lsp_locally::<GetFoldingRanges>(
 9021                    lsp_store,
 9022                    server_id,
 9023                    sender_id,
 9024                    lsp_request_id,
 9025                    get_folding_ranges,
 9026                    None,
 9027                    &mut cx,
 9028                )
 9029                .await?;
 9030            }
 9031            Request::GetDocumentSymbols(get_document_symbols) => {
 9032                Self::query_lsp_locally::<GetDocumentSymbols>(
 9033                    lsp_store,
 9034                    server_id,
 9035                    sender_id,
 9036                    lsp_request_id,
 9037                    get_document_symbols,
 9038                    None,
 9039                    &mut cx,
 9040                )
 9041                .await?;
 9042            }
 9043            Request::GetHover(get_hover) => {
 9044                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9045                Self::query_lsp_locally::<GetHover>(
 9046                    lsp_store,
 9047                    server_id,
 9048                    sender_id,
 9049                    lsp_request_id,
 9050                    get_hover,
 9051                    position,
 9052                    &mut cx,
 9053                )
 9054                .await?;
 9055            }
 9056            Request::GetCodeActions(get_code_actions) => {
 9057                Self::query_lsp_locally::<GetCodeActions>(
 9058                    lsp_store,
 9059                    server_id,
 9060                    sender_id,
 9061                    lsp_request_id,
 9062                    get_code_actions,
 9063                    None,
 9064                    &mut cx,
 9065                )
 9066                .await?;
 9067            }
 9068            Request::GetSignatureHelp(get_signature_help) => {
 9069                let position = get_signature_help
 9070                    .position
 9071                    .clone()
 9072                    .and_then(deserialize_anchor);
 9073                Self::query_lsp_locally::<GetSignatureHelp>(
 9074                    lsp_store,
 9075                    server_id,
 9076                    sender_id,
 9077                    lsp_request_id,
 9078                    get_signature_help,
 9079                    position,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083            }
 9084            Request::GetCodeLens(get_code_lens) => {
 9085                Self::query_lsp_locally::<GetCodeLens>(
 9086                    lsp_store,
 9087                    server_id,
 9088                    sender_id,
 9089                    lsp_request_id,
 9090                    get_code_lens,
 9091                    None,
 9092                    &mut cx,
 9093                )
 9094                .await?;
 9095            }
 9096            Request::GetDefinition(get_definition) => {
 9097                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9098                Self::query_lsp_locally::<GetDefinitions>(
 9099                    lsp_store,
 9100                    server_id,
 9101                    sender_id,
 9102                    lsp_request_id,
 9103                    get_definition,
 9104                    position,
 9105                    &mut cx,
 9106                )
 9107                .await?;
 9108            }
 9109            Request::GetDeclaration(get_declaration) => {
 9110                let position = get_declaration
 9111                    .position
 9112                    .clone()
 9113                    .and_then(deserialize_anchor);
 9114                Self::query_lsp_locally::<GetDeclarations>(
 9115                    lsp_store,
 9116                    server_id,
 9117                    sender_id,
 9118                    lsp_request_id,
 9119                    get_declaration,
 9120                    position,
 9121                    &mut cx,
 9122                )
 9123                .await?;
 9124            }
 9125            Request::GetTypeDefinition(get_type_definition) => {
 9126                let position = get_type_definition
 9127                    .position
 9128                    .clone()
 9129                    .and_then(deserialize_anchor);
 9130                Self::query_lsp_locally::<GetTypeDefinitions>(
 9131                    lsp_store,
 9132                    server_id,
 9133                    sender_id,
 9134                    lsp_request_id,
 9135                    get_type_definition,
 9136                    position,
 9137                    &mut cx,
 9138                )
 9139                .await?;
 9140            }
 9141            Request::GetImplementation(get_implementation) => {
 9142                let position = get_implementation
 9143                    .position
 9144                    .clone()
 9145                    .and_then(deserialize_anchor);
 9146                Self::query_lsp_locally::<GetImplementations>(
 9147                    lsp_store,
 9148                    server_id,
 9149                    sender_id,
 9150                    lsp_request_id,
 9151                    get_implementation,
 9152                    position,
 9153                    &mut cx,
 9154                )
 9155                .await?;
 9156            }
 9157            Request::InlayHints(inlay_hints) => {
 9158                let query_start = inlay_hints
 9159                    .start
 9160                    .clone()
 9161                    .and_then(deserialize_anchor)
 9162                    .context("invalid inlay hints range start")?;
 9163                let query_end = inlay_hints
 9164                    .end
 9165                    .clone()
 9166                    .and_then(deserialize_anchor)
 9167                    .context("invalid inlay hints range end")?;
 9168                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9169                    &lsp_store,
 9170                    server_id,
 9171                    lsp_request_id,
 9172                    &inlay_hints,
 9173                    query_start..query_end,
 9174                    &mut cx,
 9175                )
 9176                .await
 9177                .context("preparing inlay hints request")?;
 9178                Self::query_lsp_locally::<InlayHints>(
 9179                    lsp_store,
 9180                    server_id,
 9181                    sender_id,
 9182                    lsp_request_id,
 9183                    inlay_hints,
 9184                    None,
 9185                    &mut cx,
 9186                )
 9187                .await
 9188                .context("querying for inlay hints")?
 9189            }
 9190            //////////////////////////////
 9191            // Below are LSP queries that need to fetch more data,
 9192            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9193            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9194                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9195                    &lsp_store,
 9196                    &get_document_diagnostics,
 9197                    &mut cx,
 9198                )
 9199                .await?;
 9200                lsp_store.update(&mut cx, |lsp_store, cx| {
 9201                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9202                    let key = LspKey {
 9203                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9204                        server_queried: server_id,
 9205                    };
 9206                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9207                    ) {
 9208                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9209                            lsp_requests.clear();
 9210                        };
 9211                    }
 9212
 9213                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9214                        lsp_request_id,
 9215                        cx.spawn(async move |lsp_store, cx| {
 9216                            let diagnostics_pull = lsp_store
 9217                                .update(cx, |lsp_store, cx| {
 9218                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9219                                })
 9220                                .ok();
 9221                            if let Some(diagnostics_pull) = diagnostics_pull {
 9222                                match diagnostics_pull.await {
 9223                                    Ok(()) => {}
 9224                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9225                                };
 9226                            }
 9227                        }),
 9228                    );
 9229                });
 9230            }
 9231            Request::SemanticTokens(semantic_tokens) => {
 9232                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9233                    &lsp_store,
 9234                    &semantic_tokens,
 9235                    &mut cx,
 9236                )
 9237                .await?;
 9238                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9239                lsp_store.update(&mut cx, |lsp_store, cx| {
 9240                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9241                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9242                        let key = LspKey {
 9243                            request_type: TypeId::of::<SemanticTokensFull>(),
 9244                            server_queried: server_id,
 9245                        };
 9246                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9247                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9248                                lsp_requests.clear();
 9249                            };
 9250                        }
 9251
 9252                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9253                            lsp_request_id,
 9254                            cx.spawn(async move |lsp_store, cx| {
 9255                                let tokens_fetch = lsp_store
 9256                                    .update(cx, |lsp_store, cx| {
 9257                                        lsp_store
 9258                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9259                                    })
 9260                                    .ok();
 9261                                if let Some(tokens_fetch) = tokens_fetch {
 9262                                    let new_tokens = tokens_fetch.await;
 9263                                    if let Some(new_tokens) = new_tokens {
 9264                                        lsp_store
 9265                                            .update(cx, |lsp_store, cx| {
 9266                                                let response = new_tokens
 9267                                                    .into_iter()
 9268                                                    .map(|(server_id, response)| {
 9269                                                        (
 9270                                                            server_id.to_proto(),
 9271                                                            SemanticTokensFull::response_to_proto(
 9272                                                                response,
 9273                                                                lsp_store,
 9274                                                                sender_id,
 9275                                                                &buffer_version,
 9276                                                                cx,
 9277                                                            ),
 9278                                                        )
 9279                                                    })
 9280                                                    .collect::<HashMap<_, _>>();
 9281                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9282                                                    project_id,
 9283                                                    lsp_request_id,
 9284                                                    response,
 9285                                                ) {
 9286                                                    Ok(()) => {}
 9287                                                    Err(e) => {
 9288                                                        log::error!(
 9289                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9290                                                        )
 9291                                                    }
 9292                                                }
 9293                                            })
 9294                                            .ok();
 9295                                    }
 9296                                }
 9297                            }),
 9298                        );
 9299                    }
 9300                });
 9301            }
 9302        }
 9303        Ok(proto::Ack {})
 9304    }
 9305
 9306    async fn handle_lsp_query_response(
 9307        lsp_store: Entity<Self>,
 9308        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9309        cx: AsyncApp,
 9310    ) -> Result<()> {
 9311        lsp_store.read_with(&cx, |lsp_store, _| {
 9312            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9313                upstream_client.handle_lsp_response(envelope.clone());
 9314            }
 9315        });
 9316        Ok(())
 9317    }
 9318
 9319    async fn handle_apply_code_action(
 9320        this: Entity<Self>,
 9321        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9322        mut cx: AsyncApp,
 9323    ) -> Result<proto::ApplyCodeActionResponse> {
 9324        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9325        let action =
 9326            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9327        let apply_code_action = this.update(&mut cx, |this, cx| {
 9328            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9329            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9330            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9331        })?;
 9332
 9333        let project_transaction = apply_code_action.await?;
 9334        let project_transaction = this.update(&mut cx, |this, cx| {
 9335            this.buffer_store.update(cx, |buffer_store, cx| {
 9336                buffer_store.serialize_project_transaction_for_peer(
 9337                    project_transaction,
 9338                    sender_id,
 9339                    cx,
 9340                )
 9341            })
 9342        });
 9343        Ok(proto::ApplyCodeActionResponse {
 9344            transaction: Some(project_transaction),
 9345        })
 9346    }
 9347
 9348    async fn handle_register_buffer_with_language_servers(
 9349        this: Entity<Self>,
 9350        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9351        mut cx: AsyncApp,
 9352    ) -> Result<proto::Ack> {
 9353        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9354        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9355        this.update(&mut cx, |this, cx| {
 9356            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9357                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9358                    project_id: upstream_project_id,
 9359                    buffer_id: buffer_id.to_proto(),
 9360                    only_servers: envelope.payload.only_servers,
 9361                });
 9362            }
 9363
 9364            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9365                anyhow::bail!("buffer is not open");
 9366            };
 9367
 9368            let handle = this.register_buffer_with_language_servers(
 9369                &buffer,
 9370                envelope
 9371                    .payload
 9372                    .only_servers
 9373                    .into_iter()
 9374                    .filter_map(|selector| {
 9375                        Some(match selector.selector? {
 9376                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9377                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9378                            }
 9379                            proto::language_server_selector::Selector::Name(name) => {
 9380                                LanguageServerSelector::Name(LanguageServerName(
 9381                                    SharedString::from(name),
 9382                                ))
 9383                            }
 9384                        })
 9385                    })
 9386                    .collect(),
 9387                false,
 9388                cx,
 9389            );
 9390            // Pull diagnostics for the buffer even if it was already registered.
 9391            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9392            // but it's unclear if we need it.
 9393            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9394                .detach();
 9395            this.buffer_store().update(cx, |buffer_store, _| {
 9396                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9397            });
 9398
 9399            Ok(())
 9400        })?;
 9401        Ok(proto::Ack {})
 9402    }
 9403
 9404    async fn handle_rename_project_entry(
 9405        this: Entity<Self>,
 9406        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9407        mut cx: AsyncApp,
 9408    ) -> Result<proto::ProjectEntryResponse> {
 9409        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9410        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9411        let new_path =
 9412            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9413
 9414        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9415            .update(&mut cx, |this, cx| {
 9416                let (worktree, entry) = this
 9417                    .worktree_store
 9418                    .read(cx)
 9419                    .worktree_and_entry_for_id(entry_id, cx)?;
 9420                let new_worktree = this
 9421                    .worktree_store
 9422                    .read(cx)
 9423                    .worktree_for_id(new_worktree_id, cx)?;
 9424                Some((
 9425                    this.worktree_store.clone(),
 9426                    worktree,
 9427                    new_worktree,
 9428                    entry.clone(),
 9429                ))
 9430            })
 9431            .context("worktree not found")?;
 9432        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9433            (worktree.absolutize(&old_entry.path), worktree.id())
 9434        });
 9435        let new_abs_path =
 9436            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9437
 9438        let _transaction = Self::will_rename_entry(
 9439            this.downgrade(),
 9440            old_worktree_id,
 9441            &old_abs_path,
 9442            &new_abs_path,
 9443            old_entry.is_dir(),
 9444            cx.clone(),
 9445        )
 9446        .await;
 9447        let response = WorktreeStore::handle_rename_project_entry(
 9448            worktree_store,
 9449            envelope.payload,
 9450            cx.clone(),
 9451        )
 9452        .await;
 9453        this.read_with(&cx, |this, _| {
 9454            this.did_rename_entry(
 9455                old_worktree_id,
 9456                &old_abs_path,
 9457                &new_abs_path,
 9458                old_entry.is_dir(),
 9459            );
 9460        });
 9461        response
 9462    }
 9463
 9464    async fn handle_update_diagnostic_summary(
 9465        this: Entity<Self>,
 9466        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9467        mut cx: AsyncApp,
 9468    ) -> Result<()> {
 9469        this.update(&mut cx, |lsp_store, cx| {
 9470            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9471            let mut updated_diagnostics_paths = HashMap::default();
 9472            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9473            for message_summary in envelope
 9474                .payload
 9475                .summary
 9476                .into_iter()
 9477                .chain(envelope.payload.more_summaries)
 9478            {
 9479                let project_path = ProjectPath {
 9480                    worktree_id,
 9481                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9482                };
 9483                let path = project_path.path.clone();
 9484                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9485                let summary = DiagnosticSummary {
 9486                    error_count: message_summary.error_count as usize,
 9487                    warning_count: message_summary.warning_count as usize,
 9488                };
 9489
 9490                if summary.is_empty() {
 9491                    if let Some(worktree_summaries) =
 9492                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9493                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9494                    {
 9495                        summaries.remove(&server_id);
 9496                        if summaries.is_empty() {
 9497                            worktree_summaries.remove(&path);
 9498                        }
 9499                    }
 9500                } else {
 9501                    lsp_store
 9502                        .diagnostic_summaries
 9503                        .entry(worktree_id)
 9504                        .or_default()
 9505                        .entry(path)
 9506                        .or_default()
 9507                        .insert(server_id, summary);
 9508                }
 9509
 9510                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9511                    match &mut diagnostics_summary {
 9512                        Some(diagnostics_summary) => {
 9513                            diagnostics_summary
 9514                                .more_summaries
 9515                                .push(proto::DiagnosticSummary {
 9516                                    path: project_path.path.as_ref().to_proto(),
 9517                                    language_server_id: server_id.0 as u64,
 9518                                    error_count: summary.error_count as u32,
 9519                                    warning_count: summary.warning_count as u32,
 9520                                })
 9521                        }
 9522                        None => {
 9523                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9524                                project_id: *project_id,
 9525                                worktree_id: worktree_id.to_proto(),
 9526                                summary: Some(proto::DiagnosticSummary {
 9527                                    path: project_path.path.as_ref().to_proto(),
 9528                                    language_server_id: server_id.0 as u64,
 9529                                    error_count: summary.error_count as u32,
 9530                                    warning_count: summary.warning_count as u32,
 9531                                }),
 9532                                more_summaries: Vec::new(),
 9533                            })
 9534                        }
 9535                    }
 9536                }
 9537                updated_diagnostics_paths
 9538                    .entry(server_id)
 9539                    .or_insert_with(Vec::new)
 9540                    .push(project_path);
 9541            }
 9542
 9543            if let Some((diagnostics_summary, (downstream_client, _))) =
 9544                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9545            {
 9546                downstream_client.send(diagnostics_summary).log_err();
 9547            }
 9548            for (server_id, paths) in updated_diagnostics_paths {
 9549                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9550            }
 9551            Ok(())
 9552        })
 9553    }
 9554
 9555    async fn handle_start_language_server(
 9556        lsp_store: Entity<Self>,
 9557        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9558        mut cx: AsyncApp,
 9559    ) -> Result<()> {
 9560        let server = envelope.payload.server.context("invalid server")?;
 9561        let server_capabilities =
 9562            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9563                .with_context(|| {
 9564                    format!(
 9565                        "incorrect server capabilities {}",
 9566                        envelope.payload.capabilities
 9567                    )
 9568                })?;
 9569        lsp_store.update(&mut cx, |lsp_store, cx| {
 9570            let server_id = LanguageServerId(server.id as usize);
 9571            let server_name = LanguageServerName::from_proto(server.name.clone());
 9572            lsp_store
 9573                .lsp_server_capabilities
 9574                .insert(server_id, server_capabilities);
 9575            lsp_store.language_server_statuses.insert(
 9576                server_id,
 9577                LanguageServerStatus {
 9578                    name: server_name.clone(),
 9579                    server_version: None,
 9580                    server_readable_version: None,
 9581                    pending_work: Default::default(),
 9582                    has_pending_diagnostic_updates: false,
 9583                    progress_tokens: Default::default(),
 9584                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9585                    binary: None,
 9586                    configuration: None,
 9587                    workspace_folders: BTreeSet::new(),
 9588                    process_id: None,
 9589                },
 9590            );
 9591            cx.emit(LspStoreEvent::LanguageServerAdded(
 9592                server_id,
 9593                server_name,
 9594                server.worktree_id.map(WorktreeId::from_proto),
 9595            ));
 9596            cx.notify();
 9597        });
 9598        Ok(())
 9599    }
 9600
 9601    async fn handle_update_language_server(
 9602        lsp_store: Entity<Self>,
 9603        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9604        mut cx: AsyncApp,
 9605    ) -> Result<()> {
 9606        lsp_store.update(&mut cx, |lsp_store, cx| {
 9607            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9608
 9609            match envelope.payload.variant.context("invalid variant")? {
 9610                proto::update_language_server::Variant::WorkStart(payload) => {
 9611                    lsp_store.on_lsp_work_start(
 9612                        language_server_id,
 9613                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9614                            .context("invalid progress token value")?,
 9615                        LanguageServerProgress {
 9616                            title: payload.title,
 9617                            is_disk_based_diagnostics_progress: false,
 9618                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9619                            message: payload.message,
 9620                            percentage: payload.percentage.map(|p| p as usize),
 9621                            last_update_at: cx.background_executor().now(),
 9622                        },
 9623                        cx,
 9624                    );
 9625                }
 9626                proto::update_language_server::Variant::WorkProgress(payload) => {
 9627                    lsp_store.on_lsp_work_progress(
 9628                        language_server_id,
 9629                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9630                            .context("invalid progress token value")?,
 9631                        LanguageServerProgress {
 9632                            title: None,
 9633                            is_disk_based_diagnostics_progress: false,
 9634                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9635                            message: payload.message,
 9636                            percentage: payload.percentage.map(|p| p as usize),
 9637                            last_update_at: cx.background_executor().now(),
 9638                        },
 9639                        cx,
 9640                    );
 9641                }
 9642
 9643                proto::update_language_server::Variant::WorkEnd(payload) => {
 9644                    lsp_store.on_lsp_work_end(
 9645                        language_server_id,
 9646                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9647                            .context("invalid progress token value")?,
 9648                        cx,
 9649                    );
 9650                }
 9651
 9652                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9653                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9654                }
 9655
 9656                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9657                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9658                }
 9659
 9660                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9661                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9662                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9663                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9664                        language_server_id,
 9665                        name: envelope
 9666                            .payload
 9667                            .server_name
 9668                            .map(SharedString::new)
 9669                            .map(LanguageServerName),
 9670                        message: non_lsp,
 9671                    });
 9672                }
 9673            }
 9674
 9675            Ok(())
 9676        })
 9677    }
 9678
 9679    async fn handle_language_server_log(
 9680        this: Entity<Self>,
 9681        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9682        mut cx: AsyncApp,
 9683    ) -> Result<()> {
 9684        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9685        let log_type = envelope
 9686            .payload
 9687            .log_type
 9688            .map(LanguageServerLogType::from_proto)
 9689            .context("invalid language server log type")?;
 9690
 9691        let message = envelope.payload.message;
 9692
 9693        this.update(&mut cx, |_, cx| {
 9694            cx.emit(LspStoreEvent::LanguageServerLog(
 9695                language_server_id,
 9696                log_type,
 9697                message,
 9698            ));
 9699        });
 9700        Ok(())
 9701    }
 9702
 9703    async fn handle_lsp_ext_cancel_flycheck(
 9704        lsp_store: Entity<Self>,
 9705        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9706        cx: AsyncApp,
 9707    ) -> Result<proto::Ack> {
 9708        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9709        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9710            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9711                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9712            } else {
 9713                None
 9714            }
 9715        });
 9716        if let Some(task) = task {
 9717            task.context("handling lsp ext cancel flycheck")?;
 9718        }
 9719
 9720        Ok(proto::Ack {})
 9721    }
 9722
 9723    async fn handle_lsp_ext_run_flycheck(
 9724        lsp_store: Entity<Self>,
 9725        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9726        mut cx: AsyncApp,
 9727    ) -> Result<proto::Ack> {
 9728        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9729        lsp_store.update(&mut cx, |lsp_store, cx| {
 9730            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9731                let text_document = if envelope.payload.current_file_only {
 9732                    let buffer_id = envelope
 9733                        .payload
 9734                        .buffer_id
 9735                        .map(|id| BufferId::new(id))
 9736                        .transpose()?;
 9737                    buffer_id
 9738                        .and_then(|buffer_id| {
 9739                            lsp_store
 9740                                .buffer_store()
 9741                                .read(cx)
 9742                                .get(buffer_id)
 9743                                .and_then(|buffer| {
 9744                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9745                                })
 9746                                .map(|path| make_text_document_identifier(&path))
 9747                        })
 9748                        .transpose()?
 9749                } else {
 9750                    None
 9751                };
 9752                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9753                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9754                )?;
 9755            }
 9756            anyhow::Ok(())
 9757        })?;
 9758
 9759        Ok(proto::Ack {})
 9760    }
 9761
 9762    async fn handle_lsp_ext_clear_flycheck(
 9763        lsp_store: Entity<Self>,
 9764        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9765        cx: AsyncApp,
 9766    ) -> Result<proto::Ack> {
 9767        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9768        lsp_store.read_with(&cx, |lsp_store, _| {
 9769            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9770                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9771            } else {
 9772                None
 9773            }
 9774        });
 9775
 9776        Ok(proto::Ack {})
 9777    }
 9778
 9779    pub fn disk_based_diagnostics_started(
 9780        &mut self,
 9781        language_server_id: LanguageServerId,
 9782        cx: &mut Context<Self>,
 9783    ) {
 9784        if let Some(language_server_status) =
 9785            self.language_server_statuses.get_mut(&language_server_id)
 9786        {
 9787            language_server_status.has_pending_diagnostic_updates = true;
 9788        }
 9789
 9790        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9791        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9792            language_server_id,
 9793            name: self
 9794                .language_server_adapter_for_id(language_server_id)
 9795                .map(|adapter| adapter.name()),
 9796            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9797                Default::default(),
 9798            ),
 9799        })
 9800    }
 9801
 9802    pub fn disk_based_diagnostics_finished(
 9803        &mut self,
 9804        language_server_id: LanguageServerId,
 9805        cx: &mut Context<Self>,
 9806    ) {
 9807        if let Some(language_server_status) =
 9808            self.language_server_statuses.get_mut(&language_server_id)
 9809        {
 9810            language_server_status.has_pending_diagnostic_updates = false;
 9811        }
 9812
 9813        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9814        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9815            language_server_id,
 9816            name: self
 9817                .language_server_adapter_for_id(language_server_id)
 9818                .map(|adapter| adapter.name()),
 9819            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9820                Default::default(),
 9821            ),
 9822        })
 9823    }
 9824
 9825    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9826    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9827    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9828    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9829    // the language server might take some time to publish diagnostics.
 9830    fn simulate_disk_based_diagnostics_events_if_needed(
 9831        &mut self,
 9832        language_server_id: LanguageServerId,
 9833        cx: &mut Context<Self>,
 9834    ) {
 9835        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9836
 9837        let Some(LanguageServerState::Running {
 9838            simulate_disk_based_diagnostics_completion,
 9839            adapter,
 9840            ..
 9841        }) = self
 9842            .as_local_mut()
 9843            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9844        else {
 9845            return;
 9846        };
 9847
 9848        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9849            return;
 9850        }
 9851
 9852        let prev_task =
 9853            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9854                cx.background_executor()
 9855                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9856                    .await;
 9857
 9858                this.update(cx, |this, cx| {
 9859                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9860
 9861                    if let Some(LanguageServerState::Running {
 9862                        simulate_disk_based_diagnostics_completion,
 9863                        ..
 9864                    }) = this.as_local_mut().and_then(|local_store| {
 9865                        local_store.language_servers.get_mut(&language_server_id)
 9866                    }) {
 9867                        *simulate_disk_based_diagnostics_completion = None;
 9868                    }
 9869                })
 9870                .ok();
 9871            }));
 9872
 9873        if prev_task.is_none() {
 9874            self.disk_based_diagnostics_started(language_server_id, cx);
 9875        }
 9876    }
 9877
 9878    pub fn language_server_statuses(
 9879        &self,
 9880    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9881        self.language_server_statuses
 9882            .iter()
 9883            .map(|(key, value)| (*key, value))
 9884    }
 9885
 9886    pub(super) fn did_rename_entry(
 9887        &self,
 9888        worktree_id: WorktreeId,
 9889        old_path: &Path,
 9890        new_path: &Path,
 9891        is_dir: bool,
 9892    ) {
 9893        maybe!({
 9894            let local_store = self.as_local()?;
 9895
 9896            let old_uri = lsp::Uri::from_file_path(old_path)
 9897                .ok()
 9898                .map(|uri| uri.to_string())?;
 9899            let new_uri = lsp::Uri::from_file_path(new_path)
 9900                .ok()
 9901                .map(|uri| uri.to_string())?;
 9902
 9903            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9904                let Some(filter) = local_store
 9905                    .language_server_paths_watched_for_rename
 9906                    .get(&language_server.server_id())
 9907                else {
 9908                    continue;
 9909                };
 9910
 9911                if filter.should_send_did_rename(&old_uri, is_dir) {
 9912                    language_server
 9913                        .notify::<DidRenameFiles>(RenameFilesParams {
 9914                            files: vec![FileRename {
 9915                                old_uri: old_uri.clone(),
 9916                                new_uri: new_uri.clone(),
 9917                            }],
 9918                        })
 9919                        .ok();
 9920                }
 9921            }
 9922            Some(())
 9923        });
 9924    }
 9925
 9926    pub(super) fn will_rename_entry(
 9927        this: WeakEntity<Self>,
 9928        worktree_id: WorktreeId,
 9929        old_path: &Path,
 9930        new_path: &Path,
 9931        is_dir: bool,
 9932        cx: AsyncApp,
 9933    ) -> Task<ProjectTransaction> {
 9934        let old_uri = lsp::Uri::from_file_path(old_path)
 9935            .ok()
 9936            .map(|uri| uri.to_string());
 9937        let new_uri = lsp::Uri::from_file_path(new_path)
 9938            .ok()
 9939            .map(|uri| uri.to_string());
 9940        cx.spawn(async move |cx| {
 9941            let mut tasks = vec![];
 9942            this.update(cx, |this, cx| {
 9943                let local_store = this.as_local()?;
 9944                let old_uri = old_uri?;
 9945                let new_uri = new_uri?;
 9946                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9947                    let Some(filter) = local_store
 9948                        .language_server_paths_watched_for_rename
 9949                        .get(&language_server.server_id())
 9950                    else {
 9951                        continue;
 9952                    };
 9953
 9954                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9955                        continue;
 9956                    }
 9957                    let request_timeout = ProjectSettings::get_global(cx)
 9958                        .global_lsp_settings
 9959                        .get_request_timeout();
 9960
 9961                    let apply_edit = cx.spawn({
 9962                        let old_uri = old_uri.clone();
 9963                        let new_uri = new_uri.clone();
 9964                        let language_server = language_server.clone();
 9965                        async move |this, cx| {
 9966                            let edit = language_server
 9967                                .request::<WillRenameFiles>(
 9968                                    RenameFilesParams {
 9969                                        files: vec![FileRename { old_uri, new_uri }],
 9970                                    },
 9971                                    request_timeout,
 9972                                )
 9973                                .await
 9974                                .into_response()
 9975                                .context("will rename files")
 9976                                .log_err()
 9977                                .flatten()?;
 9978
 9979                            LocalLspStore::deserialize_workspace_edit(
 9980                                this.upgrade()?,
 9981                                edit,
 9982                                false,
 9983                                language_server.clone(),
 9984                                cx,
 9985                            )
 9986                            .await
 9987                            .ok()
 9988                        }
 9989                    });
 9990                    tasks.push(apply_edit);
 9991                }
 9992                Some(())
 9993            })
 9994            .ok()
 9995            .flatten();
 9996            let mut merged_transaction = ProjectTransaction::default();
 9997            for task in tasks {
 9998                // Await on tasks sequentially so that the order of application of edits is deterministic
 9999                // (at least with regards to the order of registration of language servers)
10000                if let Some(transaction) = task.await {
10001                    for (buffer, buffer_transaction) in transaction.0 {
10002                        merged_transaction.0.insert(buffer, buffer_transaction);
10003                    }
10004                }
10005            }
10006            merged_transaction
10007        })
10008    }
10009
10010    fn lsp_notify_abs_paths_changed(
10011        &mut self,
10012        server_id: LanguageServerId,
10013        changes: Vec<PathEvent>,
10014    ) {
10015        maybe!({
10016            let server = self.language_server_for_id(server_id)?;
10017            let changes = changes
10018                .into_iter()
10019                .filter_map(|event| {
10020                    let typ = match event.kind? {
10021                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10022                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10023                        PathEventKind::Changed | PathEventKind::Rescan => {
10024                            lsp::FileChangeType::CHANGED
10025                        }
10026                    };
10027                    Some(lsp::FileEvent {
10028                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10029                        typ,
10030                    })
10031                })
10032                .collect::<Vec<_>>();
10033            if !changes.is_empty() {
10034                server
10035                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10036                        lsp::DidChangeWatchedFilesParams { changes },
10037                    )
10038                    .ok();
10039            }
10040            Some(())
10041        });
10042    }
10043
10044    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10045        self.as_local()?.language_server_for_id(id)
10046    }
10047
10048    fn on_lsp_progress(
10049        &mut self,
10050        progress_params: lsp::ProgressParams,
10051        language_server_id: LanguageServerId,
10052        disk_based_diagnostics_progress_token: Option<String>,
10053        cx: &mut Context<Self>,
10054    ) {
10055        match progress_params.value {
10056            lsp::ProgressParamsValue::WorkDone(progress) => {
10057                self.handle_work_done_progress(
10058                    progress,
10059                    language_server_id,
10060                    disk_based_diagnostics_progress_token,
10061                    ProgressToken::from_lsp(progress_params.token),
10062                    cx,
10063                );
10064            }
10065            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10066                let registration_id = match progress_params.token {
10067                    lsp::NumberOrString::Number(_) => None,
10068                    lsp::NumberOrString::String(token) => token
10069                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10070                        .map(|(_, id)| id.to_owned()),
10071                };
10072                if let Some(LanguageServerState::Running {
10073                    workspace_diagnostics_refresh_tasks,
10074                    ..
10075                }) = self
10076                    .as_local_mut()
10077                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10078                    && let Some(workspace_diagnostics) =
10079                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10080                {
10081                    workspace_diagnostics.progress_tx.try_send(()).ok();
10082                    self.apply_workspace_diagnostic_report(
10083                        language_server_id,
10084                        report,
10085                        registration_id.map(SharedString::from),
10086                        cx,
10087                    )
10088                }
10089            }
10090        }
10091    }
10092
10093    fn handle_work_done_progress(
10094        &mut self,
10095        progress: lsp::WorkDoneProgress,
10096        language_server_id: LanguageServerId,
10097        disk_based_diagnostics_progress_token: Option<String>,
10098        token: ProgressToken,
10099        cx: &mut Context<Self>,
10100    ) {
10101        let language_server_status =
10102            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10103                status
10104            } else {
10105                return;
10106            };
10107
10108        if !language_server_status.progress_tokens.contains(&token) {
10109            return;
10110        }
10111
10112        let is_disk_based_diagnostics_progress =
10113            if let (Some(disk_based_token), ProgressToken::String(token)) =
10114                (&disk_based_diagnostics_progress_token, &token)
10115            {
10116                token.starts_with(disk_based_token)
10117            } else {
10118                false
10119            };
10120
10121        match progress {
10122            lsp::WorkDoneProgress::Begin(report) => {
10123                if is_disk_based_diagnostics_progress {
10124                    self.disk_based_diagnostics_started(language_server_id, cx);
10125                }
10126                self.on_lsp_work_start(
10127                    language_server_id,
10128                    token.clone(),
10129                    LanguageServerProgress {
10130                        title: Some(report.title),
10131                        is_disk_based_diagnostics_progress,
10132                        is_cancellable: report.cancellable.unwrap_or(false),
10133                        message: report.message.clone(),
10134                        percentage: report.percentage.map(|p| p as usize),
10135                        last_update_at: cx.background_executor().now(),
10136                    },
10137                    cx,
10138                );
10139            }
10140            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10141                language_server_id,
10142                token,
10143                LanguageServerProgress {
10144                    title: None,
10145                    is_disk_based_diagnostics_progress,
10146                    is_cancellable: report.cancellable.unwrap_or(false),
10147                    message: report.message,
10148                    percentage: report.percentage.map(|p| p as usize),
10149                    last_update_at: cx.background_executor().now(),
10150                },
10151                cx,
10152            ),
10153            lsp::WorkDoneProgress::End(_) => {
10154                language_server_status.progress_tokens.remove(&token);
10155                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10156                if is_disk_based_diagnostics_progress {
10157                    self.disk_based_diagnostics_finished(language_server_id, cx);
10158                }
10159            }
10160        }
10161    }
10162
10163    fn on_lsp_work_start(
10164        &mut self,
10165        language_server_id: LanguageServerId,
10166        token: ProgressToken,
10167        progress: LanguageServerProgress,
10168        cx: &mut Context<Self>,
10169    ) {
10170        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10171            status.pending_work.insert(token.clone(), progress.clone());
10172            cx.notify();
10173        }
10174        cx.emit(LspStoreEvent::LanguageServerUpdate {
10175            language_server_id,
10176            name: self
10177                .language_server_adapter_for_id(language_server_id)
10178                .map(|adapter| adapter.name()),
10179            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10180                token: Some(token.to_proto()),
10181                title: progress.title,
10182                message: progress.message,
10183                percentage: progress.percentage.map(|p| p as u32),
10184                is_cancellable: Some(progress.is_cancellable),
10185            }),
10186        })
10187    }
10188
10189    fn on_lsp_work_progress(
10190        &mut self,
10191        language_server_id: LanguageServerId,
10192        token: ProgressToken,
10193        progress: LanguageServerProgress,
10194        cx: &mut Context<Self>,
10195    ) {
10196        let mut did_update = false;
10197        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10198            match status.pending_work.entry(token.clone()) {
10199                btree_map::Entry::Vacant(entry) => {
10200                    entry.insert(progress.clone());
10201                    did_update = true;
10202                }
10203                btree_map::Entry::Occupied(mut entry) => {
10204                    let entry = entry.get_mut();
10205                    if (progress.last_update_at - entry.last_update_at)
10206                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10207                    {
10208                        entry.last_update_at = progress.last_update_at;
10209                        if progress.message.is_some() {
10210                            entry.message = progress.message.clone();
10211                        }
10212                        if progress.percentage.is_some() {
10213                            entry.percentage = progress.percentage;
10214                        }
10215                        if progress.is_cancellable != entry.is_cancellable {
10216                            entry.is_cancellable = progress.is_cancellable;
10217                        }
10218                        did_update = true;
10219                    }
10220                }
10221            }
10222        }
10223
10224        if did_update {
10225            cx.emit(LspStoreEvent::LanguageServerUpdate {
10226                language_server_id,
10227                name: self
10228                    .language_server_adapter_for_id(language_server_id)
10229                    .map(|adapter| adapter.name()),
10230                message: proto::update_language_server::Variant::WorkProgress(
10231                    proto::LspWorkProgress {
10232                        token: Some(token.to_proto()),
10233                        message: progress.message,
10234                        percentage: progress.percentage.map(|p| p as u32),
10235                        is_cancellable: Some(progress.is_cancellable),
10236                    },
10237                ),
10238            })
10239        }
10240    }
10241
10242    fn on_lsp_work_end(
10243        &mut self,
10244        language_server_id: LanguageServerId,
10245        token: ProgressToken,
10246        cx: &mut Context<Self>,
10247    ) {
10248        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10249            if let Some(work) = status.pending_work.remove(&token)
10250                && !work.is_disk_based_diagnostics_progress
10251            {
10252                cx.emit(LspStoreEvent::RefreshInlayHints {
10253                    server_id: language_server_id,
10254                    request_id: None,
10255                });
10256            }
10257            cx.notify();
10258        }
10259
10260        cx.emit(LspStoreEvent::LanguageServerUpdate {
10261            language_server_id,
10262            name: self
10263                .language_server_adapter_for_id(language_server_id)
10264                .map(|adapter| adapter.name()),
10265            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10266                token: Some(token.to_proto()),
10267            }),
10268        })
10269    }
10270
10271    pub async fn handle_resolve_completion_documentation(
10272        this: Entity<Self>,
10273        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10274        mut cx: AsyncApp,
10275    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10276        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10277
10278        let completion = this
10279            .read_with(&cx, |this, cx| {
10280                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10281                let server = this
10282                    .language_server_for_id(id)
10283                    .with_context(|| format!("No language server {id}"))?;
10284
10285                let request_timeout = ProjectSettings::get_global(cx)
10286                    .global_lsp_settings
10287                    .get_request_timeout();
10288
10289                anyhow::Ok(cx.background_spawn(async move {
10290                    let can_resolve = server
10291                        .capabilities()
10292                        .completion_provider
10293                        .as_ref()
10294                        .and_then(|options| options.resolve_provider)
10295                        .unwrap_or(false);
10296                    if can_resolve {
10297                        server
10298                            .request::<lsp::request::ResolveCompletionItem>(
10299                                lsp_completion,
10300                                request_timeout,
10301                            )
10302                            .await
10303                            .into_response()
10304                            .context("resolve completion item")
10305                    } else {
10306                        anyhow::Ok(lsp_completion)
10307                    }
10308                }))
10309            })?
10310            .await?;
10311
10312        let mut documentation_is_markdown = false;
10313        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10314        let documentation = match completion.documentation {
10315            Some(lsp::Documentation::String(text)) => text,
10316
10317            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10318                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10319                value
10320            }
10321
10322            _ => String::new(),
10323        };
10324
10325        // If we have a new buffer_id, that means we're talking to a new client
10326        // and want to check for new text_edits in the completion too.
10327        let mut old_replace_start = None;
10328        let mut old_replace_end = None;
10329        let mut old_insert_start = None;
10330        let mut old_insert_end = None;
10331        let mut new_text = String::default();
10332        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10333            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10334                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10335                anyhow::Ok(buffer.read(cx).snapshot())
10336            })?;
10337
10338            if let Some(text_edit) = completion.text_edit.as_ref() {
10339                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10340
10341                if let Some(mut edit) = edit {
10342                    LineEnding::normalize(&mut edit.new_text);
10343
10344                    new_text = edit.new_text;
10345                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10346                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10347                    if let Some(insert_range) = edit.insert_range {
10348                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10349                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10350                    }
10351                }
10352            }
10353        }
10354
10355        Ok(proto::ResolveCompletionDocumentationResponse {
10356            documentation,
10357            documentation_is_markdown,
10358            old_replace_start,
10359            old_replace_end,
10360            new_text,
10361            lsp_completion,
10362            old_insert_start,
10363            old_insert_end,
10364        })
10365    }
10366
10367    async fn handle_on_type_formatting(
10368        this: Entity<Self>,
10369        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10370        mut cx: AsyncApp,
10371    ) -> Result<proto::OnTypeFormattingResponse> {
10372        let on_type_formatting = this.update(&mut cx, |this, cx| {
10373            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10374            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10375            let position = envelope
10376                .payload
10377                .position
10378                .and_then(deserialize_anchor)
10379                .context("invalid position")?;
10380            anyhow::Ok(this.apply_on_type_formatting(
10381                buffer,
10382                position,
10383                envelope.payload.trigger.clone(),
10384                cx,
10385            ))
10386        })?;
10387
10388        let transaction = on_type_formatting
10389            .await?
10390            .as_ref()
10391            .map(language::proto::serialize_transaction);
10392        Ok(proto::OnTypeFormattingResponse { transaction })
10393    }
10394
10395    async fn handle_pull_workspace_diagnostics(
10396        lsp_store: Entity<Self>,
10397        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::Ack> {
10400        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10401        lsp_store.update(&mut cx, |lsp_store, _| {
10402            lsp_store.pull_workspace_diagnostics(server_id);
10403        });
10404        Ok(proto::Ack {})
10405    }
10406
10407    async fn handle_open_buffer_for_symbol(
10408        this: Entity<Self>,
10409        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10410        mut cx: AsyncApp,
10411    ) -> Result<proto::OpenBufferForSymbolResponse> {
10412        let peer_id = envelope.original_sender_id().unwrap_or_default();
10413        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10414        let symbol = Self::deserialize_symbol(symbol)?;
10415        this.read_with(&cx, |this, _| {
10416            if let SymbolLocation::OutsideProject {
10417                abs_path,
10418                signature,
10419            } = &symbol.path
10420            {
10421                let new_signature = this.symbol_signature(&abs_path);
10422                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10423            }
10424            Ok(())
10425        })?;
10426        let buffer = this
10427            .update(&mut cx, |this, cx| {
10428                this.open_buffer_for_symbol(
10429                    &Symbol {
10430                        language_server_name: symbol.language_server_name,
10431                        source_worktree_id: symbol.source_worktree_id,
10432                        source_language_server_id: symbol.source_language_server_id,
10433                        path: symbol.path,
10434                        name: symbol.name,
10435                        kind: symbol.kind,
10436                        range: symbol.range,
10437                        label: CodeLabel::default(),
10438                        container_name: symbol.container_name,
10439                    },
10440                    cx,
10441                )
10442            })
10443            .await?;
10444
10445        this.update(&mut cx, |this, cx| {
10446            let is_private = buffer
10447                .read(cx)
10448                .file()
10449                .map(|f| f.is_private())
10450                .unwrap_or_default();
10451            if is_private {
10452                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10453            } else {
10454                this.buffer_store
10455                    .update(cx, |buffer_store, cx| {
10456                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10457                    })
10458                    .detach_and_log_err(cx);
10459                let buffer_id = buffer.read(cx).remote_id().to_proto();
10460                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10461            }
10462        })
10463    }
10464
10465    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10466        let mut hasher = Sha256::new();
10467        hasher.update(abs_path.to_string_lossy().as_bytes());
10468        hasher.update(self.nonce.to_be_bytes());
10469        hasher.finalize().as_slice().try_into().unwrap()
10470    }
10471
10472    pub async fn handle_get_project_symbols(
10473        this: Entity<Self>,
10474        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10475        mut cx: AsyncApp,
10476    ) -> Result<proto::GetProjectSymbolsResponse> {
10477        let symbols = this
10478            .update(&mut cx, |this, cx| {
10479                this.symbols(&envelope.payload.query, cx)
10480            })
10481            .await?;
10482
10483        Ok(proto::GetProjectSymbolsResponse {
10484            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10485        })
10486    }
10487
10488    pub async fn handle_restart_language_servers(
10489        this: Entity<Self>,
10490        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10491        mut cx: AsyncApp,
10492    ) -> Result<proto::Ack> {
10493        this.update(&mut cx, |lsp_store, cx| {
10494            let buffers =
10495                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10496            lsp_store.restart_language_servers_for_buffers(
10497                buffers,
10498                envelope
10499                    .payload
10500                    .only_servers
10501                    .into_iter()
10502                    .filter_map(|selector| {
10503                        Some(match selector.selector? {
10504                            proto::language_server_selector::Selector::ServerId(server_id) => {
10505                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10506                            }
10507                            proto::language_server_selector::Selector::Name(name) => {
10508                                LanguageServerSelector::Name(LanguageServerName(
10509                                    SharedString::from(name),
10510                                ))
10511                            }
10512                        })
10513                    })
10514                    .collect(),
10515                cx,
10516            );
10517        });
10518
10519        Ok(proto::Ack {})
10520    }
10521
10522    pub async fn handle_stop_language_servers(
10523        lsp_store: Entity<Self>,
10524        envelope: TypedEnvelope<proto::StopLanguageServers>,
10525        mut cx: AsyncApp,
10526    ) -> Result<proto::Ack> {
10527        lsp_store.update(&mut cx, |lsp_store, cx| {
10528            if envelope.payload.all
10529                && envelope.payload.also_servers.is_empty()
10530                && envelope.payload.buffer_ids.is_empty()
10531            {
10532                lsp_store.stop_all_language_servers(cx);
10533            } else {
10534                let buffers =
10535                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10536                lsp_store
10537                    .stop_language_servers_for_buffers(
10538                        buffers,
10539                        envelope
10540                            .payload
10541                            .also_servers
10542                            .into_iter()
10543                            .filter_map(|selector| {
10544                                Some(match selector.selector? {
10545                                    proto::language_server_selector::Selector::ServerId(
10546                                        server_id,
10547                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10548                                        server_id,
10549                                    )),
10550                                    proto::language_server_selector::Selector::Name(name) => {
10551                                        LanguageServerSelector::Name(LanguageServerName(
10552                                            SharedString::from(name),
10553                                        ))
10554                                    }
10555                                })
10556                            })
10557                            .collect(),
10558                        cx,
10559                    )
10560                    .detach_and_log_err(cx);
10561            }
10562        });
10563
10564        Ok(proto::Ack {})
10565    }
10566
10567    pub async fn handle_cancel_language_server_work(
10568        lsp_store: Entity<Self>,
10569        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10570        mut cx: AsyncApp,
10571    ) -> Result<proto::Ack> {
10572        lsp_store.update(&mut cx, |lsp_store, cx| {
10573            if let Some(work) = envelope.payload.work {
10574                match work {
10575                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10576                        let buffers =
10577                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10578                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10579                    }
10580                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10581                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10582                        let token = work
10583                            .token
10584                            .map(|token| {
10585                                ProgressToken::from_proto(token)
10586                                    .context("invalid work progress token")
10587                            })
10588                            .transpose()?;
10589                        lsp_store.cancel_language_server_work(server_id, token, cx);
10590                    }
10591                }
10592            }
10593            anyhow::Ok(())
10594        })?;
10595
10596        Ok(proto::Ack {})
10597    }
10598
10599    fn buffer_ids_to_buffers(
10600        &mut self,
10601        buffer_ids: impl Iterator<Item = u64>,
10602        cx: &mut Context<Self>,
10603    ) -> Vec<Entity<Buffer>> {
10604        buffer_ids
10605            .into_iter()
10606            .flat_map(|buffer_id| {
10607                self.buffer_store
10608                    .read(cx)
10609                    .get(BufferId::new(buffer_id).log_err()?)
10610            })
10611            .collect::<Vec<_>>()
10612    }
10613
10614    async fn handle_apply_additional_edits_for_completion(
10615        this: Entity<Self>,
10616        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10617        mut cx: AsyncApp,
10618    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10619        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10620            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10621            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10622            let completion = Self::deserialize_completion(
10623                envelope.payload.completion.context("invalid completion")?,
10624            )?;
10625            let all_commit_ranges = envelope
10626                .payload
10627                .all_commit_ranges
10628                .into_iter()
10629                .map(language::proto::deserialize_anchor_range)
10630                .collect::<Result<Vec<_>, _>>()?;
10631            anyhow::Ok((buffer, completion, all_commit_ranges))
10632        })?;
10633
10634        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10635            this.apply_additional_edits_for_completion(
10636                buffer,
10637                Rc::new(RefCell::new(Box::new([Completion {
10638                    replace_range: completion.replace_range,
10639                    new_text: completion.new_text,
10640                    source: completion.source,
10641                    documentation: None,
10642                    label: CodeLabel::default(),
10643                    match_start: None,
10644                    snippet_deduplication_key: None,
10645                    insert_text_mode: None,
10646                    icon_path: None,
10647                    confirm: None,
10648                }]))),
10649                0,
10650                false,
10651                all_commit_ranges,
10652                cx,
10653            )
10654        });
10655
10656        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10657            transaction: apply_additional_edits
10658                .await?
10659                .as_ref()
10660                .map(language::proto::serialize_transaction),
10661        })
10662    }
10663
10664    pub fn last_formatting_failure(&self) -> Option<&str> {
10665        self.last_formatting_failure.as_deref()
10666    }
10667
10668    pub fn reset_last_formatting_failure(&mut self) {
10669        self.last_formatting_failure = None;
10670    }
10671
10672    pub fn environment_for_buffer(
10673        &self,
10674        buffer: &Entity<Buffer>,
10675        cx: &mut Context<Self>,
10676    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10677        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10678            environment.update(cx, |env, cx| {
10679                env.buffer_environment(buffer, &self.worktree_store, cx)
10680            })
10681        } else {
10682            Task::ready(None).shared()
10683        }
10684    }
10685
10686    pub fn format(
10687        &mut self,
10688        buffers: HashSet<Entity<Buffer>>,
10689        target: LspFormatTarget,
10690        push_to_history: bool,
10691        trigger: FormatTrigger,
10692        cx: &mut Context<Self>,
10693    ) -> Task<anyhow::Result<ProjectTransaction>> {
10694        let logger = zlog::scoped!("format");
10695        if self.as_local().is_some() {
10696            zlog::trace!(logger => "Formatting locally");
10697            let logger = zlog::scoped!(logger => "local");
10698            let buffers = buffers
10699                .into_iter()
10700                .map(|buffer_handle| {
10701                    let buffer = buffer_handle.read(cx);
10702                    let buffer_abs_path = File::from_dyn(buffer.file())
10703                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10704
10705                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10706                })
10707                .collect::<Vec<_>>();
10708
10709            cx.spawn(async move |lsp_store, cx| {
10710                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10711
10712                for (handle, abs_path, id) in buffers {
10713                    let env = lsp_store
10714                        .update(cx, |lsp_store, cx| {
10715                            lsp_store.environment_for_buffer(&handle, cx)
10716                        })?
10717                        .await;
10718
10719                    let ranges = match &target {
10720                        LspFormatTarget::Buffers => None,
10721                        LspFormatTarget::Ranges(ranges) => {
10722                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10723                        }
10724                    };
10725
10726                    formattable_buffers.push(FormattableBuffer {
10727                        handle,
10728                        abs_path,
10729                        env,
10730                        ranges,
10731                    });
10732                }
10733                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10734
10735                let format_timer = zlog::time!(logger => "Formatting buffers");
10736                let result = LocalLspStore::format_locally(
10737                    lsp_store.clone(),
10738                    formattable_buffers,
10739                    push_to_history,
10740                    trigger,
10741                    logger,
10742                    cx,
10743                )
10744                .await;
10745                format_timer.end();
10746
10747                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10748
10749                lsp_store.update(cx, |lsp_store, _| {
10750                    lsp_store.update_last_formatting_failure(&result);
10751                })?;
10752
10753                result
10754            })
10755        } else if let Some((client, project_id)) = self.upstream_client() {
10756            zlog::trace!(logger => "Formatting remotely");
10757            let logger = zlog::scoped!(logger => "remote");
10758
10759            let buffer_ranges = match &target {
10760                LspFormatTarget::Buffers => Vec::new(),
10761                LspFormatTarget::Ranges(ranges) => ranges
10762                    .iter()
10763                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10764                        buffer_id: buffer_id.to_proto(),
10765                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10766                    })
10767                    .collect(),
10768            };
10769
10770            let buffer_store = self.buffer_store();
10771            cx.spawn(async move |lsp_store, cx| {
10772                zlog::trace!(logger => "Sending remote format request");
10773                let request_timer = zlog::time!(logger => "remote format request");
10774                let result = client
10775                    .request(proto::FormatBuffers {
10776                        project_id,
10777                        trigger: trigger as i32,
10778                        buffer_ids: buffers
10779                            .iter()
10780                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10781                            .collect(),
10782                        buffer_ranges,
10783                    })
10784                    .await
10785                    .and_then(|result| result.transaction.context("missing transaction"));
10786                request_timer.end();
10787
10788                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10789
10790                lsp_store.update(cx, |lsp_store, _| {
10791                    lsp_store.update_last_formatting_failure(&result);
10792                })?;
10793
10794                let transaction_response = result?;
10795                let _timer = zlog::time!(logger => "deserializing project transaction");
10796                buffer_store
10797                    .update(cx, |buffer_store, cx| {
10798                        buffer_store.deserialize_project_transaction(
10799                            transaction_response,
10800                            push_to_history,
10801                            cx,
10802                        )
10803                    })
10804                    .await
10805            })
10806        } else {
10807            zlog::trace!(logger => "Not formatting");
10808            Task::ready(Ok(ProjectTransaction::default()))
10809        }
10810    }
10811
10812    async fn handle_format_buffers(
10813        this: Entity<Self>,
10814        envelope: TypedEnvelope<proto::FormatBuffers>,
10815        mut cx: AsyncApp,
10816    ) -> Result<proto::FormatBuffersResponse> {
10817        let sender_id = envelope.original_sender_id().unwrap_or_default();
10818        let format = this.update(&mut cx, |this, cx| {
10819            let mut buffers = HashSet::default();
10820            for buffer_id in &envelope.payload.buffer_ids {
10821                let buffer_id = BufferId::new(*buffer_id)?;
10822                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10823            }
10824
10825            let target = if envelope.payload.buffer_ranges.is_empty() {
10826                LspFormatTarget::Buffers
10827            } else {
10828                let mut ranges_map = BTreeMap::new();
10829                for buffer_range in &envelope.payload.buffer_ranges {
10830                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10831                    let ranges: Result<Vec<_>> = buffer_range
10832                        .ranges
10833                        .iter()
10834                        .map(|range| {
10835                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10836                        })
10837                        .collect();
10838                    ranges_map.insert(buffer_id, ranges?);
10839                }
10840                LspFormatTarget::Ranges(ranges_map)
10841            };
10842
10843            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10844            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10845        })?;
10846
10847        let project_transaction = format.await?;
10848        let project_transaction = this.update(&mut cx, |this, cx| {
10849            this.buffer_store.update(cx, |buffer_store, cx| {
10850                buffer_store.serialize_project_transaction_for_peer(
10851                    project_transaction,
10852                    sender_id,
10853                    cx,
10854                )
10855            })
10856        });
10857        Ok(proto::FormatBuffersResponse {
10858            transaction: Some(project_transaction),
10859        })
10860    }
10861
10862    async fn handle_apply_code_action_kind(
10863        this: Entity<Self>,
10864        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10865        mut cx: AsyncApp,
10866    ) -> Result<proto::ApplyCodeActionKindResponse> {
10867        let sender_id = envelope.original_sender_id().unwrap_or_default();
10868        let format = this.update(&mut cx, |this, cx| {
10869            let mut buffers = HashSet::default();
10870            for buffer_id in &envelope.payload.buffer_ids {
10871                let buffer_id = BufferId::new(*buffer_id)?;
10872                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10873            }
10874            let kind = match envelope.payload.kind.as_str() {
10875                "" => CodeActionKind::EMPTY,
10876                "quickfix" => CodeActionKind::QUICKFIX,
10877                "refactor" => CodeActionKind::REFACTOR,
10878                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10879                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10880                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10881                "source" => CodeActionKind::SOURCE,
10882                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10883                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10884                _ => anyhow::bail!(
10885                    "Invalid code action kind {}",
10886                    envelope.payload.kind.as_str()
10887                ),
10888            };
10889            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10890        })?;
10891
10892        let project_transaction = format.await?;
10893        let project_transaction = this.update(&mut cx, |this, cx| {
10894            this.buffer_store.update(cx, |buffer_store, cx| {
10895                buffer_store.serialize_project_transaction_for_peer(
10896                    project_transaction,
10897                    sender_id,
10898                    cx,
10899                )
10900            })
10901        });
10902        Ok(proto::ApplyCodeActionKindResponse {
10903            transaction: Some(project_transaction),
10904        })
10905    }
10906
10907    async fn shutdown_language_server(
10908        server_state: Option<LanguageServerState>,
10909        name: LanguageServerName,
10910        cx: &mut AsyncApp,
10911    ) {
10912        let server = match server_state {
10913            Some(LanguageServerState::Starting { startup, .. }) => {
10914                let mut timer = cx
10915                    .background_executor()
10916                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10917                    .fuse();
10918
10919                select! {
10920                    server = startup.fuse() => server,
10921                    () = timer => {
10922                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10923                        None
10924                    },
10925                }
10926            }
10927
10928            Some(LanguageServerState::Running { server, .. }) => Some(server),
10929
10930            None => None,
10931        };
10932
10933        let Some(server) = server else { return };
10934        if let Some(shutdown) = server.shutdown() {
10935            shutdown.await;
10936        }
10937    }
10938
10939    // Returns a list of all of the worktrees which no longer have a language server and the root path
10940    // for the stopped server
10941    fn stop_local_language_server(
10942        &mut self,
10943        server_id: LanguageServerId,
10944        cx: &mut Context<Self>,
10945    ) -> Task<()> {
10946        let local = match &mut self.mode {
10947            LspStoreMode::Local(local) => local,
10948            _ => {
10949                return Task::ready(());
10950            }
10951        };
10952
10953        // Remove this server ID from all entries in the given worktree.
10954        local
10955            .language_server_ids
10956            .retain(|_, state| state.id != server_id);
10957        self.buffer_store.update(cx, |buffer_store, cx| {
10958            for buffer in buffer_store.buffers() {
10959                buffer.update(cx, |buffer, cx| {
10960                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10961                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10962                });
10963            }
10964        });
10965
10966        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10967        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10968            summaries.retain(|path, summaries_by_server_id| {
10969                if summaries_by_server_id.remove(&server_id).is_some() {
10970                    if let Some((client, project_id)) = self.downstream_client.clone() {
10971                        client
10972                            .send(proto::UpdateDiagnosticSummary {
10973                                project_id,
10974                                worktree_id: worktree_id.to_proto(),
10975                                summary: Some(proto::DiagnosticSummary {
10976                                    path: path.as_ref().to_proto(),
10977                                    language_server_id: server_id.0 as u64,
10978                                    error_count: 0,
10979                                    warning_count: 0,
10980                                }),
10981                                more_summaries: Vec::new(),
10982                            })
10983                            .log_err();
10984                    }
10985                    cleared_paths.push(ProjectPath {
10986                        worktree_id: *worktree_id,
10987                        path: path.clone(),
10988                    });
10989                    !summaries_by_server_id.is_empty()
10990                } else {
10991                    true
10992                }
10993            });
10994        }
10995        if !cleared_paths.is_empty() {
10996            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10997                server_id,
10998                paths: cleared_paths,
10999            });
11000        }
11001
11002        let local = self.as_local_mut().unwrap();
11003        for diagnostics in local.diagnostics.values_mut() {
11004            diagnostics.retain(|_, diagnostics_by_server_id| {
11005                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11006                    diagnostics_by_server_id.remove(ix);
11007                    !diagnostics_by_server_id.is_empty()
11008                } else {
11009                    true
11010                }
11011            });
11012        }
11013        local.language_server_watched_paths.remove(&server_id);
11014
11015        let server_state = local.language_servers.remove(&server_id);
11016        self.cleanup_lsp_data(server_id);
11017        let name = self
11018            .language_server_statuses
11019            .remove(&server_id)
11020            .map(|status| status.name)
11021            .or_else(|| {
11022                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11023                    Some(adapter.name())
11024                } else {
11025                    None
11026                }
11027            });
11028
11029        if let Some(name) = name {
11030            log::info!("stopping language server {name}");
11031            self.languages
11032                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11033            cx.notify();
11034
11035            return cx.spawn(async move |lsp_store, cx| {
11036                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11037                lsp_store
11038                    .update(cx, |lsp_store, cx| {
11039                        lsp_store
11040                            .languages
11041                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11042                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11043                        cx.notify();
11044                    })
11045                    .ok();
11046            });
11047        }
11048
11049        if server_state.is_some() {
11050            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11051        }
11052        Task::ready(())
11053    }
11054
11055    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11056        self.shutdown_all_language_servers(cx).detach();
11057    }
11058
11059    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11060        if let Some((client, project_id)) = self.upstream_client() {
11061            let request = client.request(proto::StopLanguageServers {
11062                project_id,
11063                buffer_ids: Vec::new(),
11064                also_servers: Vec::new(),
11065                all: true,
11066            });
11067            cx.background_spawn(async move {
11068                request.await.ok();
11069            })
11070        } else {
11071            let Some(local) = self.as_local_mut() else {
11072                return Task::ready(());
11073            };
11074            let language_servers_to_stop = local
11075                .language_server_ids
11076                .values()
11077                .map(|state| state.id)
11078                .collect();
11079            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11080            let tasks = language_servers_to_stop
11081                .into_iter()
11082                .map(|server| self.stop_local_language_server(server, cx))
11083                .collect::<Vec<_>>();
11084            cx.background_spawn(async move {
11085                futures::future::join_all(tasks).await;
11086            })
11087        }
11088    }
11089
11090    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11091        let buffers = self.buffer_store.read(cx).buffers().collect();
11092        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11093    }
11094
11095    pub fn restart_language_servers_for_buffers(
11096        &mut self,
11097        buffers: Vec<Entity<Buffer>>,
11098        only_restart_servers: HashSet<LanguageServerSelector>,
11099        cx: &mut Context<Self>,
11100    ) {
11101        if let Some((client, project_id)) = self.upstream_client() {
11102            let request = client.request(proto::RestartLanguageServers {
11103                project_id,
11104                buffer_ids: buffers
11105                    .into_iter()
11106                    .map(|b| b.read(cx).remote_id().to_proto())
11107                    .collect(),
11108                only_servers: only_restart_servers
11109                    .into_iter()
11110                    .map(|selector| {
11111                        let selector = match selector {
11112                            LanguageServerSelector::Id(language_server_id) => {
11113                                proto::language_server_selector::Selector::ServerId(
11114                                    language_server_id.to_proto(),
11115                                )
11116                            }
11117                            LanguageServerSelector::Name(language_server_name) => {
11118                                proto::language_server_selector::Selector::Name(
11119                                    language_server_name.to_string(),
11120                                )
11121                            }
11122                        };
11123                        proto::LanguageServerSelector {
11124                            selector: Some(selector),
11125                        }
11126                    })
11127                    .collect(),
11128                all: false,
11129            });
11130            cx.background_spawn(request).detach_and_log_err(cx);
11131        } else {
11132            let stop_task = if only_restart_servers.is_empty() {
11133                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11134            } else {
11135                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11136            };
11137            cx.spawn(async move |lsp_store, cx| {
11138                stop_task.await;
11139                lsp_store.update(cx, |lsp_store, cx| {
11140                    for buffer in buffers {
11141                        lsp_store.register_buffer_with_language_servers(
11142                            &buffer,
11143                            only_restart_servers.clone(),
11144                            true,
11145                            cx,
11146                        );
11147                    }
11148                })
11149            })
11150            .detach();
11151        }
11152    }
11153
11154    pub fn stop_language_servers_for_buffers(
11155        &mut self,
11156        buffers: Vec<Entity<Buffer>>,
11157        also_stop_servers: HashSet<LanguageServerSelector>,
11158        cx: &mut Context<Self>,
11159    ) -> Task<Result<()>> {
11160        if let Some((client, project_id)) = self.upstream_client() {
11161            let request = client.request(proto::StopLanguageServers {
11162                project_id,
11163                buffer_ids: buffers
11164                    .into_iter()
11165                    .map(|b| b.read(cx).remote_id().to_proto())
11166                    .collect(),
11167                also_servers: also_stop_servers
11168                    .into_iter()
11169                    .map(|selector| {
11170                        let selector = match selector {
11171                            LanguageServerSelector::Id(language_server_id) => {
11172                                proto::language_server_selector::Selector::ServerId(
11173                                    language_server_id.to_proto(),
11174                                )
11175                            }
11176                            LanguageServerSelector::Name(language_server_name) => {
11177                                proto::language_server_selector::Selector::Name(
11178                                    language_server_name.to_string(),
11179                                )
11180                            }
11181                        };
11182                        proto::LanguageServerSelector {
11183                            selector: Some(selector),
11184                        }
11185                    })
11186                    .collect(),
11187                all: false,
11188            });
11189            cx.background_spawn(async move {
11190                let _ = request.await?;
11191                Ok(())
11192            })
11193        } else {
11194            let task =
11195                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11196            cx.background_spawn(async move {
11197                task.await;
11198                Ok(())
11199            })
11200        }
11201    }
11202
11203    fn stop_local_language_servers_for_buffers(
11204        &mut self,
11205        buffers: &[Entity<Buffer>],
11206        also_stop_servers: HashSet<LanguageServerSelector>,
11207        cx: &mut Context<Self>,
11208    ) -> Task<()> {
11209        let Some(local) = self.as_local_mut() else {
11210            return Task::ready(());
11211        };
11212        let mut language_server_names_to_stop = BTreeSet::default();
11213        let mut language_servers_to_stop = also_stop_servers
11214            .into_iter()
11215            .flat_map(|selector| match selector {
11216                LanguageServerSelector::Id(id) => Some(id),
11217                LanguageServerSelector::Name(name) => {
11218                    language_server_names_to_stop.insert(name);
11219                    None
11220                }
11221            })
11222            .collect::<BTreeSet<_>>();
11223
11224        let mut covered_worktrees = HashSet::default();
11225        for buffer in buffers {
11226            buffer.update(cx, |buffer, cx| {
11227                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11228                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11229                    && covered_worktrees.insert(worktree_id)
11230                {
11231                    language_server_names_to_stop.retain(|name| {
11232                        let old_ids_count = language_servers_to_stop.len();
11233                        let all_language_servers_with_this_name = local
11234                            .language_server_ids
11235                            .iter()
11236                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11237                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11238                        old_ids_count == language_servers_to_stop.len()
11239                    });
11240                }
11241            });
11242        }
11243        for name in language_server_names_to_stop {
11244            language_servers_to_stop.extend(
11245                local
11246                    .language_server_ids
11247                    .iter()
11248                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11249            );
11250        }
11251
11252        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11253        let tasks = language_servers_to_stop
11254            .into_iter()
11255            .map(|server| self.stop_local_language_server(server, cx))
11256            .collect::<Vec<_>>();
11257
11258        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11259    }
11260
11261    #[cfg(any(test, feature = "test-support"))]
11262    pub fn update_diagnostics(
11263        &mut self,
11264        server_id: LanguageServerId,
11265        diagnostics: lsp::PublishDiagnosticsParams,
11266        result_id: Option<SharedString>,
11267        source_kind: DiagnosticSourceKind,
11268        disk_based_sources: &[String],
11269        cx: &mut Context<Self>,
11270    ) -> Result<()> {
11271        self.merge_lsp_diagnostics(
11272            source_kind,
11273            vec![DocumentDiagnosticsUpdate {
11274                diagnostics,
11275                result_id,
11276                server_id,
11277                disk_based_sources: Cow::Borrowed(disk_based_sources),
11278                registration_id: None,
11279            }],
11280            |_, _, _| false,
11281            cx,
11282        )
11283    }
11284
11285    pub fn merge_lsp_diagnostics(
11286        &mut self,
11287        source_kind: DiagnosticSourceKind,
11288        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11289        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11290        cx: &mut Context<Self>,
11291    ) -> Result<()> {
11292        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11293        let updates = lsp_diagnostics
11294            .into_iter()
11295            .filter_map(|update| {
11296                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11297                Some(DocumentDiagnosticsUpdate {
11298                    diagnostics: self.lsp_to_document_diagnostics(
11299                        abs_path,
11300                        source_kind,
11301                        update.server_id,
11302                        update.diagnostics,
11303                        &update.disk_based_sources,
11304                        update.registration_id.clone(),
11305                    ),
11306                    result_id: update.result_id,
11307                    server_id: update.server_id,
11308                    disk_based_sources: update.disk_based_sources,
11309                    registration_id: update.registration_id,
11310                })
11311            })
11312            .collect();
11313        self.merge_diagnostic_entries(updates, merge, cx)?;
11314        Ok(())
11315    }
11316
11317    fn lsp_to_document_diagnostics(
11318        &mut self,
11319        document_abs_path: PathBuf,
11320        source_kind: DiagnosticSourceKind,
11321        server_id: LanguageServerId,
11322        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11323        disk_based_sources: &[String],
11324        registration_id: Option<SharedString>,
11325    ) -> DocumentDiagnostics {
11326        let mut diagnostics = Vec::default();
11327        let mut primary_diagnostic_group_ids = HashMap::default();
11328        let mut sources_by_group_id = HashMap::default();
11329        let mut supporting_diagnostics = HashMap::default();
11330
11331        let adapter = self.language_server_adapter_for_id(server_id);
11332
11333        // Ensure that primary diagnostics are always the most severe
11334        lsp_diagnostics
11335            .diagnostics
11336            .sort_by_key(|item| item.severity);
11337
11338        for diagnostic in &lsp_diagnostics.diagnostics {
11339            let source = diagnostic.source.as_ref();
11340            let range = range_from_lsp(diagnostic.range);
11341            let is_supporting = diagnostic
11342                .related_information
11343                .as_ref()
11344                .is_some_and(|infos| {
11345                    infos.iter().any(|info| {
11346                        primary_diagnostic_group_ids.contains_key(&(
11347                            source,
11348                            diagnostic.code.clone(),
11349                            range_from_lsp(info.location.range),
11350                        ))
11351                    })
11352                });
11353
11354            let is_unnecessary = diagnostic
11355                .tags
11356                .as_ref()
11357                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11358
11359            let underline = self
11360                .language_server_adapter_for_id(server_id)
11361                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11362
11363            if is_supporting {
11364                supporting_diagnostics.insert(
11365                    (source, diagnostic.code.clone(), range),
11366                    (diagnostic.severity, is_unnecessary),
11367                );
11368            } else {
11369                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11370                let is_disk_based =
11371                    source.is_some_and(|source| disk_based_sources.contains(source));
11372
11373                sources_by_group_id.insert(group_id, source);
11374                primary_diagnostic_group_ids
11375                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11376
11377                diagnostics.push(DiagnosticEntry {
11378                    range,
11379                    diagnostic: Diagnostic {
11380                        source: diagnostic.source.clone(),
11381                        source_kind,
11382                        code: diagnostic.code.clone(),
11383                        code_description: diagnostic
11384                            .code_description
11385                            .as_ref()
11386                            .and_then(|d| d.href.clone()),
11387                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11388                        markdown: adapter.as_ref().and_then(|adapter| {
11389                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11390                        }),
11391                        message: diagnostic.message.trim().to_string(),
11392                        group_id,
11393                        is_primary: true,
11394                        is_disk_based,
11395                        is_unnecessary,
11396                        underline,
11397                        data: diagnostic.data.clone(),
11398                        registration_id: registration_id.clone(),
11399                    },
11400                });
11401                if let Some(infos) = &diagnostic.related_information {
11402                    for info in infos {
11403                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11404                            let range = range_from_lsp(info.location.range);
11405                            diagnostics.push(DiagnosticEntry {
11406                                range,
11407                                diagnostic: Diagnostic {
11408                                    source: diagnostic.source.clone(),
11409                                    source_kind,
11410                                    code: diagnostic.code.clone(),
11411                                    code_description: diagnostic
11412                                        .code_description
11413                                        .as_ref()
11414                                        .and_then(|d| d.href.clone()),
11415                                    severity: DiagnosticSeverity::INFORMATION,
11416                                    markdown: adapter.as_ref().and_then(|adapter| {
11417                                        adapter.diagnostic_message_to_markdown(&info.message)
11418                                    }),
11419                                    message: info.message.trim().to_string(),
11420                                    group_id,
11421                                    is_primary: false,
11422                                    is_disk_based,
11423                                    is_unnecessary: false,
11424                                    underline,
11425                                    data: diagnostic.data.clone(),
11426                                    registration_id: registration_id.clone(),
11427                                },
11428                            });
11429                        }
11430                    }
11431                }
11432            }
11433        }
11434
11435        for entry in &mut diagnostics {
11436            let diagnostic = &mut entry.diagnostic;
11437            if !diagnostic.is_primary {
11438                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11439                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11440                    source,
11441                    diagnostic.code.clone(),
11442                    entry.range.clone(),
11443                )) {
11444                    if let Some(severity) = severity {
11445                        diagnostic.severity = severity;
11446                    }
11447                    diagnostic.is_unnecessary = is_unnecessary;
11448                }
11449            }
11450        }
11451
11452        DocumentDiagnostics {
11453            diagnostics,
11454            document_abs_path,
11455            version: lsp_diagnostics.version,
11456        }
11457    }
11458
11459    fn insert_newly_running_language_server(
11460        &mut self,
11461        adapter: Arc<CachedLspAdapter>,
11462        language_server: Arc<LanguageServer>,
11463        server_id: LanguageServerId,
11464        key: LanguageServerSeed,
11465        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11466        cx: &mut Context<Self>,
11467    ) {
11468        let Some(local) = self.as_local_mut() else {
11469            return;
11470        };
11471        // If the language server for this key doesn't match the server id, don't store the
11472        // server. Which will cause it to be dropped, killing the process
11473        if local
11474            .language_server_ids
11475            .get(&key)
11476            .map(|state| state.id != server_id)
11477            .unwrap_or(false)
11478        {
11479            return;
11480        }
11481
11482        // Update language_servers collection with Running variant of LanguageServerState
11483        // indicating that the server is up and running and ready
11484        let workspace_folders = workspace_folders.lock().clone();
11485        language_server.set_workspace_folders(workspace_folders);
11486
11487        let workspace_diagnostics_refresh_tasks = language_server
11488            .capabilities()
11489            .diagnostic_provider
11490            .and_then(|provider| {
11491                local
11492                    .language_server_dynamic_registrations
11493                    .entry(server_id)
11494                    .or_default()
11495                    .diagnostics
11496                    .entry(None)
11497                    .or_insert(provider.clone());
11498                let workspace_refresher =
11499                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11500
11501                Some((None, workspace_refresher))
11502            })
11503            .into_iter()
11504            .collect();
11505        local.language_servers.insert(
11506            server_id,
11507            LanguageServerState::Running {
11508                workspace_diagnostics_refresh_tasks,
11509                adapter: adapter.clone(),
11510                server: language_server.clone(),
11511                simulate_disk_based_diagnostics_completion: None,
11512            },
11513        );
11514        local
11515            .languages
11516            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11517        if let Some(file_ops_caps) = language_server
11518            .capabilities()
11519            .workspace
11520            .as_ref()
11521            .and_then(|ws| ws.file_operations.as_ref())
11522        {
11523            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11524            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11525            if did_rename_caps.or(will_rename_caps).is_some() {
11526                let watcher = RenamePathsWatchedForServer::default()
11527                    .with_did_rename_patterns(did_rename_caps)
11528                    .with_will_rename_patterns(will_rename_caps);
11529                local
11530                    .language_server_paths_watched_for_rename
11531                    .insert(server_id, watcher);
11532            }
11533        }
11534
11535        self.language_server_statuses.insert(
11536            server_id,
11537            LanguageServerStatus {
11538                name: language_server.name(),
11539                server_version: language_server.version(),
11540                server_readable_version: language_server.readable_version(),
11541                pending_work: Default::default(),
11542                has_pending_diagnostic_updates: false,
11543                progress_tokens: Default::default(),
11544                worktree: Some(key.worktree_id),
11545                binary: Some(language_server.binary().clone()),
11546                configuration: Some(language_server.configuration().clone()),
11547                workspace_folders: language_server.workspace_folders(),
11548                process_id: language_server.process_id(),
11549            },
11550        );
11551
11552        cx.emit(LspStoreEvent::LanguageServerAdded(
11553            server_id,
11554            language_server.name(),
11555            Some(key.worktree_id),
11556        ));
11557
11558        let server_capabilities = language_server.capabilities();
11559        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11560            downstream_client
11561                .send(proto::StartLanguageServer {
11562                    project_id: *project_id,
11563                    server: Some(proto::LanguageServer {
11564                        id: server_id.to_proto(),
11565                        name: language_server.name().to_string(),
11566                        worktree_id: Some(key.worktree_id.to_proto()),
11567                    }),
11568                    capabilities: serde_json::to_string(&server_capabilities)
11569                        .expect("serializing server LSP capabilities"),
11570                })
11571                .log_err();
11572        }
11573        self.lsp_server_capabilities
11574            .insert(server_id, server_capabilities);
11575
11576        // Tell the language server about every open buffer in the worktree that matches the language.
11577        // Also check for buffers in worktrees that reused this server
11578        let mut worktrees_using_server = vec![key.worktree_id];
11579        if let Some(local) = self.as_local() {
11580            // Find all worktrees that have this server in their language server tree
11581            for (worktree_id, servers) in &local.lsp_tree.instances {
11582                if *worktree_id != key.worktree_id {
11583                    for server_map in servers.roots.values() {
11584                        if server_map
11585                            .values()
11586                            .any(|(node, _)| node.id() == Some(server_id))
11587                        {
11588                            worktrees_using_server.push(*worktree_id);
11589                        }
11590                    }
11591                }
11592            }
11593        }
11594
11595        let mut buffer_paths_registered = Vec::new();
11596        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11597            let mut lsp_adapters = HashMap::default();
11598            for buffer_handle in buffer_store.buffers() {
11599                let buffer = buffer_handle.read(cx);
11600                let file = match File::from_dyn(buffer.file()) {
11601                    Some(file) => file,
11602                    None => continue,
11603                };
11604                let language = match buffer.language() {
11605                    Some(language) => language,
11606                    None => continue,
11607                };
11608
11609                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11610                    || !lsp_adapters
11611                        .entry(language.name())
11612                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11613                        .iter()
11614                        .any(|a| a.name == key.name)
11615                {
11616                    continue;
11617                }
11618                // didOpen
11619                let file = match file.as_local() {
11620                    Some(file) => file,
11621                    None => continue,
11622                };
11623
11624                let local = self.as_local_mut().unwrap();
11625
11626                let buffer_id = buffer.remote_id();
11627                if local.registered_buffers.contains_key(&buffer_id) {
11628                    let abs_path = file.abs_path(cx);
11629                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11630                        Ok(uri) => uri,
11631                        Err(()) => {
11632                            log::error!("failed to convert path to URI: {:?}", abs_path);
11633                            continue;
11634                        }
11635                    };
11636
11637                    let versions = local
11638                        .buffer_snapshots
11639                        .entry(buffer_id)
11640                        .or_default()
11641                        .entry(server_id)
11642                        .and_modify(|_| {
11643                            assert!(
11644                            false,
11645                            "There should not be an existing snapshot for a newly inserted buffer"
11646                        )
11647                        })
11648                        .or_insert_with(|| {
11649                            vec![LspBufferSnapshot {
11650                                version: 0,
11651                                snapshot: buffer.text_snapshot(),
11652                            }]
11653                        });
11654
11655                    let snapshot = versions.last().unwrap();
11656                    let version = snapshot.version;
11657                    let initial_snapshot = &snapshot.snapshot;
11658                    language_server.register_buffer(
11659                        uri,
11660                        adapter.language_id(&language.name()),
11661                        version,
11662                        initial_snapshot.text(),
11663                    );
11664                    buffer_paths_registered.push((buffer_id, abs_path));
11665                    local
11666                        .buffers_opened_in_servers
11667                        .entry(buffer_id)
11668                        .or_default()
11669                        .insert(server_id);
11670                }
11671                buffer_handle.update(cx, |buffer, cx| {
11672                    buffer.set_completion_triggers(
11673                        server_id,
11674                        language_server
11675                            .capabilities()
11676                            .completion_provider
11677                            .as_ref()
11678                            .and_then(|provider| {
11679                                provider
11680                                    .trigger_characters
11681                                    .as_ref()
11682                                    .map(|characters| characters.iter().cloned().collect())
11683                            })
11684                            .unwrap_or_default(),
11685                        cx,
11686                    )
11687                });
11688            }
11689        });
11690
11691        for (buffer_id, abs_path) in buffer_paths_registered {
11692            cx.emit(LspStoreEvent::LanguageServerUpdate {
11693                language_server_id: server_id,
11694                name: Some(adapter.name()),
11695                message: proto::update_language_server::Variant::RegisteredForBuffer(
11696                    proto::RegisteredForBuffer {
11697                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11698                        buffer_id: buffer_id.to_proto(),
11699                    },
11700                ),
11701            });
11702        }
11703
11704        cx.notify();
11705    }
11706
11707    pub fn language_servers_running_disk_based_diagnostics(
11708        &self,
11709    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11710        self.language_server_statuses
11711            .iter()
11712            .filter_map(|(id, status)| {
11713                if status.has_pending_diagnostic_updates {
11714                    Some(*id)
11715                } else {
11716                    None
11717                }
11718            })
11719    }
11720
11721    pub(crate) fn cancel_language_server_work_for_buffers(
11722        &mut self,
11723        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11724        cx: &mut Context<Self>,
11725    ) {
11726        if let Some((client, project_id)) = self.upstream_client() {
11727            let request = client.request(proto::CancelLanguageServerWork {
11728                project_id,
11729                work: Some(proto::cancel_language_server_work::Work::Buffers(
11730                    proto::cancel_language_server_work::Buffers {
11731                        buffer_ids: buffers
11732                            .into_iter()
11733                            .map(|b| b.read(cx).remote_id().to_proto())
11734                            .collect(),
11735                    },
11736                )),
11737            });
11738            cx.background_spawn(request).detach_and_log_err(cx);
11739        } else if let Some(local) = self.as_local() {
11740            let servers = buffers
11741                .into_iter()
11742                .flat_map(|buffer| {
11743                    buffer.update(cx, |buffer, cx| {
11744                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11745                    })
11746                })
11747                .collect::<HashSet<_>>();
11748            for server_id in servers {
11749                self.cancel_language_server_work(server_id, None, cx);
11750            }
11751        }
11752    }
11753
11754    pub(crate) fn cancel_language_server_work(
11755        &mut self,
11756        server_id: LanguageServerId,
11757        token_to_cancel: Option<ProgressToken>,
11758        cx: &mut Context<Self>,
11759    ) {
11760        if let Some(local) = self.as_local() {
11761            let status = self.language_server_statuses.get(&server_id);
11762            let server = local.language_servers.get(&server_id);
11763            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11764            {
11765                for (token, progress) in &status.pending_work {
11766                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11767                        && token != token_to_cancel
11768                    {
11769                        continue;
11770                    }
11771                    if progress.is_cancellable {
11772                        server
11773                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11774                                WorkDoneProgressCancelParams {
11775                                    token: token.to_lsp(),
11776                                },
11777                            )
11778                            .ok();
11779                    }
11780                }
11781            }
11782        } else if let Some((client, project_id)) = self.upstream_client() {
11783            let request = client.request(proto::CancelLanguageServerWork {
11784                project_id,
11785                work: Some(
11786                    proto::cancel_language_server_work::Work::LanguageServerWork(
11787                        proto::cancel_language_server_work::LanguageServerWork {
11788                            language_server_id: server_id.to_proto(),
11789                            token: token_to_cancel.map(|token| token.to_proto()),
11790                        },
11791                    ),
11792                ),
11793            });
11794            cx.background_spawn(request).detach_and_log_err(cx);
11795        }
11796    }
11797
11798    fn register_supplementary_language_server(
11799        &mut self,
11800        id: LanguageServerId,
11801        name: LanguageServerName,
11802        server: Arc<LanguageServer>,
11803        cx: &mut Context<Self>,
11804    ) {
11805        if let Some(local) = self.as_local_mut() {
11806            local
11807                .supplementary_language_servers
11808                .insert(id, (name.clone(), server));
11809            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11810        }
11811    }
11812
11813    fn unregister_supplementary_language_server(
11814        &mut self,
11815        id: LanguageServerId,
11816        cx: &mut Context<Self>,
11817    ) {
11818        if let Some(local) = self.as_local_mut() {
11819            local.supplementary_language_servers.remove(&id);
11820            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11821        }
11822    }
11823
11824    pub(crate) fn supplementary_language_servers(
11825        &self,
11826    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11827        self.as_local().into_iter().flat_map(|local| {
11828            local
11829                .supplementary_language_servers
11830                .iter()
11831                .map(|(id, (name, _))| (*id, name.clone()))
11832        })
11833    }
11834
11835    pub fn language_server_adapter_for_id(
11836        &self,
11837        id: LanguageServerId,
11838    ) -> Option<Arc<CachedLspAdapter>> {
11839        self.as_local()
11840            .and_then(|local| local.language_servers.get(&id))
11841            .and_then(|language_server_state| match language_server_state {
11842                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11843                _ => None,
11844            })
11845    }
11846
11847    pub(super) fn update_local_worktree_language_servers(
11848        &mut self,
11849        worktree_handle: &Entity<Worktree>,
11850        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11851        cx: &mut Context<Self>,
11852    ) {
11853        if changes.is_empty() {
11854            return;
11855        }
11856
11857        let Some(local) = self.as_local() else { return };
11858
11859        local.prettier_store.update(cx, |prettier_store, cx| {
11860            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11861        });
11862
11863        let worktree_id = worktree_handle.read(cx).id();
11864        let mut language_server_ids = local
11865            .language_server_ids
11866            .iter()
11867            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11868            .collect::<Vec<_>>();
11869        language_server_ids.sort();
11870        language_server_ids.dedup();
11871
11872        // let abs_path = worktree_handle.read(cx).abs_path();
11873        for server_id in &language_server_ids {
11874            if let Some(LanguageServerState::Running { server, .. }) =
11875                local.language_servers.get(server_id)
11876                && let Some(watched_paths) = local
11877                    .language_server_watched_paths
11878                    .get(server_id)
11879                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11880            {
11881                let params = lsp::DidChangeWatchedFilesParams {
11882                    changes: changes
11883                        .iter()
11884                        .filter_map(|(path, _, change)| {
11885                            if !watched_paths.is_match(path.as_std_path()) {
11886                                return None;
11887                            }
11888                            let typ = match change {
11889                                PathChange::Loaded => return None,
11890                                PathChange::Added => lsp::FileChangeType::CREATED,
11891                                PathChange::Removed => lsp::FileChangeType::DELETED,
11892                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11893                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11894                            };
11895                            let uri = lsp::Uri::from_file_path(
11896                                worktree_handle.read(cx).absolutize(&path),
11897                            )
11898                            .ok()?;
11899                            Some(lsp::FileEvent { uri, typ })
11900                        })
11901                        .collect(),
11902                };
11903                if !params.changes.is_empty() {
11904                    server
11905                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11906                        .ok();
11907                }
11908            }
11909        }
11910        for (path, _, _) in changes {
11911            if let Some(file_name) = path.file_name()
11912                && local.watched_manifest_filenames.contains(file_name)
11913            {
11914                self.request_workspace_config_refresh();
11915                break;
11916            }
11917        }
11918    }
11919
11920    pub fn wait_for_remote_buffer(
11921        &mut self,
11922        id: BufferId,
11923        cx: &mut Context<Self>,
11924    ) -> Task<Result<Entity<Buffer>>> {
11925        self.buffer_store.update(cx, |buffer_store, cx| {
11926            buffer_store.wait_for_remote_buffer(id, cx)
11927        })
11928    }
11929
11930    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11931        let mut result = proto::Symbol {
11932            language_server_name: symbol.language_server_name.0.to_string(),
11933            source_worktree_id: symbol.source_worktree_id.to_proto(),
11934            language_server_id: symbol.source_language_server_id.to_proto(),
11935            name: symbol.name.clone(),
11936            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11937            start: Some(proto::PointUtf16 {
11938                row: symbol.range.start.0.row,
11939                column: symbol.range.start.0.column,
11940            }),
11941            end: Some(proto::PointUtf16 {
11942                row: symbol.range.end.0.row,
11943                column: symbol.range.end.0.column,
11944            }),
11945            worktree_id: Default::default(),
11946            path: Default::default(),
11947            signature: Default::default(),
11948            container_name: symbol.container_name.clone(),
11949        };
11950        match &symbol.path {
11951            SymbolLocation::InProject(path) => {
11952                result.worktree_id = path.worktree_id.to_proto();
11953                result.path = path.path.to_proto();
11954            }
11955            SymbolLocation::OutsideProject {
11956                abs_path,
11957                signature,
11958            } => {
11959                result.path = abs_path.to_string_lossy().into_owned();
11960                result.signature = signature.to_vec();
11961            }
11962        }
11963        result
11964    }
11965
11966    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11967        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11968        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11969        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11970
11971        let path = if serialized_symbol.signature.is_empty() {
11972            SymbolLocation::InProject(ProjectPath {
11973                worktree_id,
11974                path: RelPath::from_proto(&serialized_symbol.path)
11975                    .context("invalid symbol path")?,
11976            })
11977        } else {
11978            SymbolLocation::OutsideProject {
11979                abs_path: Path::new(&serialized_symbol.path).into(),
11980                signature: serialized_symbol
11981                    .signature
11982                    .try_into()
11983                    .map_err(|_| anyhow!("invalid signature"))?,
11984            }
11985        };
11986
11987        let start = serialized_symbol.start.context("invalid start")?;
11988        let end = serialized_symbol.end.context("invalid end")?;
11989        Ok(CoreSymbol {
11990            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11991            source_worktree_id,
11992            source_language_server_id: LanguageServerId::from_proto(
11993                serialized_symbol.language_server_id,
11994            ),
11995            path,
11996            name: serialized_symbol.name,
11997            range: Unclipped(PointUtf16::new(start.row, start.column))
11998                ..Unclipped(PointUtf16::new(end.row, end.column)),
11999            kind,
12000            container_name: serialized_symbol.container_name,
12001        })
12002    }
12003
12004    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12005        let mut serialized_completion = proto::Completion {
12006            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12007            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12008            new_text: completion.new_text.clone(),
12009            ..proto::Completion::default()
12010        };
12011        match &completion.source {
12012            CompletionSource::Lsp {
12013                insert_range,
12014                server_id,
12015                lsp_completion,
12016                lsp_defaults,
12017                resolved,
12018            } => {
12019                let (old_insert_start, old_insert_end) = insert_range
12020                    .as_ref()
12021                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12022                    .unzip();
12023
12024                serialized_completion.old_insert_start = old_insert_start;
12025                serialized_completion.old_insert_end = old_insert_end;
12026                serialized_completion.source = proto::completion::Source::Lsp as i32;
12027                serialized_completion.server_id = server_id.0 as u64;
12028                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12029                serialized_completion.lsp_defaults = lsp_defaults
12030                    .as_deref()
12031                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12032                serialized_completion.resolved = *resolved;
12033            }
12034            CompletionSource::BufferWord {
12035                word_range,
12036                resolved,
12037            } => {
12038                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12039                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12040                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12041                serialized_completion.resolved = *resolved;
12042            }
12043            CompletionSource::Custom => {
12044                serialized_completion.source = proto::completion::Source::Custom as i32;
12045                serialized_completion.resolved = true;
12046            }
12047            CompletionSource::Dap { sort_text } => {
12048                serialized_completion.source = proto::completion::Source::Dap as i32;
12049                serialized_completion.sort_text = Some(sort_text.clone());
12050            }
12051        }
12052
12053        serialized_completion
12054    }
12055
12056    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12057        let old_replace_start = completion
12058            .old_replace_start
12059            .and_then(deserialize_anchor)
12060            .context("invalid old start")?;
12061        let old_replace_end = completion
12062            .old_replace_end
12063            .and_then(deserialize_anchor)
12064            .context("invalid old end")?;
12065        let insert_range = {
12066            match completion.old_insert_start.zip(completion.old_insert_end) {
12067                Some((start, end)) => {
12068                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12069                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12070                    Some(start..end)
12071                }
12072                None => None,
12073            }
12074        };
12075        Ok(CoreCompletion {
12076            replace_range: old_replace_start..old_replace_end,
12077            new_text: completion.new_text,
12078            source: match proto::completion::Source::from_i32(completion.source) {
12079                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12080                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12081                    insert_range,
12082                    server_id: LanguageServerId::from_proto(completion.server_id),
12083                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12084                    lsp_defaults: completion
12085                        .lsp_defaults
12086                        .as_deref()
12087                        .map(serde_json::from_slice)
12088                        .transpose()?,
12089                    resolved: completion.resolved,
12090                },
12091                Some(proto::completion::Source::BufferWord) => {
12092                    let word_range = completion
12093                        .buffer_word_start
12094                        .and_then(deserialize_anchor)
12095                        .context("invalid buffer word start")?
12096                        ..completion
12097                            .buffer_word_end
12098                            .and_then(deserialize_anchor)
12099                            .context("invalid buffer word end")?;
12100                    CompletionSource::BufferWord {
12101                        word_range,
12102                        resolved: completion.resolved,
12103                    }
12104                }
12105                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12106                    sort_text: completion
12107                        .sort_text
12108                        .context("expected sort text to exist")?,
12109                },
12110                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12111            },
12112        })
12113    }
12114
12115    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12116        let (kind, lsp_action) = match &action.lsp_action {
12117            LspAction::Action(code_action) => (
12118                proto::code_action::Kind::Action as i32,
12119                serde_json::to_vec(code_action).unwrap(),
12120            ),
12121            LspAction::Command(command) => (
12122                proto::code_action::Kind::Command as i32,
12123                serde_json::to_vec(command).unwrap(),
12124            ),
12125            LspAction::CodeLens(code_lens) => (
12126                proto::code_action::Kind::CodeLens as i32,
12127                serde_json::to_vec(code_lens).unwrap(),
12128            ),
12129        };
12130
12131        proto::CodeAction {
12132            server_id: action.server_id.0 as u64,
12133            start: Some(serialize_anchor(&action.range.start)),
12134            end: Some(serialize_anchor(&action.range.end)),
12135            lsp_action,
12136            kind,
12137            resolved: action.resolved,
12138        }
12139    }
12140
12141    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12142        let start = action
12143            .start
12144            .and_then(deserialize_anchor)
12145            .context("invalid start")?;
12146        let end = action
12147            .end
12148            .and_then(deserialize_anchor)
12149            .context("invalid end")?;
12150        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12151            Some(proto::code_action::Kind::Action) => {
12152                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12153            }
12154            Some(proto::code_action::Kind::Command) => {
12155                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12156            }
12157            Some(proto::code_action::Kind::CodeLens) => {
12158                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12159            }
12160            None => anyhow::bail!("Unknown action kind {}", action.kind),
12161        };
12162        Ok(CodeAction {
12163            server_id: LanguageServerId(action.server_id as usize),
12164            range: start..end,
12165            resolved: action.resolved,
12166            lsp_action,
12167        })
12168    }
12169
12170    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12171        match &formatting_result {
12172            Ok(_) => self.last_formatting_failure = None,
12173            Err(error) => {
12174                let error_string = format!("{error:#}");
12175                log::error!("Formatting failed: {error_string}");
12176                self.last_formatting_failure
12177                    .replace(error_string.lines().join(" "));
12178            }
12179        }
12180    }
12181
12182    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12183        self.lsp_server_capabilities.remove(&for_server);
12184        self.semantic_token_config.remove_server_data(for_server);
12185        for lsp_data in self.lsp_data.values_mut() {
12186            lsp_data.remove_server_data(for_server);
12187        }
12188        if let Some(local) = self.as_local_mut() {
12189            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12190            local
12191                .workspace_pull_diagnostics_result_ids
12192                .remove(&for_server);
12193            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12194                buffer_servers.remove(&for_server);
12195            }
12196        }
12197    }
12198
12199    pub fn result_id_for_buffer_pull(
12200        &self,
12201        server_id: LanguageServerId,
12202        buffer_id: BufferId,
12203        registration_id: &Option<SharedString>,
12204        cx: &App,
12205    ) -> Option<SharedString> {
12206        let abs_path = self
12207            .buffer_store
12208            .read(cx)
12209            .get(buffer_id)
12210            .and_then(|b| File::from_dyn(b.read(cx).file()))
12211            .map(|f| f.abs_path(cx))?;
12212        self.as_local()?
12213            .buffer_pull_diagnostics_result_ids
12214            .get(&server_id)?
12215            .get(registration_id)?
12216            .get(&abs_path)?
12217            .clone()
12218    }
12219
12220    /// Gets all result_ids for a workspace diagnostics pull request.
12221    /// 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.
12222    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12223    pub fn result_ids_for_workspace_refresh(
12224        &self,
12225        server_id: LanguageServerId,
12226        registration_id: &Option<SharedString>,
12227    ) -> HashMap<PathBuf, SharedString> {
12228        let Some(local) = self.as_local() else {
12229            return HashMap::default();
12230        };
12231        local
12232            .workspace_pull_diagnostics_result_ids
12233            .get(&server_id)
12234            .into_iter()
12235            .filter_map(|diagnostics| diagnostics.get(registration_id))
12236            .flatten()
12237            .filter_map(|(abs_path, result_id)| {
12238                let result_id = local
12239                    .buffer_pull_diagnostics_result_ids
12240                    .get(&server_id)
12241                    .and_then(|buffer_ids_result_ids| {
12242                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12243                    })
12244                    .cloned()
12245                    .flatten()
12246                    .or_else(|| result_id.clone())?;
12247                Some((abs_path.clone(), result_id))
12248            })
12249            .collect()
12250    }
12251
12252    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12253        if let Some(LanguageServerState::Running {
12254            workspace_diagnostics_refresh_tasks,
12255            ..
12256        }) = self
12257            .as_local_mut()
12258            .and_then(|local| local.language_servers.get_mut(&server_id))
12259        {
12260            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12261                diagnostics.refresh_tx.try_send(()).ok();
12262            }
12263        }
12264    }
12265
12266    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12267    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12268    /// which requires refreshing both workspace and document diagnostics.
12269    pub fn pull_document_diagnostics_for_server(
12270        &mut self,
12271        server_id: LanguageServerId,
12272        source_buffer_id: Option<BufferId>,
12273        cx: &mut Context<Self>,
12274    ) -> Shared<Task<()>> {
12275        let Some(local) = self.as_local_mut() else {
12276            return Task::ready(()).shared();
12277        };
12278        let mut buffers_to_refresh = HashSet::default();
12279        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12280            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12281                buffers_to_refresh.insert(*buffer_id);
12282            }
12283        }
12284
12285        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12286    }
12287
12288    pub fn pull_document_diagnostics_for_buffer_edit(
12289        &mut self,
12290        buffer_id: BufferId,
12291        cx: &mut Context<Self>,
12292    ) {
12293        let Some(local) = self.as_local_mut() else {
12294            return;
12295        };
12296        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12297        else {
12298            return;
12299        };
12300        for server_id in languages_servers {
12301            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12302        }
12303    }
12304
12305    fn apply_workspace_diagnostic_report(
12306        &mut self,
12307        server_id: LanguageServerId,
12308        report: lsp::WorkspaceDiagnosticReportResult,
12309        registration_id: Option<SharedString>,
12310        cx: &mut Context<Self>,
12311    ) {
12312        let mut workspace_diagnostics =
12313            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12314                report,
12315                server_id,
12316                registration_id,
12317            );
12318        workspace_diagnostics.retain(|d| match &d.diagnostics {
12319            LspPullDiagnostics::Response {
12320                server_id,
12321                registration_id,
12322                ..
12323            } => self.diagnostic_registration_exists(*server_id, registration_id),
12324            LspPullDiagnostics::Default => false,
12325        });
12326        let mut unchanged_buffers = HashMap::default();
12327        let workspace_diagnostics_updates = workspace_diagnostics
12328            .into_iter()
12329            .filter_map(
12330                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12331                    LspPullDiagnostics::Response {
12332                        server_id,
12333                        uri,
12334                        diagnostics,
12335                        registration_id,
12336                    } => Some((
12337                        server_id,
12338                        uri,
12339                        diagnostics,
12340                        workspace_diagnostics.version,
12341                        registration_id,
12342                    )),
12343                    LspPullDiagnostics::Default => None,
12344                },
12345            )
12346            .fold(
12347                HashMap::default(),
12348                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12349                    let (result_id, diagnostics) = match diagnostics {
12350                        PulledDiagnostics::Unchanged { result_id } => {
12351                            unchanged_buffers
12352                                .entry(new_registration_id.clone())
12353                                .or_insert_with(HashSet::default)
12354                                .insert(uri.clone());
12355                            (Some(result_id), Vec::new())
12356                        }
12357                        PulledDiagnostics::Changed {
12358                            result_id,
12359                            diagnostics,
12360                        } => (result_id, diagnostics),
12361                    };
12362                    let disk_based_sources = Cow::Owned(
12363                        self.language_server_adapter_for_id(server_id)
12364                            .as_ref()
12365                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12366                            .unwrap_or(&[])
12367                            .to_vec(),
12368                    );
12369
12370                    let Some(abs_path) = uri.to_file_path().ok() else {
12371                        return acc;
12372                    };
12373                    let Some((worktree, relative_path)) =
12374                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12375                    else {
12376                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12377                        return acc;
12378                    };
12379                    let worktree_id = worktree.read(cx).id();
12380                    let project_path = ProjectPath {
12381                        worktree_id,
12382                        path: relative_path,
12383                    };
12384                    if let Some(local_lsp_store) = self.as_local_mut() {
12385                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12386                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12387                    }
12388                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12389                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12390                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12391                        acc.entry(server_id)
12392                            .or_insert_with(HashMap::default)
12393                            .entry(new_registration_id.clone())
12394                            .or_insert_with(Vec::new)
12395                            .push(DocumentDiagnosticsUpdate {
12396                                server_id,
12397                                diagnostics: lsp::PublishDiagnosticsParams {
12398                                    uri,
12399                                    diagnostics,
12400                                    version,
12401                                },
12402                                result_id: result_id.map(SharedString::new),
12403                                disk_based_sources,
12404                                registration_id: new_registration_id,
12405                            });
12406                    }
12407                    acc
12408                },
12409            );
12410
12411        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12412            for (registration_id, diagnostic_updates) in diagnostic_updates {
12413                self.merge_lsp_diagnostics(
12414                    DiagnosticSourceKind::Pulled,
12415                    diagnostic_updates,
12416                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12417                        DiagnosticSourceKind::Pulled => {
12418                            old_diagnostic.registration_id != registration_id
12419                                || unchanged_buffers
12420                                    .get(&old_diagnostic.registration_id)
12421                                    .is_some_and(|unchanged_buffers| {
12422                                        unchanged_buffers.contains(&document_uri)
12423                                    })
12424                        }
12425                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12426                    },
12427                    cx,
12428                )
12429                .log_err();
12430            }
12431        }
12432    }
12433
12434    fn register_server_capabilities(
12435        &mut self,
12436        server_id: LanguageServerId,
12437        params: lsp::RegistrationParams,
12438        cx: &mut Context<Self>,
12439    ) -> anyhow::Result<()> {
12440        let server = self
12441            .language_server_for_id(server_id)
12442            .with_context(|| format!("no server {server_id} found"))?;
12443        for reg in params.registrations {
12444            match reg.method.as_str() {
12445                "workspace/didChangeWatchedFiles" => {
12446                    if let Some(options) = reg.register_options {
12447                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12448                            let caps = serde_json::from_value(options)?;
12449                            local_lsp_store
12450                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12451                            true
12452                        } else {
12453                            false
12454                        };
12455                        if notify {
12456                            notify_server_capabilities_updated(&server, cx);
12457                        }
12458                    }
12459                }
12460                "workspace/didChangeConfiguration" => {
12461                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12462                }
12463                "workspace/didChangeWorkspaceFolders" => {
12464                    // In this case register options is an empty object, we can ignore it
12465                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12466                        supported: Some(true),
12467                        change_notifications: Some(OneOf::Right(reg.id)),
12468                    };
12469                    server.update_capabilities(|capabilities| {
12470                        capabilities
12471                            .workspace
12472                            .get_or_insert_default()
12473                            .workspace_folders = Some(caps);
12474                    });
12475                    notify_server_capabilities_updated(&server, cx);
12476                }
12477                "workspace/symbol" => {
12478                    let options = parse_register_capabilities(reg)?;
12479                    server.update_capabilities(|capabilities| {
12480                        capabilities.workspace_symbol_provider = Some(options);
12481                    });
12482                    notify_server_capabilities_updated(&server, cx);
12483                }
12484                "workspace/fileOperations" => {
12485                    if let Some(options) = reg.register_options {
12486                        let caps = serde_json::from_value(options)?;
12487                        server.update_capabilities(|capabilities| {
12488                            capabilities
12489                                .workspace
12490                                .get_or_insert_default()
12491                                .file_operations = Some(caps);
12492                        });
12493                        notify_server_capabilities_updated(&server, cx);
12494                    }
12495                }
12496                "workspace/executeCommand" => {
12497                    if let Some(options) = reg.register_options {
12498                        let options = serde_json::from_value(options)?;
12499                        server.update_capabilities(|capabilities| {
12500                            capabilities.execute_command_provider = Some(options);
12501                        });
12502                        notify_server_capabilities_updated(&server, cx);
12503                    }
12504                }
12505                "textDocument/rangeFormatting" => {
12506                    let options = parse_register_capabilities(reg)?;
12507                    server.update_capabilities(|capabilities| {
12508                        capabilities.document_range_formatting_provider = Some(options);
12509                    });
12510                    notify_server_capabilities_updated(&server, cx);
12511                }
12512                "textDocument/onTypeFormatting" => {
12513                    if let Some(options) = reg
12514                        .register_options
12515                        .map(serde_json::from_value)
12516                        .transpose()?
12517                    {
12518                        server.update_capabilities(|capabilities| {
12519                            capabilities.document_on_type_formatting_provider = Some(options);
12520                        });
12521                        notify_server_capabilities_updated(&server, cx);
12522                    }
12523                }
12524                "textDocument/formatting" => {
12525                    let options = parse_register_capabilities(reg)?;
12526                    server.update_capabilities(|capabilities| {
12527                        capabilities.document_formatting_provider = Some(options);
12528                    });
12529                    notify_server_capabilities_updated(&server, cx);
12530                }
12531                "textDocument/rename" => {
12532                    let options = parse_register_capabilities(reg)?;
12533                    server.update_capabilities(|capabilities| {
12534                        capabilities.rename_provider = Some(options);
12535                    });
12536                    notify_server_capabilities_updated(&server, cx);
12537                }
12538                "textDocument/inlayHint" => {
12539                    let options = parse_register_capabilities(reg)?;
12540                    server.update_capabilities(|capabilities| {
12541                        capabilities.inlay_hint_provider = Some(options);
12542                    });
12543                    notify_server_capabilities_updated(&server, cx);
12544                }
12545                "textDocument/documentSymbol" => {
12546                    let options = parse_register_capabilities(reg)?;
12547                    server.update_capabilities(|capabilities| {
12548                        capabilities.document_symbol_provider = Some(options);
12549                    });
12550                    notify_server_capabilities_updated(&server, cx);
12551                }
12552                "textDocument/codeAction" => {
12553                    let options = parse_register_capabilities(reg)?;
12554                    let provider = match options {
12555                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12556                        OneOf::Right(caps) => caps,
12557                    };
12558                    server.update_capabilities(|capabilities| {
12559                        capabilities.code_action_provider = Some(provider);
12560                    });
12561                    notify_server_capabilities_updated(&server, cx);
12562                }
12563                "textDocument/definition" => {
12564                    let options = parse_register_capabilities(reg)?;
12565                    server.update_capabilities(|capabilities| {
12566                        capabilities.definition_provider = Some(options);
12567                    });
12568                    notify_server_capabilities_updated(&server, cx);
12569                }
12570                "textDocument/completion" => {
12571                    if let Some(caps) = reg
12572                        .register_options
12573                        .map(serde_json::from_value::<CompletionOptions>)
12574                        .transpose()?
12575                    {
12576                        server.update_capabilities(|capabilities| {
12577                            capabilities.completion_provider = Some(caps.clone());
12578                        });
12579
12580                        if let Some(local) = self.as_local() {
12581                            let mut buffers_with_language_server = Vec::new();
12582                            for handle in self.buffer_store.read(cx).buffers() {
12583                                let buffer_id = handle.read(cx).remote_id();
12584                                if local
12585                                    .buffers_opened_in_servers
12586                                    .get(&buffer_id)
12587                                    .filter(|s| s.contains(&server_id))
12588                                    .is_some()
12589                                {
12590                                    buffers_with_language_server.push(handle);
12591                                }
12592                            }
12593                            let triggers = caps
12594                                .trigger_characters
12595                                .unwrap_or_default()
12596                                .into_iter()
12597                                .collect::<BTreeSet<_>>();
12598                            for handle in buffers_with_language_server {
12599                                let triggers = triggers.clone();
12600                                let _ = handle.update(cx, move |buffer, cx| {
12601                                    buffer.set_completion_triggers(server_id, triggers, cx);
12602                                });
12603                            }
12604                        }
12605                        notify_server_capabilities_updated(&server, cx);
12606                    }
12607                }
12608                "textDocument/hover" => {
12609                    let options = parse_register_capabilities(reg)?;
12610                    let provider = match options {
12611                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12612                        OneOf::Right(caps) => caps,
12613                    };
12614                    server.update_capabilities(|capabilities| {
12615                        capabilities.hover_provider = Some(provider);
12616                    });
12617                    notify_server_capabilities_updated(&server, cx);
12618                }
12619                "textDocument/signatureHelp" => {
12620                    if let Some(caps) = reg
12621                        .register_options
12622                        .map(serde_json::from_value)
12623                        .transpose()?
12624                    {
12625                        server.update_capabilities(|capabilities| {
12626                            capabilities.signature_help_provider = Some(caps);
12627                        });
12628                        notify_server_capabilities_updated(&server, cx);
12629                    }
12630                }
12631                "textDocument/didChange" => {
12632                    if let Some(sync_kind) = reg
12633                        .register_options
12634                        .and_then(|opts| opts.get("syncKind").cloned())
12635                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12636                        .transpose()?
12637                    {
12638                        server.update_capabilities(|capabilities| {
12639                            let mut sync_options =
12640                                Self::take_text_document_sync_options(capabilities);
12641                            sync_options.change = Some(sync_kind);
12642                            capabilities.text_document_sync =
12643                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12644                        });
12645                        notify_server_capabilities_updated(&server, cx);
12646                    }
12647                }
12648                "textDocument/didSave" => {
12649                    if let Some(include_text) = reg
12650                        .register_options
12651                        .map(|opts| {
12652                            let transpose = opts
12653                                .get("includeText")
12654                                .cloned()
12655                                .map(serde_json::from_value::<Option<bool>>)
12656                                .transpose();
12657                            match transpose {
12658                                Ok(value) => Ok(value.flatten()),
12659                                Err(e) => Err(e),
12660                            }
12661                        })
12662                        .transpose()?
12663                    {
12664                        server.update_capabilities(|capabilities| {
12665                            let mut sync_options =
12666                                Self::take_text_document_sync_options(capabilities);
12667                            sync_options.save =
12668                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12669                                    include_text,
12670                                }));
12671                            capabilities.text_document_sync =
12672                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12673                        });
12674                        notify_server_capabilities_updated(&server, cx);
12675                    }
12676                }
12677                "textDocument/codeLens" => {
12678                    if let Some(caps) = reg
12679                        .register_options
12680                        .map(serde_json::from_value)
12681                        .transpose()?
12682                    {
12683                        server.update_capabilities(|capabilities| {
12684                            capabilities.code_lens_provider = Some(caps);
12685                        });
12686                        notify_server_capabilities_updated(&server, cx);
12687                    }
12688                }
12689                "textDocument/diagnostic" => {
12690                    if let Some(caps) = reg
12691                        .register_options
12692                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12693                        .transpose()?
12694                    {
12695                        let local = self
12696                            .as_local_mut()
12697                            .context("Expected LSP Store to be local")?;
12698                        let state = local
12699                            .language_servers
12700                            .get_mut(&server_id)
12701                            .context("Could not obtain Language Servers state")?;
12702                        local
12703                            .language_server_dynamic_registrations
12704                            .entry(server_id)
12705                            .or_default()
12706                            .diagnostics
12707                            .insert(Some(reg.id.clone()), caps.clone());
12708
12709                        let supports_workspace_diagnostics =
12710                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12711                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12712                                    diagnostic_options.workspace_diagnostics
12713                                }
12714                                DiagnosticServerCapabilities::RegistrationOptions(
12715                                    diagnostic_registration_options,
12716                                ) => {
12717                                    diagnostic_registration_options
12718                                        .diagnostic_options
12719                                        .workspace_diagnostics
12720                                }
12721                            };
12722
12723                        if supports_workspace_diagnostics(&caps) {
12724                            if let LanguageServerState::Running {
12725                                workspace_diagnostics_refresh_tasks,
12726                                ..
12727                            } = state
12728                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12729                                    Some(reg.id.clone()),
12730                                    caps.clone(),
12731                                    server.clone(),
12732                                    cx,
12733                                )
12734                            {
12735                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12736                            }
12737                        }
12738
12739                        server.update_capabilities(|capabilities| {
12740                            capabilities.diagnostic_provider = Some(caps);
12741                        });
12742
12743                        notify_server_capabilities_updated(&server, cx);
12744
12745                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12746                    }
12747                }
12748                "textDocument/documentColor" => {
12749                    let options = parse_register_capabilities(reg)?;
12750                    let provider = match options {
12751                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12752                        OneOf::Right(caps) => caps,
12753                    };
12754                    server.update_capabilities(|capabilities| {
12755                        capabilities.color_provider = Some(provider);
12756                    });
12757                    notify_server_capabilities_updated(&server, cx);
12758                }
12759                "textDocument/foldingRange" => {
12760                    let options = parse_register_capabilities(reg)?;
12761                    let provider = match options {
12762                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12763                        OneOf::Right(caps) => caps,
12764                    };
12765                    server.update_capabilities(|capabilities| {
12766                        capabilities.folding_range_provider = Some(provider);
12767                    });
12768                    notify_server_capabilities_updated(&server, cx);
12769                }
12770                _ => log::warn!("unhandled capability registration: {reg:?}"),
12771            }
12772        }
12773
12774        Ok(())
12775    }
12776
12777    fn unregister_server_capabilities(
12778        &mut self,
12779        server_id: LanguageServerId,
12780        params: lsp::UnregistrationParams,
12781        cx: &mut Context<Self>,
12782    ) -> anyhow::Result<()> {
12783        let server = self
12784            .language_server_for_id(server_id)
12785            .with_context(|| format!("no server {server_id} found"))?;
12786        for unreg in params.unregisterations.iter() {
12787            match unreg.method.as_str() {
12788                "workspace/didChangeWatchedFiles" => {
12789                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12790                        local_lsp_store
12791                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12792                        true
12793                    } else {
12794                        false
12795                    };
12796                    if notify {
12797                        notify_server_capabilities_updated(&server, cx);
12798                    }
12799                }
12800                "workspace/didChangeConfiguration" => {
12801                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12802                }
12803                "workspace/didChangeWorkspaceFolders" => {
12804                    server.update_capabilities(|capabilities| {
12805                        capabilities
12806                            .workspace
12807                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12808                                workspace_folders: None,
12809                                file_operations: None,
12810                            })
12811                            .workspace_folders = None;
12812                    });
12813                    notify_server_capabilities_updated(&server, cx);
12814                }
12815                "workspace/symbol" => {
12816                    server.update_capabilities(|capabilities| {
12817                        capabilities.workspace_symbol_provider = None
12818                    });
12819                    notify_server_capabilities_updated(&server, cx);
12820                }
12821                "workspace/fileOperations" => {
12822                    server.update_capabilities(|capabilities| {
12823                        capabilities
12824                            .workspace
12825                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12826                                workspace_folders: None,
12827                                file_operations: None,
12828                            })
12829                            .file_operations = None;
12830                    });
12831                    notify_server_capabilities_updated(&server, cx);
12832                }
12833                "workspace/executeCommand" => {
12834                    server.update_capabilities(|capabilities| {
12835                        capabilities.execute_command_provider = None;
12836                    });
12837                    notify_server_capabilities_updated(&server, cx);
12838                }
12839                "textDocument/rangeFormatting" => {
12840                    server.update_capabilities(|capabilities| {
12841                        capabilities.document_range_formatting_provider = None
12842                    });
12843                    notify_server_capabilities_updated(&server, cx);
12844                }
12845                "textDocument/onTypeFormatting" => {
12846                    server.update_capabilities(|capabilities| {
12847                        capabilities.document_on_type_formatting_provider = None;
12848                    });
12849                    notify_server_capabilities_updated(&server, cx);
12850                }
12851                "textDocument/formatting" => {
12852                    server.update_capabilities(|capabilities| {
12853                        capabilities.document_formatting_provider = None;
12854                    });
12855                    notify_server_capabilities_updated(&server, cx);
12856                }
12857                "textDocument/rename" => {
12858                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12859                    notify_server_capabilities_updated(&server, cx);
12860                }
12861                "textDocument/codeAction" => {
12862                    server.update_capabilities(|capabilities| {
12863                        capabilities.code_action_provider = None;
12864                    });
12865                    notify_server_capabilities_updated(&server, cx);
12866                }
12867                "textDocument/definition" => {
12868                    server.update_capabilities(|capabilities| {
12869                        capabilities.definition_provider = None;
12870                    });
12871                    notify_server_capabilities_updated(&server, cx);
12872                }
12873                "textDocument/completion" => {
12874                    server.update_capabilities(|capabilities| {
12875                        capabilities.completion_provider = None;
12876                    });
12877                    notify_server_capabilities_updated(&server, cx);
12878                }
12879                "textDocument/hover" => {
12880                    server.update_capabilities(|capabilities| {
12881                        capabilities.hover_provider = None;
12882                    });
12883                    notify_server_capabilities_updated(&server, cx);
12884                }
12885                "textDocument/signatureHelp" => {
12886                    server.update_capabilities(|capabilities| {
12887                        capabilities.signature_help_provider = None;
12888                    });
12889                    notify_server_capabilities_updated(&server, cx);
12890                }
12891                "textDocument/didChange" => {
12892                    server.update_capabilities(|capabilities| {
12893                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12894                        sync_options.change = None;
12895                        capabilities.text_document_sync =
12896                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12897                    });
12898                    notify_server_capabilities_updated(&server, cx);
12899                }
12900                "textDocument/didSave" => {
12901                    server.update_capabilities(|capabilities| {
12902                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12903                        sync_options.save = None;
12904                        capabilities.text_document_sync =
12905                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12906                    });
12907                    notify_server_capabilities_updated(&server, cx);
12908                }
12909                "textDocument/codeLens" => {
12910                    server.update_capabilities(|capabilities| {
12911                        capabilities.code_lens_provider = None;
12912                    });
12913                    notify_server_capabilities_updated(&server, cx);
12914                }
12915                "textDocument/diagnostic" => {
12916                    let local = self
12917                        .as_local_mut()
12918                        .context("Expected LSP Store to be local")?;
12919
12920                    let state = local
12921                        .language_servers
12922                        .get_mut(&server_id)
12923                        .context("Could not obtain Language Servers state")?;
12924                    let registrations = local
12925                        .language_server_dynamic_registrations
12926                        .get_mut(&server_id)
12927                        .with_context(|| {
12928                            format!("Expected dynamic registration to exist for server {server_id}")
12929                        })?;
12930                    registrations.diagnostics
12931                        .remove(&Some(unreg.id.clone()))
12932                        .with_context(|| format!(
12933                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12934                            unreg.id)
12935                        )?;
12936                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12937
12938                    if let LanguageServerState::Running {
12939                        workspace_diagnostics_refresh_tasks,
12940                        ..
12941                    } = state
12942                    {
12943                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12944                    }
12945
12946                    self.clear_unregistered_diagnostics(
12947                        server_id,
12948                        SharedString::from(unreg.id.clone()),
12949                        cx,
12950                    )?;
12951
12952                    if removed_last_diagnostic_provider {
12953                        server.update_capabilities(|capabilities| {
12954                            debug_assert!(capabilities.diagnostic_provider.is_some());
12955                            capabilities.diagnostic_provider = None;
12956                        });
12957                    }
12958
12959                    notify_server_capabilities_updated(&server, cx);
12960                }
12961                "textDocument/documentColor" => {
12962                    server.update_capabilities(|capabilities| {
12963                        capabilities.color_provider = None;
12964                    });
12965                    notify_server_capabilities_updated(&server, cx);
12966                }
12967                "textDocument/foldingRange" => {
12968                    server.update_capabilities(|capabilities| {
12969                        capabilities.folding_range_provider = None;
12970                    });
12971                    notify_server_capabilities_updated(&server, cx);
12972                }
12973                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12974            }
12975        }
12976
12977        Ok(())
12978    }
12979
12980    fn clear_unregistered_diagnostics(
12981        &mut self,
12982        server_id: LanguageServerId,
12983        cleared_registration_id: SharedString,
12984        cx: &mut Context<Self>,
12985    ) -> anyhow::Result<()> {
12986        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12987
12988        self.buffer_store.update(cx, |buffer_store, cx| {
12989            for buffer_handle in buffer_store.buffers() {
12990                let buffer = buffer_handle.read(cx);
12991                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12992                let Some(abs_path) = abs_path else {
12993                    continue;
12994                };
12995                affected_abs_paths.insert(abs_path);
12996            }
12997        });
12998
12999        let local = self.as_local().context("Expected LSP Store to be local")?;
13000        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13001            let Some(worktree) = self
13002                .worktree_store
13003                .read(cx)
13004                .worktree_for_id(*worktree_id, cx)
13005            else {
13006                continue;
13007            };
13008
13009            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13010                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13011                    let has_matching_registration =
13012                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13013                            entry.diagnostic.registration_id.as_ref()
13014                                == Some(&cleared_registration_id)
13015                        });
13016                    if has_matching_registration {
13017                        let abs_path = worktree.read(cx).absolutize(rel_path);
13018                        affected_abs_paths.insert(abs_path);
13019                    }
13020                }
13021            }
13022        }
13023
13024        if affected_abs_paths.is_empty() {
13025            return Ok(());
13026        }
13027
13028        // Send a fake diagnostic update which clears the state for the registration ID
13029        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13030            affected_abs_paths
13031                .into_iter()
13032                .map(|abs_path| DocumentDiagnosticsUpdate {
13033                    diagnostics: DocumentDiagnostics {
13034                        diagnostics: Vec::new(),
13035                        document_abs_path: abs_path,
13036                        version: None,
13037                    },
13038                    result_id: None,
13039                    registration_id: Some(cleared_registration_id.clone()),
13040                    server_id,
13041                    disk_based_sources: Cow::Borrowed(&[]),
13042                })
13043                .collect();
13044
13045        let merge_registration_id = cleared_registration_id.clone();
13046        self.merge_diagnostic_entries(
13047            clears,
13048            move |_, diagnostic, _| {
13049                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13050                    diagnostic.registration_id != Some(merge_registration_id.clone())
13051                } else {
13052                    true
13053                }
13054            },
13055            cx,
13056        )?;
13057
13058        Ok(())
13059    }
13060
13061    async fn deduplicate_range_based_lsp_requests<T>(
13062        lsp_store: &Entity<Self>,
13063        server_id: Option<LanguageServerId>,
13064        lsp_request_id: LspRequestId,
13065        proto_request: &T::ProtoRequest,
13066        range: Range<Anchor>,
13067        cx: &mut AsyncApp,
13068    ) -> Result<()>
13069    where
13070        T: LspCommand,
13071        T::ProtoRequest: proto::LspRequestMessage,
13072    {
13073        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13074        let version = deserialize_version(proto_request.buffer_version());
13075        let buffer = lsp_store.update(cx, |this, cx| {
13076            this.buffer_store.read(cx).get_existing(buffer_id)
13077        })?;
13078        buffer
13079            .update(cx, |buffer, _| buffer.wait_for_version(version))
13080            .await?;
13081        lsp_store.update(cx, |lsp_store, cx| {
13082            let buffer_snapshot = buffer.read(cx).snapshot();
13083            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13084            let chunks_queried_for = lsp_data
13085                .inlay_hints
13086                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13087                .collect::<Vec<_>>();
13088            match chunks_queried_for.as_slice() {
13089                &[chunk] => {
13090                    let key = LspKey {
13091                        request_type: TypeId::of::<T>(),
13092                        server_queried: server_id,
13093                    };
13094                    let previous_request = lsp_data
13095                        .chunk_lsp_requests
13096                        .entry(key)
13097                        .or_default()
13098                        .insert(chunk, lsp_request_id);
13099                    if let Some((previous_request, running_requests)) =
13100                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13101                    {
13102                        running_requests.remove(&previous_request);
13103                    }
13104                }
13105                _ambiguous_chunks => {
13106                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13107                    // there, a buffer version-based check will be performed and outdated requests discarded.
13108                }
13109            }
13110            anyhow::Ok(())
13111        })?;
13112
13113        Ok(())
13114    }
13115
13116    async fn query_lsp_locally<T>(
13117        lsp_store: Entity<Self>,
13118        for_server_id: Option<LanguageServerId>,
13119        sender_id: proto::PeerId,
13120        lsp_request_id: LspRequestId,
13121        proto_request: T::ProtoRequest,
13122        position: Option<Anchor>,
13123        cx: &mut AsyncApp,
13124    ) -> Result<()>
13125    where
13126        T: LspCommand + Clone,
13127        T::ProtoRequest: proto::LspRequestMessage,
13128        <T::ProtoRequest as proto::RequestMessage>::Response:
13129            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13130    {
13131        let (buffer_version, buffer) =
13132            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13133        let request =
13134            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13135        let key = LspKey {
13136            request_type: TypeId::of::<T>(),
13137            server_queried: for_server_id,
13138        };
13139        lsp_store.update(cx, |lsp_store, cx| {
13140            let request_task = match for_server_id {
13141                Some(server_id) => {
13142                    let server_task = lsp_store.request_lsp(
13143                        buffer.clone(),
13144                        LanguageServerToQuery::Other(server_id),
13145                        request.clone(),
13146                        cx,
13147                    );
13148                    cx.background_spawn(async move {
13149                        let mut responses = Vec::new();
13150                        match server_task.await {
13151                            Ok(response) => responses.push((server_id, response)),
13152                            // rust-analyzer likes to error with this when its still loading up
13153                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13154                            Err(e) => log::error!(
13155                                "Error handling response for request {request:?}: {e:#}"
13156                            ),
13157                        }
13158                        responses
13159                    })
13160                }
13161                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13162            };
13163            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13164            if T::ProtoRequest::stop_previous_requests() {
13165                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13166                    lsp_requests.clear();
13167                }
13168            }
13169            lsp_data.lsp_requests.entry(key).or_default().insert(
13170                lsp_request_id,
13171                cx.spawn(async move |lsp_store, cx| {
13172                    let response = request_task.await;
13173                    lsp_store
13174                        .update(cx, |lsp_store, cx| {
13175                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13176                            {
13177                                let response = response
13178                                    .into_iter()
13179                                    .map(|(server_id, response)| {
13180                                        (
13181                                            server_id.to_proto(),
13182                                            T::response_to_proto(
13183                                                response,
13184                                                lsp_store,
13185                                                sender_id,
13186                                                &buffer_version,
13187                                                cx,
13188                                            )
13189                                            .into(),
13190                                        )
13191                                    })
13192                                    .collect::<HashMap<_, _>>();
13193                                match client.send_lsp_response::<T::ProtoRequest>(
13194                                    project_id,
13195                                    lsp_request_id,
13196                                    response,
13197                                ) {
13198                                    Ok(()) => {}
13199                                    Err(e) => {
13200                                        log::error!("Failed to send LSP response: {e:#}",)
13201                                    }
13202                                }
13203                            }
13204                        })
13205                        .ok();
13206                }),
13207            );
13208        });
13209        Ok(())
13210    }
13211
13212    async fn wait_for_buffer_version<T>(
13213        lsp_store: &Entity<Self>,
13214        proto_request: &T::ProtoRequest,
13215        cx: &mut AsyncApp,
13216    ) -> Result<(Global, Entity<Buffer>)>
13217    where
13218        T: LspCommand,
13219        T::ProtoRequest: proto::LspRequestMessage,
13220    {
13221        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13222        let version = deserialize_version(proto_request.buffer_version());
13223        let buffer = lsp_store.update(cx, |this, cx| {
13224            this.buffer_store.read(cx).get_existing(buffer_id)
13225        })?;
13226        buffer
13227            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13228            .await?;
13229        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13230        Ok((buffer_version, buffer))
13231    }
13232
13233    fn take_text_document_sync_options(
13234        capabilities: &mut lsp::ServerCapabilities,
13235    ) -> lsp::TextDocumentSyncOptions {
13236        match capabilities.text_document_sync.take() {
13237            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13238            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13239                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13240                sync_options.change = Some(sync_kind);
13241                sync_options
13242            }
13243            None => lsp::TextDocumentSyncOptions::default(),
13244        }
13245    }
13246
13247    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13248        self.downstream_client.clone()
13249    }
13250
13251    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13252        self.worktree_store.clone()
13253    }
13254
13255    /// Gets what's stored in the LSP data for the given buffer.
13256    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13257        self.lsp_data.get_mut(&buffer_id)
13258    }
13259
13260    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13261    /// new [`BufferLspData`] will be created to replace the previous state.
13262    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13263        let (buffer_id, buffer_version) =
13264            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13265        let lsp_data = self
13266            .lsp_data
13267            .entry(buffer_id)
13268            .or_insert_with(|| BufferLspData::new(buffer, cx));
13269        if buffer_version.changed_since(&lsp_data.buffer_version) {
13270            // To send delta requests for semantic tokens, the previous tokens
13271            // need to be kept between buffer changes.
13272            let semantic_tokens = lsp_data.semantic_tokens.take();
13273            *lsp_data = BufferLspData::new(buffer, cx);
13274            lsp_data.semantic_tokens = semantic_tokens;
13275        }
13276        lsp_data
13277    }
13278}
13279
13280// Registration with registerOptions as null, should fallback to true.
13281// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13282fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13283    reg: lsp::Registration,
13284) -> Result<OneOf<bool, T>> {
13285    Ok(match reg.register_options {
13286        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13287        None => OneOf::Left(true),
13288    })
13289}
13290
13291fn subscribe_to_binary_statuses(
13292    languages: &Arc<LanguageRegistry>,
13293    cx: &mut Context<'_, LspStore>,
13294) -> Task<()> {
13295    let mut server_statuses = languages.language_server_binary_statuses();
13296    cx.spawn(async move |lsp_store, cx| {
13297        while let Some((server_name, binary_status)) = server_statuses.next().await {
13298            if lsp_store
13299                .update(cx, |_, cx| {
13300                    let mut message = None;
13301                    let binary_status = match binary_status {
13302                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13303                        BinaryStatus::CheckingForUpdate => {
13304                            proto::ServerBinaryStatus::CheckingForUpdate
13305                        }
13306                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13307                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13308                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13309                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13310                        BinaryStatus::Failed { error } => {
13311                            message = Some(error);
13312                            proto::ServerBinaryStatus::Failed
13313                        }
13314                    };
13315                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13316                        // Binary updates are about the binary that might not have any language server id at that point.
13317                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13318                        language_server_id: LanguageServerId(0),
13319                        name: Some(server_name),
13320                        message: proto::update_language_server::Variant::StatusUpdate(
13321                            proto::StatusUpdate {
13322                                message,
13323                                status: Some(proto::status_update::Status::Binary(
13324                                    binary_status as i32,
13325                                )),
13326                            },
13327                        ),
13328                    });
13329                })
13330                .is_err()
13331            {
13332                break;
13333            }
13334        }
13335    })
13336}
13337
13338fn lsp_workspace_diagnostics_refresh(
13339    registration_id: Option<String>,
13340    options: DiagnosticServerCapabilities,
13341    server: Arc<LanguageServer>,
13342    cx: &mut Context<'_, LspStore>,
13343) -> Option<WorkspaceRefreshTask> {
13344    let identifier = workspace_diagnostic_identifier(&options)?;
13345    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13346
13347    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13348    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13349    refresh_tx.try_send(()).ok();
13350
13351    let request_timeout = ProjectSettings::get_global(cx)
13352        .global_lsp_settings
13353        .get_request_timeout();
13354
13355    // 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.
13356    // This allows users to increase the duration if need be
13357    let timeout = if request_timeout != Duration::ZERO {
13358        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13359    } else {
13360        request_timeout
13361    };
13362
13363    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13364        let mut attempts = 0;
13365        let max_attempts = 50;
13366        let mut requests = 0;
13367
13368        loop {
13369            let Some(()) = refresh_rx.recv().await else {
13370                return;
13371            };
13372
13373            'request: loop {
13374                requests += 1;
13375                if attempts > max_attempts {
13376                    log::error!(
13377                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13378                    );
13379                    return;
13380                }
13381                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13382                cx.background_executor()
13383                    .timer(Duration::from_millis(backoff_millis))
13384                    .await;
13385                attempts += 1;
13386
13387                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13388                    lsp_store
13389                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13390                        .into_iter()
13391                        .filter_map(|(abs_path, result_id)| {
13392                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13393                            Some(lsp::PreviousResultId {
13394                                uri,
13395                                value: result_id.to_string(),
13396                            })
13397                        })
13398                        .collect()
13399                }) else {
13400                    return;
13401                };
13402
13403                let token = if let Some(registration_id) = &registration_id {
13404                    format!(
13405                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13406                        server.server_id(),
13407                    )
13408                } else {
13409                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13410                };
13411
13412                progress_rx.try_recv().ok();
13413                let timer = server.request_timer(timeout).fuse();
13414                let progress = pin!(progress_rx.recv().fuse());
13415                let response_result = server
13416                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13417                        lsp::WorkspaceDiagnosticParams {
13418                            previous_result_ids,
13419                            identifier: identifier.clone(),
13420                            work_done_progress_params: Default::default(),
13421                            partial_result_params: lsp::PartialResultParams {
13422                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13423                            },
13424                        },
13425                        select(timer, progress).then(|either| match either {
13426                            Either::Left((message, ..)) => ready(message).left_future(),
13427                            Either::Right(..) => pending::<String>().right_future(),
13428                        }),
13429                    )
13430                    .await;
13431
13432                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13433                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13434                match response_result {
13435                    ConnectionResult::Timeout => {
13436                        log::error!("Timeout during workspace diagnostics pull");
13437                        continue 'request;
13438                    }
13439                    ConnectionResult::ConnectionReset => {
13440                        log::error!("Server closed a workspace diagnostics pull request");
13441                        continue 'request;
13442                    }
13443                    ConnectionResult::Result(Err(e)) => {
13444                        log::error!("Error during workspace diagnostics pull: {e:#}");
13445                        break 'request;
13446                    }
13447                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13448                        attempts = 0;
13449                        if lsp_store
13450                            .update(cx, |lsp_store, cx| {
13451                                lsp_store.apply_workspace_diagnostic_report(
13452                                    server.server_id(),
13453                                    pulled_diagnostics,
13454                                    registration_id_shared.clone(),
13455                                    cx,
13456                                )
13457                            })
13458                            .is_err()
13459                        {
13460                            return;
13461                        }
13462                        break 'request;
13463                    }
13464                }
13465            }
13466        }
13467    });
13468
13469    Some(WorkspaceRefreshTask {
13470        refresh_tx,
13471        progress_tx,
13472        task: workspace_query_language_server,
13473    })
13474}
13475
13476fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13477    match &options {
13478        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13479            .identifier
13480            .as_deref()
13481            .map(SharedString::new),
13482        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13483            let diagnostic_options = &registration_options.diagnostic_options;
13484            diagnostic_options
13485                .identifier
13486                .as_deref()
13487                .map(SharedString::new)
13488        }
13489    }
13490}
13491
13492fn workspace_diagnostic_identifier(
13493    options: &DiagnosticServerCapabilities,
13494) -> Option<Option<String>> {
13495    match &options {
13496        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13497            if !diagnostic_options.workspace_diagnostics {
13498                return None;
13499            }
13500            Some(diagnostic_options.identifier.clone())
13501        }
13502        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13503            let diagnostic_options = &registration_options.diagnostic_options;
13504            if !diagnostic_options.workspace_diagnostics {
13505                return None;
13506            }
13507            Some(diagnostic_options.identifier.clone())
13508        }
13509    }
13510}
13511
13512fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13513    let CompletionSource::BufferWord {
13514        word_range,
13515        resolved,
13516    } = &mut completion.source
13517    else {
13518        return;
13519    };
13520    if *resolved {
13521        return;
13522    }
13523
13524    if completion.new_text
13525        != snapshot
13526            .text_for_range(word_range.clone())
13527            .collect::<String>()
13528    {
13529        return;
13530    }
13531
13532    let mut offset = 0;
13533    for chunk in snapshot.chunks(word_range.clone(), true) {
13534        let end_offset = offset + chunk.text.len();
13535        if let Some(highlight_id) = chunk.syntax_highlight_id {
13536            completion
13537                .label
13538                .runs
13539                .push((offset..end_offset, highlight_id));
13540        }
13541        offset = end_offset;
13542    }
13543    *resolved = true;
13544}
13545
13546impl EventEmitter<LspStoreEvent> for LspStore {}
13547
13548fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13549    hover
13550        .contents
13551        .retain(|hover_block| !hover_block.text.trim().is_empty());
13552    if hover.contents.is_empty() {
13553        None
13554    } else {
13555        Some(hover)
13556    }
13557}
13558
13559async fn populate_labels_for_completions(
13560    new_completions: Vec<CoreCompletion>,
13561    language: Option<Arc<Language>>,
13562    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13563) -> Vec<Completion> {
13564    let lsp_completions = new_completions
13565        .iter()
13566        .filter_map(|new_completion| {
13567            new_completion
13568                .source
13569                .lsp_completion(true)
13570                .map(|lsp_completion| lsp_completion.into_owned())
13571        })
13572        .collect::<Vec<_>>();
13573
13574    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13575        lsp_adapter
13576            .labels_for_completions(&lsp_completions, language)
13577            .await
13578            .log_err()
13579            .unwrap_or_default()
13580    } else {
13581        Vec::new()
13582    }
13583    .into_iter()
13584    .fuse();
13585
13586    let mut completions = Vec::new();
13587    for completion in new_completions {
13588        match completion.source.lsp_completion(true) {
13589            Some(lsp_completion) => {
13590                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13591
13592                let mut label = labels.next().flatten().unwrap_or_else(|| {
13593                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13594                });
13595                ensure_uniform_list_compatible_label(&mut label);
13596                completions.push(Completion {
13597                    label,
13598                    documentation,
13599                    replace_range: completion.replace_range,
13600                    new_text: completion.new_text,
13601                    insert_text_mode: lsp_completion.insert_text_mode,
13602                    source: completion.source,
13603                    icon_path: None,
13604                    confirm: None,
13605                    match_start: None,
13606                    snippet_deduplication_key: None,
13607                });
13608            }
13609            None => {
13610                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13611                ensure_uniform_list_compatible_label(&mut label);
13612                completions.push(Completion {
13613                    label,
13614                    documentation: None,
13615                    replace_range: completion.replace_range,
13616                    new_text: completion.new_text,
13617                    source: completion.source,
13618                    insert_text_mode: None,
13619                    icon_path: None,
13620                    confirm: None,
13621                    match_start: None,
13622                    snippet_deduplication_key: None,
13623                });
13624            }
13625        }
13626    }
13627    completions
13628}
13629
13630#[derive(Debug)]
13631pub enum LanguageServerToQuery {
13632    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13633    FirstCapable,
13634    /// Query a specific language server.
13635    Other(LanguageServerId),
13636}
13637
13638#[derive(Default)]
13639struct RenamePathsWatchedForServer {
13640    did_rename: Vec<RenameActionPredicate>,
13641    will_rename: Vec<RenameActionPredicate>,
13642}
13643
13644impl RenamePathsWatchedForServer {
13645    fn with_did_rename_patterns(
13646        mut self,
13647        did_rename: Option<&FileOperationRegistrationOptions>,
13648    ) -> Self {
13649        if let Some(did_rename) = did_rename {
13650            self.did_rename = did_rename
13651                .filters
13652                .iter()
13653                .filter_map(|filter| filter.try_into().log_err())
13654                .collect();
13655        }
13656        self
13657    }
13658    fn with_will_rename_patterns(
13659        mut self,
13660        will_rename: Option<&FileOperationRegistrationOptions>,
13661    ) -> Self {
13662        if let Some(will_rename) = will_rename {
13663            self.will_rename = will_rename
13664                .filters
13665                .iter()
13666                .filter_map(|filter| filter.try_into().log_err())
13667                .collect();
13668        }
13669        self
13670    }
13671
13672    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13673        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13674    }
13675    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13676        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13677    }
13678}
13679
13680impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13681    type Error = globset::Error;
13682    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13683        Ok(Self {
13684            kind: ops.pattern.matches.clone(),
13685            glob: GlobBuilder::new(&ops.pattern.glob)
13686                .case_insensitive(
13687                    ops.pattern
13688                        .options
13689                        .as_ref()
13690                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13691                )
13692                .build()?
13693                .compile_matcher(),
13694        })
13695    }
13696}
13697struct RenameActionPredicate {
13698    glob: GlobMatcher,
13699    kind: Option<FileOperationPatternKind>,
13700}
13701
13702impl RenameActionPredicate {
13703    // Returns true if language server should be notified
13704    fn eval(&self, path: &str, is_dir: bool) -> bool {
13705        self.kind.as_ref().is_none_or(|kind| {
13706            let expected_kind = if is_dir {
13707                FileOperationPatternKind::Folder
13708            } else {
13709                FileOperationPatternKind::File
13710            };
13711            kind == &expected_kind
13712        }) && self.glob.is_match(path)
13713    }
13714}
13715
13716#[derive(Default)]
13717struct LanguageServerWatchedPaths {
13718    worktree_paths: HashMap<WorktreeId, GlobSet>,
13719    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13720}
13721
13722#[derive(Default)]
13723struct LanguageServerWatchedPathsBuilder {
13724    worktree_paths: HashMap<WorktreeId, GlobSet>,
13725    abs_paths: HashMap<Arc<Path>, GlobSet>,
13726}
13727
13728impl LanguageServerWatchedPathsBuilder {
13729    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13730        self.worktree_paths.insert(worktree_id, glob_set);
13731    }
13732    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13733        self.abs_paths.insert(path, glob_set);
13734    }
13735    fn build(
13736        self,
13737        fs: Arc<dyn Fs>,
13738        language_server_id: LanguageServerId,
13739        cx: &mut Context<LspStore>,
13740    ) -> LanguageServerWatchedPaths {
13741        let lsp_store = cx.weak_entity();
13742
13743        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13744        let abs_paths = self
13745            .abs_paths
13746            .into_iter()
13747            .map(|(abs_path, globset)| {
13748                let task = cx.spawn({
13749                    let abs_path = abs_path.clone();
13750                    let fs = fs.clone();
13751
13752                    let lsp_store = lsp_store.clone();
13753                    async move |_, cx| {
13754                        maybe!(async move {
13755                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13756                            while let Some(update) = push_updates.0.next().await {
13757                                let action = lsp_store
13758                                    .update(cx, |this, _| {
13759                                        let Some(local) = this.as_local() else {
13760                                            return ControlFlow::Break(());
13761                                        };
13762                                        let Some(watcher) = local
13763                                            .language_server_watched_paths
13764                                            .get(&language_server_id)
13765                                        else {
13766                                            return ControlFlow::Break(());
13767                                        };
13768                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13769                                            "Watched abs path is not registered with a watcher",
13770                                        );
13771                                        let matching_entries = update
13772                                            .into_iter()
13773                                            .filter(|event| globs.is_match(&event.path))
13774                                            .collect::<Vec<_>>();
13775                                        this.lsp_notify_abs_paths_changed(
13776                                            language_server_id,
13777                                            matching_entries,
13778                                        );
13779                                        ControlFlow::Continue(())
13780                                    })
13781                                    .ok()?;
13782
13783                                if action.is_break() {
13784                                    break;
13785                                }
13786                            }
13787                            Some(())
13788                        })
13789                        .await;
13790                    }
13791                });
13792                (abs_path, (globset, task))
13793            })
13794            .collect();
13795        LanguageServerWatchedPaths {
13796            worktree_paths: self.worktree_paths,
13797            abs_paths,
13798        }
13799    }
13800}
13801
13802struct LspBufferSnapshot {
13803    version: i32,
13804    snapshot: TextBufferSnapshot,
13805}
13806
13807/// A prompt requested by LSP server.
13808#[derive(Clone, Debug)]
13809pub struct LanguageServerPromptRequest {
13810    pub id: usize,
13811    pub level: PromptLevel,
13812    pub message: String,
13813    pub actions: Vec<MessageActionItem>,
13814    pub lsp_name: String,
13815    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13816}
13817
13818impl LanguageServerPromptRequest {
13819    pub fn new(
13820        level: PromptLevel,
13821        message: String,
13822        actions: Vec<MessageActionItem>,
13823        lsp_name: String,
13824        response_channel: smol::channel::Sender<MessageActionItem>,
13825    ) -> Self {
13826        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13827        LanguageServerPromptRequest {
13828            id,
13829            level,
13830            message,
13831            actions,
13832            lsp_name,
13833            response_channel,
13834        }
13835    }
13836    pub async fn respond(self, index: usize) -> Option<()> {
13837        if let Some(response) = self.actions.into_iter().nth(index) {
13838            self.response_channel.send(response).await.ok()
13839        } else {
13840            None
13841        }
13842    }
13843
13844    #[cfg(any(test, feature = "test-support"))]
13845    pub fn test(
13846        level: PromptLevel,
13847        message: String,
13848        actions: Vec<MessageActionItem>,
13849        lsp_name: String,
13850    ) -> Self {
13851        let (tx, _rx) = smol::channel::unbounded();
13852        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13853    }
13854}
13855impl PartialEq for LanguageServerPromptRequest {
13856    fn eq(&self, other: &Self) -> bool {
13857        self.message == other.message && self.actions == other.actions
13858    }
13859}
13860
13861#[derive(Clone, Debug, PartialEq)]
13862pub enum LanguageServerLogType {
13863    Log(MessageType),
13864    Trace { verbose_info: Option<String> },
13865    Rpc { received: bool },
13866}
13867
13868impl LanguageServerLogType {
13869    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13870        match self {
13871            Self::Log(log_type) => {
13872                use proto::log_message::LogLevel;
13873                let level = match *log_type {
13874                    MessageType::ERROR => LogLevel::Error,
13875                    MessageType::WARNING => LogLevel::Warning,
13876                    MessageType::INFO => LogLevel::Info,
13877                    MessageType::LOG => LogLevel::Log,
13878                    other => {
13879                        log::warn!("Unknown lsp log message type: {other:?}");
13880                        LogLevel::Log
13881                    }
13882                };
13883                proto::language_server_log::LogType::Log(proto::LogMessage {
13884                    level: level as i32,
13885                })
13886            }
13887            Self::Trace { verbose_info } => {
13888                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13889                    verbose_info: verbose_info.to_owned(),
13890                })
13891            }
13892            Self::Rpc { received } => {
13893                let kind = if *received {
13894                    proto::rpc_message::Kind::Received
13895                } else {
13896                    proto::rpc_message::Kind::Sent
13897                };
13898                let kind = kind as i32;
13899                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13900            }
13901        }
13902    }
13903
13904    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13905        use proto::log_message::LogLevel;
13906        use proto::rpc_message;
13907        match log_type {
13908            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13909                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13910                    LogLevel::Error => MessageType::ERROR,
13911                    LogLevel::Warning => MessageType::WARNING,
13912                    LogLevel::Info => MessageType::INFO,
13913                    LogLevel::Log => MessageType::LOG,
13914                },
13915            ),
13916            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13917                verbose_info: trace_message.verbose_info,
13918            },
13919            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13920                received: match rpc_message::Kind::from_i32(message.kind)
13921                    .unwrap_or(rpc_message::Kind::Received)
13922                {
13923                    rpc_message::Kind::Received => true,
13924                    rpc_message::Kind::Sent => false,
13925                },
13926            },
13927        }
13928    }
13929}
13930
13931pub struct WorkspaceRefreshTask {
13932    refresh_tx: mpsc::Sender<()>,
13933    progress_tx: mpsc::Sender<()>,
13934    #[allow(dead_code)]
13935    task: Task<()>,
13936}
13937
13938pub enum LanguageServerState {
13939    Starting {
13940        startup: Task<Option<Arc<LanguageServer>>>,
13941        /// List of language servers that will be added to the workspace once it's initialization completes.
13942        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13943    },
13944
13945    Running {
13946        adapter: Arc<CachedLspAdapter>,
13947        server: Arc<LanguageServer>,
13948        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13949        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13950    },
13951}
13952
13953impl LanguageServerState {
13954    fn add_workspace_folder(&self, uri: Uri) {
13955        match self {
13956            LanguageServerState::Starting {
13957                pending_workspace_folders,
13958                ..
13959            } => {
13960                pending_workspace_folders.lock().insert(uri);
13961            }
13962            LanguageServerState::Running { server, .. } => {
13963                server.add_workspace_folder(uri);
13964            }
13965        }
13966    }
13967    fn _remove_workspace_folder(&self, uri: Uri) {
13968        match self {
13969            LanguageServerState::Starting {
13970                pending_workspace_folders,
13971                ..
13972            } => {
13973                pending_workspace_folders.lock().remove(&uri);
13974            }
13975            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13976        }
13977    }
13978}
13979
13980impl std::fmt::Debug for LanguageServerState {
13981    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13982        match self {
13983            LanguageServerState::Starting { .. } => {
13984                f.debug_struct("LanguageServerState::Starting").finish()
13985            }
13986            LanguageServerState::Running { .. } => {
13987                f.debug_struct("LanguageServerState::Running").finish()
13988            }
13989        }
13990    }
13991}
13992
13993#[derive(Clone, Debug, Serialize)]
13994pub struct LanguageServerProgress {
13995    pub is_disk_based_diagnostics_progress: bool,
13996    pub is_cancellable: bool,
13997    pub title: Option<String>,
13998    pub message: Option<String>,
13999    pub percentage: Option<usize>,
14000    #[serde(skip_serializing)]
14001    pub last_update_at: Instant,
14002}
14003
14004#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14005pub struct DiagnosticSummary {
14006    pub error_count: usize,
14007    pub warning_count: usize,
14008}
14009
14010impl DiagnosticSummary {
14011    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14012        let mut this = Self {
14013            error_count: 0,
14014            warning_count: 0,
14015        };
14016
14017        for entry in diagnostics {
14018            if entry.diagnostic.is_primary {
14019                match entry.diagnostic.severity {
14020                    DiagnosticSeverity::ERROR => this.error_count += 1,
14021                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14022                    _ => {}
14023                }
14024            }
14025        }
14026
14027        this
14028    }
14029
14030    pub fn is_empty(&self) -> bool {
14031        self.error_count == 0 && self.warning_count == 0
14032    }
14033
14034    pub fn to_proto(
14035        self,
14036        language_server_id: LanguageServerId,
14037        path: &RelPath,
14038    ) -> proto::DiagnosticSummary {
14039        proto::DiagnosticSummary {
14040            path: path.to_proto(),
14041            language_server_id: language_server_id.0 as u64,
14042            error_count: self.error_count as u32,
14043            warning_count: self.warning_count as u32,
14044        }
14045    }
14046}
14047
14048#[derive(Clone, Debug)]
14049pub enum CompletionDocumentation {
14050    /// There is no documentation for this completion.
14051    Undocumented,
14052    /// A single line of documentation.
14053    SingleLine(SharedString),
14054    /// Multiple lines of plain text documentation.
14055    MultiLinePlainText(SharedString),
14056    /// Markdown documentation.
14057    MultiLineMarkdown(SharedString),
14058    /// Both single line and multiple lines of plain text documentation.
14059    SingleLineAndMultiLinePlainText {
14060        single_line: SharedString,
14061        plain_text: Option<SharedString>,
14062    },
14063}
14064
14065impl CompletionDocumentation {
14066    #[cfg(any(test, feature = "test-support"))]
14067    pub fn text(&self) -> SharedString {
14068        match self {
14069            CompletionDocumentation::Undocumented => "".into(),
14070            CompletionDocumentation::SingleLine(s) => s.clone(),
14071            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14072            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14073            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14074                single_line.clone()
14075            }
14076        }
14077    }
14078}
14079
14080impl From<lsp::Documentation> for CompletionDocumentation {
14081    fn from(docs: lsp::Documentation) -> Self {
14082        match docs {
14083            lsp::Documentation::String(text) => {
14084                if text.lines().count() <= 1 {
14085                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14086                } else {
14087                    CompletionDocumentation::MultiLinePlainText(text.into())
14088                }
14089            }
14090
14091            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14092                lsp::MarkupKind::PlainText => {
14093                    if value.lines().count() <= 1 {
14094                        CompletionDocumentation::SingleLine(value.into())
14095                    } else {
14096                        CompletionDocumentation::MultiLinePlainText(value.into())
14097                    }
14098                }
14099
14100                lsp::MarkupKind::Markdown => {
14101                    CompletionDocumentation::MultiLineMarkdown(value.into())
14102                }
14103            },
14104        }
14105    }
14106}
14107
14108pub enum ResolvedHint {
14109    Resolved(InlayHint),
14110    Resolving(Shared<Task<()>>),
14111}
14112
14113pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14114    glob.components()
14115        .take_while(|component| match component {
14116            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14117            _ => true,
14118        })
14119        .collect()
14120}
14121
14122pub struct SshLspAdapter {
14123    name: LanguageServerName,
14124    binary: LanguageServerBinary,
14125    initialization_options: Option<String>,
14126    code_action_kinds: Option<Vec<CodeActionKind>>,
14127}
14128
14129impl SshLspAdapter {
14130    pub fn new(
14131        name: LanguageServerName,
14132        binary: LanguageServerBinary,
14133        initialization_options: Option<String>,
14134        code_action_kinds: Option<String>,
14135    ) -> Self {
14136        Self {
14137            name,
14138            binary,
14139            initialization_options,
14140            code_action_kinds: code_action_kinds
14141                .as_ref()
14142                .and_then(|c| serde_json::from_str(c).ok()),
14143        }
14144    }
14145}
14146
14147impl LspInstaller for SshLspAdapter {
14148    type BinaryVersion = ();
14149    async fn check_if_user_installed(
14150        &self,
14151        _: &dyn LspAdapterDelegate,
14152        _: Option<Toolchain>,
14153        _: &AsyncApp,
14154    ) -> Option<LanguageServerBinary> {
14155        Some(self.binary.clone())
14156    }
14157
14158    async fn cached_server_binary(
14159        &self,
14160        _: PathBuf,
14161        _: &dyn LspAdapterDelegate,
14162    ) -> Option<LanguageServerBinary> {
14163        None
14164    }
14165
14166    async fn fetch_latest_server_version(
14167        &self,
14168        _: &dyn LspAdapterDelegate,
14169        _: bool,
14170        _: &mut AsyncApp,
14171    ) -> Result<()> {
14172        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14173    }
14174
14175    async fn fetch_server_binary(
14176        &self,
14177        _: (),
14178        _: PathBuf,
14179        _: &dyn LspAdapterDelegate,
14180    ) -> Result<LanguageServerBinary> {
14181        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14182    }
14183}
14184
14185#[async_trait(?Send)]
14186impl LspAdapter for SshLspAdapter {
14187    fn name(&self) -> LanguageServerName {
14188        self.name.clone()
14189    }
14190
14191    async fn initialization_options(
14192        self: Arc<Self>,
14193        _: &Arc<dyn LspAdapterDelegate>,
14194        _: &mut AsyncApp,
14195    ) -> Result<Option<serde_json::Value>> {
14196        let Some(options) = &self.initialization_options else {
14197            return Ok(None);
14198        };
14199        let result = serde_json::from_str(options)?;
14200        Ok(result)
14201    }
14202
14203    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14204        self.code_action_kinds.clone()
14205    }
14206}
14207
14208pub fn language_server_settings<'a>(
14209    delegate: &'a dyn LspAdapterDelegate,
14210    language: &LanguageServerName,
14211    cx: &'a App,
14212) -> Option<&'a LspSettings> {
14213    language_server_settings_for(
14214        SettingsLocation {
14215            worktree_id: delegate.worktree_id(),
14216            path: RelPath::empty(),
14217        },
14218        language,
14219        cx,
14220    )
14221}
14222
14223pub fn language_server_settings_for<'a>(
14224    location: SettingsLocation<'a>,
14225    language: &LanguageServerName,
14226    cx: &'a App,
14227) -> Option<&'a LspSettings> {
14228    ProjectSettings::get(Some(location), cx).lsp.get(language)
14229}
14230
14231pub struct LocalLspAdapterDelegate {
14232    lsp_store: WeakEntity<LspStore>,
14233    worktree: worktree::Snapshot,
14234    fs: Arc<dyn Fs>,
14235    http_client: Arc<dyn HttpClient>,
14236    language_registry: Arc<LanguageRegistry>,
14237    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14238}
14239
14240impl LocalLspAdapterDelegate {
14241    pub fn new(
14242        language_registry: Arc<LanguageRegistry>,
14243        environment: &Entity<ProjectEnvironment>,
14244        lsp_store: WeakEntity<LspStore>,
14245        worktree: &Entity<Worktree>,
14246        http_client: Arc<dyn HttpClient>,
14247        fs: Arc<dyn Fs>,
14248        cx: &mut App,
14249    ) -> Arc<Self> {
14250        let load_shell_env_task =
14251            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14252
14253        Arc::new(Self {
14254            lsp_store,
14255            worktree: worktree.read(cx).snapshot(),
14256            fs,
14257            http_client,
14258            language_registry,
14259            load_shell_env_task,
14260        })
14261    }
14262
14263    pub fn from_local_lsp(
14264        local: &LocalLspStore,
14265        worktree: &Entity<Worktree>,
14266        cx: &mut App,
14267    ) -> Arc<Self> {
14268        Self::new(
14269            local.languages.clone(),
14270            &local.environment,
14271            local.weak.clone(),
14272            worktree,
14273            local.http_client.clone(),
14274            local.fs.clone(),
14275            cx,
14276        )
14277    }
14278}
14279
14280#[async_trait]
14281impl LspAdapterDelegate for LocalLspAdapterDelegate {
14282    fn show_notification(&self, message: &str, cx: &mut App) {
14283        self.lsp_store
14284            .update(cx, |_, cx| {
14285                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14286            })
14287            .ok();
14288    }
14289
14290    fn http_client(&self) -> Arc<dyn HttpClient> {
14291        self.http_client.clone()
14292    }
14293
14294    fn worktree_id(&self) -> WorktreeId {
14295        self.worktree.id()
14296    }
14297
14298    fn worktree_root_path(&self) -> &Path {
14299        self.worktree.abs_path().as_ref()
14300    }
14301
14302    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14303        self.worktree.resolve_relative_path(path)
14304    }
14305
14306    async fn shell_env(&self) -> HashMap<String, String> {
14307        let task = self.load_shell_env_task.clone();
14308        task.await.unwrap_or_default()
14309    }
14310
14311    async fn npm_package_installed_version(
14312        &self,
14313        package_name: &str,
14314    ) -> Result<Option<(PathBuf, Version)>> {
14315        let local_package_directory = self.worktree_root_path();
14316        let node_modules_directory = local_package_directory.join("node_modules");
14317
14318        if let Some(version) =
14319            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14320        {
14321            return Ok(Some((node_modules_directory, version)));
14322        }
14323        let Some(npm) = self.which("npm".as_ref()).await else {
14324            log::warn!(
14325                "Failed to find npm executable for {:?}",
14326                local_package_directory
14327            );
14328            return Ok(None);
14329        };
14330
14331        let env = self.shell_env().await;
14332        let output = util::command::new_command(&npm)
14333            .args(["root", "-g"])
14334            .envs(env)
14335            .current_dir(local_package_directory)
14336            .output()
14337            .await?;
14338        let global_node_modules =
14339            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14340
14341        if let Some(version) =
14342            read_package_installed_version(global_node_modules.clone(), package_name).await?
14343        {
14344            return Ok(Some((global_node_modules, version)));
14345        }
14346        return Ok(None);
14347    }
14348
14349    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14350        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14351        if self.fs.is_file(&worktree_abs_path).await {
14352            worktree_abs_path.pop();
14353        }
14354
14355        let env = self.shell_env().await;
14356
14357        let shell_path = env.get("PATH").cloned();
14358
14359        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14360    }
14361
14362    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14363        let mut working_dir = self.worktree_root_path().to_path_buf();
14364        if self.fs.is_file(&working_dir).await {
14365            working_dir.pop();
14366        }
14367        let output = util::command::new_command(&command.path)
14368            .args(command.arguments)
14369            .envs(command.env.clone().unwrap_or_default())
14370            .current_dir(working_dir)
14371            .output()
14372            .await?;
14373
14374        anyhow::ensure!(
14375            output.status.success(),
14376            "{}, stdout: {:?}, stderr: {:?}",
14377            output.status,
14378            String::from_utf8_lossy(&output.stdout),
14379            String::from_utf8_lossy(&output.stderr)
14380        );
14381        Ok(())
14382    }
14383
14384    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14385        self.language_registry
14386            .update_lsp_binary_status(server_name, status);
14387    }
14388
14389    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14390        self.language_registry
14391            .all_lsp_adapters()
14392            .into_iter()
14393            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14394            .collect()
14395    }
14396
14397    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14398        let dir = self.language_registry.language_server_download_dir(name)?;
14399
14400        if !dir.exists() {
14401            smol::fs::create_dir_all(&dir)
14402                .await
14403                .context("failed to create container directory")
14404                .log_err()?;
14405        }
14406
14407        Some(dir)
14408    }
14409
14410    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14411        let entry = self
14412            .worktree
14413            .entry_for_path(path)
14414            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14415        let abs_path = self.worktree.absolutize(&entry.path);
14416        self.fs.load(&abs_path).await
14417    }
14418}
14419
14420async fn populate_labels_for_symbols(
14421    symbols: Vec<CoreSymbol>,
14422    language_registry: &Arc<LanguageRegistry>,
14423    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14424    output: &mut Vec<Symbol>,
14425) {
14426    #[allow(clippy::mutable_key_type)]
14427    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14428
14429    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14430    for symbol in symbols {
14431        let Some(file_name) = symbol.path.file_name() else {
14432            continue;
14433        };
14434        let language = language_registry
14435            .load_language_for_file_path(Path::new(file_name))
14436            .await
14437            .ok()
14438            .or_else(|| {
14439                unknown_paths.insert(file_name.into());
14440                None
14441            });
14442        symbols_by_language
14443            .entry(language)
14444            .or_default()
14445            .push(symbol);
14446    }
14447
14448    for unknown_path in unknown_paths {
14449        log::info!("no language found for symbol in file {unknown_path:?}");
14450    }
14451
14452    let mut label_params = Vec::new();
14453    for (language, mut symbols) in symbols_by_language {
14454        label_params.clear();
14455        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14456            name: mem::take(&mut symbol.name),
14457            kind: symbol.kind,
14458            container_name: symbol.container_name.take(),
14459        }));
14460
14461        let mut labels = Vec::new();
14462        if let Some(language) = language {
14463            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14464                language_registry
14465                    .lsp_adapters(&language.name())
14466                    .first()
14467                    .cloned()
14468            });
14469            if let Some(lsp_adapter) = lsp_adapter {
14470                labels = lsp_adapter
14471                    .labels_for_symbols(&label_params, &language)
14472                    .await
14473                    .log_err()
14474                    .unwrap_or_default();
14475            }
14476        }
14477
14478        for (
14479            (
14480                symbol,
14481                language::Symbol {
14482                    name,
14483                    container_name,
14484                    ..
14485                },
14486            ),
14487            label,
14488        ) in symbols
14489            .into_iter()
14490            .zip(label_params.drain(..))
14491            .zip(labels.into_iter().chain(iter::repeat(None)))
14492        {
14493            output.push(Symbol {
14494                language_server_name: symbol.language_server_name,
14495                source_worktree_id: symbol.source_worktree_id,
14496                source_language_server_id: symbol.source_language_server_id,
14497                path: symbol.path,
14498                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14499                name,
14500                kind: symbol.kind,
14501                range: symbol.range,
14502                container_name,
14503            });
14504        }
14505    }
14506}
14507
14508pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14509    text.lines()
14510        .map(|line| line.trim())
14511        .filter(|line| !line.is_empty())
14512        .join(separator)
14513}
14514
14515fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14516    match server.capabilities().text_document_sync.as_ref()? {
14517        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14518            // Server wants didSave but didn't specify includeText.
14519            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14520            // Server doesn't want didSave at all.
14521            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14522            // Server provided SaveOptions.
14523            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14524                Some(save_options.include_text.unwrap_or(false))
14525            }
14526        },
14527        // We do not have any save info. Kind affects didChange only.
14528        lsp::TextDocumentSyncCapability::Kind(_) => None,
14529    }
14530}
14531
14532/// Completion items are displayed in a `UniformList`.
14533/// Usually, those items are single-line strings, but in LSP responses,
14534/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14535/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14536/// 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,
14537/// breaking the completions menu presentation.
14538///
14539/// 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.
14540pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14541    let mut new_text = String::with_capacity(label.text.len());
14542    let mut offset_map = vec![0; label.text.len() + 1];
14543    let mut last_char_was_space = false;
14544    let mut new_idx = 0;
14545    let chars = label.text.char_indices().fuse();
14546    let mut newlines_removed = false;
14547
14548    for (idx, c) in chars {
14549        offset_map[idx] = new_idx;
14550
14551        match c {
14552            '\n' if last_char_was_space => {
14553                newlines_removed = true;
14554            }
14555            '\t' | ' ' if last_char_was_space => {}
14556            '\n' if !last_char_was_space => {
14557                new_text.push(' ');
14558                new_idx += 1;
14559                last_char_was_space = true;
14560                newlines_removed = true;
14561            }
14562            ' ' | '\t' => {
14563                new_text.push(' ');
14564                new_idx += 1;
14565                last_char_was_space = true;
14566            }
14567            _ => {
14568                new_text.push(c);
14569                new_idx += c.len_utf8();
14570                last_char_was_space = false;
14571            }
14572        }
14573    }
14574    offset_map[label.text.len()] = new_idx;
14575
14576    // Only modify the label if newlines were removed.
14577    if !newlines_removed {
14578        return;
14579    }
14580
14581    let last_index = new_idx;
14582    let mut run_ranges_errors = Vec::new();
14583    label.runs.retain_mut(|(range, _)| {
14584        match offset_map.get(range.start) {
14585            Some(&start) => range.start = start,
14586            None => {
14587                run_ranges_errors.push(range.clone());
14588                return false;
14589            }
14590        }
14591
14592        match offset_map.get(range.end) {
14593            Some(&end) => range.end = end,
14594            None => {
14595                run_ranges_errors.push(range.clone());
14596                range.end = last_index;
14597            }
14598        }
14599        true
14600    });
14601    if !run_ranges_errors.is_empty() {
14602        log::error!(
14603            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14604            label.text
14605        );
14606    }
14607
14608    let mut wrong_filter_range = None;
14609    if label.filter_range == (0..label.text.len()) {
14610        label.filter_range = 0..new_text.len();
14611    } else {
14612        let mut original_filter_range = Some(label.filter_range.clone());
14613        match offset_map.get(label.filter_range.start) {
14614            Some(&start) => label.filter_range.start = start,
14615            None => {
14616                wrong_filter_range = original_filter_range.take();
14617                label.filter_range.start = last_index;
14618            }
14619        }
14620
14621        match offset_map.get(label.filter_range.end) {
14622            Some(&end) => label.filter_range.end = end,
14623            None => {
14624                wrong_filter_range = original_filter_range.take();
14625                label.filter_range.end = last_index;
14626            }
14627        }
14628    }
14629    if let Some(wrong_filter_range) = wrong_filter_range {
14630        log::error!(
14631            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14632            label.text
14633        );
14634    }
14635
14636    label.text = new_text;
14637}
14638
14639/// Apply edits to the buffer that will become part of the formatting transaction.
14640/// Fails if the buffer has been edited since the start of that transaction.
14641fn extend_formatting_transaction(
14642    buffer: &FormattableBuffer,
14643    formatting_transaction_id: text::TransactionId,
14644    cx: &mut AsyncApp,
14645    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14646) -> anyhow::Result<()> {
14647    buffer.handle.update(cx, |buffer, cx| {
14648        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14649        if last_transaction_id != Some(formatting_transaction_id) {
14650            anyhow::bail!("Buffer edited while formatting. Aborting")
14651        }
14652        buffer.start_transaction();
14653        operation(buffer, cx);
14654        if let Some(transaction_id) = buffer.end_transaction(cx) {
14655            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14656        }
14657        Ok(())
14658    })
14659}