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, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   81    },
   82    modeline, point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153#[cfg(any(test, feature = "test-support"))]
  154pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  155pub use semantic_tokens::{
  156    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  157};
  158
  159pub use worktree::{
  160    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  161    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  162};
  163
  164const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  165pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  166const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  167const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  168static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  169
  170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  171pub enum ProgressToken {
  172    Number(i32),
  173    String(SharedString),
  174}
  175
  176impl std::fmt::Display for ProgressToken {
  177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178        match self {
  179            Self::Number(number) => write!(f, "{number}"),
  180            Self::String(string) => write!(f, "{string}"),
  181        }
  182    }
  183}
  184
  185impl ProgressToken {
  186    fn from_lsp(value: lsp::NumberOrString) -> Self {
  187        match value {
  188            lsp::NumberOrString::Number(number) => Self::Number(number),
  189            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  190        }
  191    }
  192
  193    fn to_lsp(&self) -> lsp::NumberOrString {
  194        match self {
  195            Self::Number(number) => lsp::NumberOrString::Number(*number),
  196            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  197        }
  198    }
  199
  200    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  201        Some(match value.value? {
  202            proto::progress_token::Value::Number(number) => Self::Number(number),
  203            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  204        })
  205    }
  206
  207    fn to_proto(&self) -> proto::ProgressToken {
  208        proto::ProgressToken {
  209            value: Some(match self {
  210                Self::Number(number) => proto::progress_token::Value::Number(*number),
  211                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  212            }),
  213        }
  214    }
  215}
  216
  217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  218pub enum FormatTrigger {
  219    Save,
  220    Manual,
  221}
  222
  223pub enum LspFormatTarget {
  224    Buffers,
  225    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  226}
  227
  228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  229pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  230
  231struct OpenLspBuffer(Entity<Buffer>);
  232
  233impl FormatTrigger {
  234    fn from_proto(value: i32) -> FormatTrigger {
  235        match value {
  236            0 => FormatTrigger::Save,
  237            1 => FormatTrigger::Manual,
  238            _ => FormatTrigger::Save,
  239        }
  240    }
  241}
  242
  243#[derive(Clone)]
  244struct UnifiedLanguageServer {
  245    id: LanguageServerId,
  246    project_roots: HashSet<Arc<RelPath>>,
  247}
  248
  249/// Settings that affect language server identity.
  250///
  251/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  252/// updated via `workspace/didChangeConfiguration` without restarting the server.
  253#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  254struct LanguageServerSeedSettings {
  255    binary: Option<BinarySettings>,
  256    initialization_options: Option<serde_json::Value>,
  257}
  258
  259#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  260struct LanguageServerSeed {
  261    worktree_id: WorktreeId,
  262    name: LanguageServerName,
  263    toolchain: Option<Toolchain>,
  264    settings: LanguageServerSeedSettings,
  265}
  266
  267#[derive(Debug)]
  268pub struct DocumentDiagnosticsUpdate<'a, D> {
  269    pub diagnostics: D,
  270    pub result_id: Option<SharedString>,
  271    pub registration_id: Option<SharedString>,
  272    pub server_id: LanguageServerId,
  273    pub disk_based_sources: Cow<'a, [String]>,
  274}
  275
  276pub struct DocumentDiagnostics {
  277    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278    document_abs_path: PathBuf,
  279    version: Option<i32>,
  280}
  281
  282#[derive(Default, Debug)]
  283struct DynamicRegistrations {
  284    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  285    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  286}
  287
  288pub struct LocalLspStore {
  289    weak: WeakEntity<LspStore>,
  290    pub worktree_store: Entity<WorktreeStore>,
  291    toolchain_store: Entity<LocalToolchainStore>,
  292    http_client: Arc<dyn HttpClient>,
  293    environment: Entity<ProjectEnvironment>,
  294    fs: Arc<dyn Fs>,
  295    languages: Arc<LanguageRegistry>,
  296    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  297    yarn: Entity<YarnPathStore>,
  298    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  299    buffers_being_formatted: HashSet<BufferId>,
  300    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  301    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  302    watched_manifest_filenames: HashSet<ManifestName>,
  303    language_server_paths_watched_for_rename:
  304        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  305    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  306    supplementary_language_servers:
  307        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  308    prettier_store: Entity<PrettierStore>,
  309    next_diagnostic_group_id: usize,
  310    diagnostics: HashMap<
  311        WorktreeId,
  312        HashMap<
  313            Arc<RelPath>,
  314            Vec<(
  315                LanguageServerId,
  316                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  317            )>,
  318        >,
  319    >,
  320    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  321    _subscription: gpui::Subscription,
  322    lsp_tree: LanguageServerTree,
  323    registered_buffers: HashMap<BufferId, usize>,
  324    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  325    buffer_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    workspace_pull_diagnostics_result_ids: HashMap<
  330        LanguageServerId,
  331        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  332    >,
  333    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  334
  335    buffers_to_refresh_hash_set: HashSet<BufferId>,
  336    buffers_to_refresh_queue: VecDeque<BufferId>,
  337    _background_diagnostics_worker: Shared<Task<()>>,
  338}
  339
  340impl LocalLspStore {
  341    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  342    pub fn running_language_server_for_id(
  343        &self,
  344        id: LanguageServerId,
  345    ) -> Option<&Arc<LanguageServer>> {
  346        let language_server_state = self.language_servers.get(&id)?;
  347
  348        match language_server_state {
  349            LanguageServerState::Running { server, .. } => Some(server),
  350            LanguageServerState::Starting { .. } => None,
  351        }
  352    }
  353
  354    fn get_or_insert_language_server(
  355        &mut self,
  356        worktree_handle: &Entity<Worktree>,
  357        delegate: Arc<LocalLspAdapterDelegate>,
  358        disposition: &Arc<LaunchDisposition>,
  359        language_name: &LanguageName,
  360        cx: &mut App,
  361    ) -> LanguageServerId {
  362        let key = LanguageServerSeed {
  363            worktree_id: worktree_handle.read(cx).id(),
  364            name: disposition.server_name.clone(),
  365            settings: LanguageServerSeedSettings {
  366                binary: disposition.settings.binary.clone(),
  367                initialization_options: disposition.settings.initialization_options.clone(),
  368            },
  369            toolchain: disposition.toolchain.clone(),
  370        };
  371        if let Some(state) = self.language_server_ids.get_mut(&key) {
  372            state.project_roots.insert(disposition.path.path.clone());
  373            state.id
  374        } else {
  375            let adapter = self
  376                .languages
  377                .lsp_adapters(language_name)
  378                .into_iter()
  379                .find(|adapter| adapter.name() == disposition.server_name)
  380                .expect("To find LSP adapter");
  381            let new_language_server_id = self.start_language_server(
  382                worktree_handle,
  383                delegate,
  384                adapter,
  385                disposition.settings.clone(),
  386                key.clone(),
  387                language_name.clone(),
  388                cx,
  389            );
  390            if let Some(state) = self.language_server_ids.get_mut(&key) {
  391                state.project_roots.insert(disposition.path.path.clone());
  392            } else {
  393                debug_assert!(
  394                    false,
  395                    "Expected `start_language_server` to ensure that `key` exists in a map"
  396                );
  397            }
  398            new_language_server_id
  399        }
  400    }
  401
  402    fn start_language_server(
  403        &mut self,
  404        worktree_handle: &Entity<Worktree>,
  405        delegate: Arc<LocalLspAdapterDelegate>,
  406        adapter: Arc<CachedLspAdapter>,
  407        settings: Arc<LspSettings>,
  408        key: LanguageServerSeed,
  409        language_name: LanguageName,
  410        cx: &mut App,
  411    ) -> LanguageServerId {
  412        let worktree = worktree_handle.read(cx);
  413
  414        let worktree_id = worktree.id();
  415        let worktree_abs_path = worktree.abs_path();
  416        let toolchain = key.toolchain.clone();
  417        let override_options = settings.initialization_options.clone();
  418
  419        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  420
  421        let server_id = self.languages.next_language_server_id();
  422        log::trace!(
  423            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  424            adapter.name.0
  425        );
  426
  427        let wait_until_worktree_trust =
  428            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  429                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  430                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  431                });
  432                if can_trust {
  433                    self.restricted_worktrees_tasks.remove(&worktree_id);
  434                    None
  435                } else {
  436                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  437                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  438                        hash_map::Entry::Vacant(v) => {
  439                            let (mut tx, rx) = watch::channel::<bool>();
  440                            let lsp_store = self.weak.clone();
  441                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  442                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  443                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  444                                        tx.blocking_send(true).ok();
  445                                        lsp_store
  446                                            .update(cx, |lsp_store, _| {
  447                                                if let Some(local_lsp_store) =
  448                                                    lsp_store.as_local_mut()
  449                                                {
  450                                                    local_lsp_store
  451                                                        .restricted_worktrees_tasks
  452                                                        .remove(&worktree_id);
  453                                                }
  454                                            })
  455                                            .ok();
  456                                    }
  457                                }
  458                            });
  459                            v.insert((subscription, rx.clone()));
  460                            Some(rx)
  461                        }
  462                    }
  463                }
  464            });
  465        let update_binary_status = wait_until_worktree_trust.is_none();
  466
  467        let binary = self.get_language_server_binary(
  468            worktree_abs_path.clone(),
  469            adapter.clone(),
  470            settings,
  471            toolchain.clone(),
  472            delegate.clone(),
  473            true,
  474            wait_until_worktree_trust,
  475            cx,
  476        );
  477        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  478
  479        let pending_server = cx.spawn({
  480            let adapter = adapter.clone();
  481            let server_name = adapter.name.clone();
  482            let stderr_capture = stderr_capture.clone();
  483            #[cfg(any(test, feature = "test-support"))]
  484            let lsp_store = self.weak.clone();
  485            let pending_workspace_folders = pending_workspace_folders.clone();
  486            async move |cx| {
  487                let binary = binary.await?;
  488                #[cfg(any(test, feature = "test-support"))]
  489                if let Some(server) = lsp_store
  490                    .update(&mut cx.clone(), |this, cx| {
  491                        this.languages.create_fake_language_server(
  492                            server_id,
  493                            &server_name,
  494                            binary.clone(),
  495                            &mut cx.to_async(),
  496                        )
  497                    })
  498                    .ok()
  499                    .flatten()
  500                {
  501                    return Ok(server);
  502                }
  503
  504                let code_action_kinds = adapter.code_action_kinds();
  505                lsp::LanguageServer::new(
  506                    stderr_capture,
  507                    server_id,
  508                    server_name,
  509                    binary,
  510                    &worktree_abs_path,
  511                    code_action_kinds,
  512                    Some(pending_workspace_folders),
  513                    cx,
  514                )
  515            }
  516        });
  517
  518        let startup = {
  519            let server_name = adapter.name.0.clone();
  520            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  521            let key = key.clone();
  522            let adapter = adapter.clone();
  523            let lsp_store = self.weak.clone();
  524            let pending_workspace_folders = pending_workspace_folders.clone();
  525            let pull_diagnostics = ProjectSettings::get_global(cx)
  526                .diagnostics
  527                .lsp_pull_diagnostics
  528                .enabled;
  529            let settings_location = SettingsLocation {
  530                worktree_id,
  531                path: RelPath::empty(),
  532            };
  533            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  534                .language(Some(settings_location), Some(&language_name), cx)
  535                .semantic_tokens
  536                .use_tree_sitter();
  537            cx.spawn(async move |cx| {
  538                let result = async {
  539                    let language_server = pending_server.await?;
  540
  541                    let workspace_config = Self::workspace_configuration_for_adapter(
  542                        adapter.adapter.clone(),
  543                        &delegate,
  544                        toolchain,
  545                        None,
  546                        cx,
  547                    )
  548                    .await?;
  549
  550                    let mut initialization_options = Self::initialization_options_for_adapter(
  551                        adapter.adapter.clone(),
  552                        &delegate,
  553                        cx,
  554                    )
  555                    .await?;
  556
  557                    match (&mut initialization_options, override_options) {
  558                        (Some(initialization_options), Some(override_options)) => {
  559                            merge_json_value_into(override_options, initialization_options);
  560                        }
  561                        (None, override_options) => initialization_options = override_options,
  562                        _ => {}
  563                    }
  564
  565                    let initialization_params = cx.update(|cx| {
  566                        let mut params = language_server.default_initialize_params(
  567                            pull_diagnostics,
  568                            augments_syntax_tokens,
  569                            cx,
  570                        );
  571                        params.initialization_options = initialization_options;
  572                        adapter.adapter.prepare_initialize_params(params, cx)
  573                    })?;
  574
  575                    Self::setup_lsp_messages(
  576                        lsp_store.clone(),
  577                        &language_server,
  578                        delegate.clone(),
  579                        adapter.clone(),
  580                    );
  581
  582                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  583                        settings: workspace_config,
  584                    };
  585                    let language_server = cx
  586                        .update(|cx| {
  587                            let request_timeout = ProjectSettings::get_global(cx)
  588                                .global_lsp_settings
  589                                .get_request_timeout();
  590
  591                            language_server.initialize(
  592                                initialization_params,
  593                                Arc::new(did_change_configuration_params.clone()),
  594                                request_timeout,
  595                                cx,
  596                            )
  597                        })
  598                        .await
  599                        .inspect_err(|_| {
  600                            if let Some(lsp_store) = lsp_store.upgrade() {
  601                                lsp_store.update(cx, |lsp_store, cx| {
  602                                    lsp_store.cleanup_lsp_data(server_id);
  603                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  604                                });
  605                            }
  606                        })?;
  607
  608                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  609                        did_change_configuration_params,
  610                    )?;
  611
  612                    anyhow::Ok(language_server)
  613                }
  614                .await;
  615
  616                match result {
  617                    Ok(server) => {
  618                        lsp_store
  619                            .update(cx, |lsp_store, cx| {
  620                                lsp_store.insert_newly_running_language_server(
  621                                    adapter,
  622                                    server.clone(),
  623                                    server_id,
  624                                    key,
  625                                    pending_workspace_folders,
  626                                    cx,
  627                                );
  628                            })
  629                            .ok();
  630                        stderr_capture.lock().take();
  631                        Some(server)
  632                    }
  633
  634                    Err(err) => {
  635                        let log = stderr_capture.lock().take().unwrap_or_default();
  636                        delegate.update_status(
  637                            adapter.name(),
  638                            BinaryStatus::Failed {
  639                                error: if log.is_empty() {
  640                                    format!("{err:#}")
  641                                } else {
  642                                    format!("{err:#}\n-- stderr --\n{log}")
  643                                },
  644                            },
  645                        );
  646                        log::error!(
  647                            "Failed to start language server {server_name:?}: {}",
  648                            redact_command(&format!("{err:?}"))
  649                        );
  650                        if !log.is_empty() {
  651                            log::error!("server stderr: {}", redact_command(&log));
  652                        }
  653                        None
  654                    }
  655                }
  656            })
  657        };
  658        let state = LanguageServerState::Starting {
  659            startup,
  660            pending_workspace_folders,
  661        };
  662
  663        if update_binary_status {
  664            self.languages
  665                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  666        }
  667
  668        self.language_servers.insert(server_id, state);
  669        self.language_server_ids
  670            .entry(key)
  671            .or_insert(UnifiedLanguageServer {
  672                id: server_id,
  673                project_roots: Default::default(),
  674            });
  675        server_id
  676    }
  677
  678    fn get_language_server_binary(
  679        &self,
  680        worktree_abs_path: Arc<Path>,
  681        adapter: Arc<CachedLspAdapter>,
  682        settings: Arc<LspSettings>,
  683        toolchain: Option<Toolchain>,
  684        delegate: Arc<dyn LspAdapterDelegate>,
  685        allow_binary_download: bool,
  686        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  687        cx: &mut App,
  688    ) -> Task<Result<LanguageServerBinary>> {
  689        if let Some(settings) = &settings.binary
  690            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  691        {
  692            let settings = settings.clone();
  693            let languages = self.languages.clone();
  694            return cx.background_spawn(async move {
  695                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  696                    let already_trusted =  *wait_until_worktree_trust.borrow();
  697                    if !already_trusted {
  698                        log::info!(
  699                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  700                            adapter.name(),
  701                        );
  702                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  703                            if worktree_trusted {
  704                                break;
  705                            }
  706                        }
  707                        log::info!(
  708                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  709                            adapter.name(),
  710                        );
  711                    }
  712                    languages
  713                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  714                }
  715                let mut env = delegate.shell_env().await;
  716                env.extend(settings.env.unwrap_or_default());
  717
  718                Ok(LanguageServerBinary {
  719                    path: delegate.resolve_relative_path(path),
  720                    env: Some(env),
  721                    arguments: settings
  722                        .arguments
  723                        .unwrap_or_default()
  724                        .iter()
  725                        .map(Into::into)
  726                        .collect(),
  727                })
  728            });
  729        }
  730        let lsp_binary_options = LanguageServerBinaryOptions {
  731            allow_path_lookup: !settings
  732                .binary
  733                .as_ref()
  734                .and_then(|b| b.ignore_system_version)
  735                .unwrap_or_default(),
  736            allow_binary_download,
  737            pre_release: settings
  738                .fetch
  739                .as_ref()
  740                .and_then(|f| f.pre_release)
  741                .unwrap_or(false),
  742        };
  743
  744        cx.spawn(async move |cx| {
  745            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  746                let already_trusted =  *wait_until_worktree_trust.borrow();
  747                if !already_trusted {
  748                    log::info!(
  749                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  750                        adapter.name(),
  751                    );
  752                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  753                        if worktree_trusted {
  754                            break;
  755                        }
  756                    }
  757                    log::info!(
  758                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  759                            adapter.name(),
  760                    );
  761                }
  762            }
  763
  764            let (existing_binary, maybe_download_binary) = adapter
  765                .clone()
  766                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  767                .await
  768                .await;
  769
  770            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  771
  772            let mut binary = match (existing_binary, maybe_download_binary) {
  773                (binary, None) => binary?,
  774                (Err(_), Some(downloader)) => downloader.await?,
  775                (Ok(existing_binary), Some(downloader)) => {
  776                    let mut download_timeout = cx
  777                        .background_executor()
  778                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  779                        .fuse();
  780                    let mut downloader = downloader.fuse();
  781                    futures::select! {
  782                        _ = download_timeout => {
  783                            // Return existing binary and kick the existing work to the background.
  784                            cx.spawn(async move |_| downloader.await).detach();
  785                            Ok(existing_binary)
  786                        },
  787                        downloaded_or_existing_binary = downloader => {
  788                            // If download fails, this results in the existing binary.
  789                            downloaded_or_existing_binary
  790                        }
  791                    }?
  792                }
  793            };
  794            let mut shell_env = delegate.shell_env().await;
  795
  796            shell_env.extend(binary.env.unwrap_or_default());
  797
  798            if let Some(settings) = settings.binary.as_ref() {
  799                if let Some(arguments) = &settings.arguments {
  800                    binary.arguments = arguments.iter().map(Into::into).collect();
  801                }
  802                if let Some(env) = &settings.env {
  803                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  804                }
  805            }
  806
  807            binary.env = Some(shell_env);
  808            Ok(binary)
  809        })
  810    }
  811
  812    fn setup_lsp_messages(
  813        lsp_store: WeakEntity<LspStore>,
  814        language_server: &LanguageServer,
  815        delegate: Arc<dyn LspAdapterDelegate>,
  816        adapter: Arc<CachedLspAdapter>,
  817    ) {
  818        let name = language_server.name();
  819        let server_id = language_server.server_id();
  820        language_server
  821            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  822                let adapter = adapter.clone();
  823                let this = lsp_store.clone();
  824                move |mut params, cx| {
  825                    let adapter = adapter.clone();
  826                    if let Some(this) = this.upgrade() {
  827                        this.update(cx, |this, cx| {
  828                            adapter.process_diagnostics(&mut params, server_id);
  829
  830                            this.merge_lsp_diagnostics(
  831                                DiagnosticSourceKind::Pushed,
  832                                vec![DocumentDiagnosticsUpdate {
  833                                    server_id,
  834                                    diagnostics: params,
  835                                    result_id: None,
  836                                    disk_based_sources: Cow::Borrowed(
  837                                        &adapter.disk_based_diagnostic_sources,
  838                                    ),
  839                                    registration_id: None,
  840                                }],
  841                                |_, diagnostic, _cx| match diagnostic.source_kind {
  842                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  843                                        adapter.retain_old_diagnostic(diagnostic)
  844                                    }
  845                                    DiagnosticSourceKind::Pulled => true,
  846                                },
  847                                cx,
  848                            )
  849                            .log_err();
  850                        });
  851                    }
  852                }
  853            })
  854            .detach();
  855        language_server
  856            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  857                let adapter = adapter.adapter.clone();
  858                let delegate = delegate.clone();
  859                let this = lsp_store.clone();
  860                move |params, cx| {
  861                    let adapter = adapter.clone();
  862                    let delegate = delegate.clone();
  863                    let this = this.clone();
  864                    let mut cx = cx.clone();
  865                    async move {
  866                        let toolchain_for_id = this
  867                            .update(&mut cx, |this, _| {
  868                                this.as_local()?.language_server_ids.iter().find_map(
  869                                    |(seed, value)| {
  870                                        (value.id == server_id).then(|| seed.toolchain.clone())
  871                                    },
  872                                )
  873                            })?
  874                            .context("Expected the LSP store to be in a local mode")?;
  875
  876                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  877                        for item in &params.items {
  878                            let scope_uri = item.scope_uri.clone();
  879                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  880                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  881                            else {
  882                                // We've already queried workspace configuration of this URI.
  883                                continue;
  884                            };
  885                            let workspace_config = Self::workspace_configuration_for_adapter(
  886                                adapter.clone(),
  887                                &delegate,
  888                                toolchain_for_id.clone(),
  889                                scope_uri,
  890                                &mut cx,
  891                            )
  892                            .await?;
  893                            new_scope_uri.insert(workspace_config);
  894                        }
  895
  896                        Ok(params
  897                            .items
  898                            .into_iter()
  899                            .filter_map(|item| {
  900                                let workspace_config =
  901                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  902                                if let Some(section) = &item.section {
  903                                    Some(
  904                                        workspace_config
  905                                            .get(section)
  906                                            .cloned()
  907                                            .unwrap_or(serde_json::Value::Null),
  908                                    )
  909                                } else {
  910                                    Some(workspace_config.clone())
  911                                }
  912                            })
  913                            .collect())
  914                    }
  915                }
  916            })
  917            .detach();
  918
  919        language_server
  920            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  921                let this = lsp_store.clone();
  922                move |_, cx| {
  923                    let this = this.clone();
  924                    let cx = cx.clone();
  925                    async move {
  926                        let Some(server) =
  927                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  928                        else {
  929                            return Ok(None);
  930                        };
  931                        let root = server.workspace_folders();
  932                        Ok(Some(
  933                            root.into_iter()
  934                                .map(|uri| WorkspaceFolder {
  935                                    uri,
  936                                    name: Default::default(),
  937                                })
  938                                .collect(),
  939                        ))
  940                    }
  941                }
  942            })
  943            .detach();
  944        // Even though we don't have handling for these requests, respond to them to
  945        // avoid stalling any language server like `gopls` which waits for a response
  946        // to these requests when initializing.
  947        language_server
  948            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  949                let this = lsp_store.clone();
  950                move |params, cx| {
  951                    let this = this.clone();
  952                    let mut cx = cx.clone();
  953                    async move {
  954                        this.update(&mut cx, |this, _| {
  955                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  956                            {
  957                                status
  958                                    .progress_tokens
  959                                    .insert(ProgressToken::from_lsp(params.token));
  960                            }
  961                        })?;
  962
  963                        Ok(())
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_request::<lsp::request::RegisterCapability, _, _>({
  971                let lsp_store = lsp_store.clone();
  972                move |params, cx| {
  973                    let lsp_store = lsp_store.clone();
  974                    let mut cx = cx.clone();
  975                    async move {
  976                        lsp_store
  977                            .update(&mut cx, |lsp_store, cx| {
  978                                if lsp_store.as_local().is_some() {
  979                                    match lsp_store
  980                                        .register_server_capabilities(server_id, params, cx)
  981                                    {
  982                                        Ok(()) => {}
  983                                        Err(e) => {
  984                                            log::error!(
  985                                                "Failed to register server capabilities: {e:#}"
  986                                            );
  987                                        }
  988                                    };
  989                                }
  990                            })
  991                            .ok();
  992                        Ok(())
  993                    }
  994                }
  995            })
  996            .detach();
  997
  998        language_server
  999            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1000                let lsp_store = lsp_store.clone();
 1001                move |params, cx| {
 1002                    let lsp_store = lsp_store.clone();
 1003                    let mut cx = cx.clone();
 1004                    async move {
 1005                        lsp_store
 1006                            .update(&mut cx, |lsp_store, cx| {
 1007                                if lsp_store.as_local().is_some() {
 1008                                    match lsp_store
 1009                                        .unregister_server_capabilities(server_id, params, cx)
 1010                                    {
 1011                                        Ok(()) => {}
 1012                                        Err(e) => {
 1013                                            log::error!(
 1014                                                "Failed to unregister server capabilities: {e:#}"
 1015                                            );
 1016                                        }
 1017                                    }
 1018                                }
 1019                            })
 1020                            .ok();
 1021                        Ok(())
 1022                    }
 1023                }
 1024            })
 1025            .detach();
 1026
 1027        language_server
 1028            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1029                let this = lsp_store.clone();
 1030                move |params, cx| {
 1031                    let mut cx = cx.clone();
 1032                    let this = this.clone();
 1033                    async move {
 1034                        LocalLspStore::on_lsp_workspace_edit(
 1035                            this.clone(),
 1036                            params,
 1037                            server_id,
 1038                            &mut cx,
 1039                        )
 1040                        .await
 1041                    }
 1042                }
 1043            })
 1044            .detach();
 1045
 1046        language_server
 1047            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1048                let lsp_store = lsp_store.clone();
 1049                let request_id = Arc::new(AtomicUsize::new(0));
 1050                move |(), cx| {
 1051                    let lsp_store = lsp_store.clone();
 1052                    let request_id = request_id.clone();
 1053                    let mut cx = cx.clone();
 1054                    async move {
 1055                        lsp_store
 1056                            .update(&mut cx, |lsp_store, cx| {
 1057                                let request_id =
 1058                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1059                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1060                                    server_id,
 1061                                    request_id,
 1062                                });
 1063                                lsp_store
 1064                                    .downstream_client
 1065                                    .as_ref()
 1066                                    .map(|(client, project_id)| {
 1067                                        client.send(proto::RefreshInlayHints {
 1068                                            project_id: *project_id,
 1069                                            server_id: server_id.to_proto(),
 1070                                            request_id: request_id.map(|id| id as u64),
 1071                                        })
 1072                                    })
 1073                            })?
 1074                            .transpose()?;
 1075                        Ok(())
 1076                    }
 1077                }
 1078            })
 1079            .detach();
 1080
 1081        language_server
 1082            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1083                let this = lsp_store.clone();
 1084                move |(), cx| {
 1085                    let this = this.clone();
 1086                    let mut cx = cx.clone();
 1087                    async move {
 1088                        this.update(&mut cx, |this, cx| {
 1089                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1090                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1091                                client.send(proto::RefreshCodeLens {
 1092                                    project_id: *project_id,
 1093                                })
 1094                            })
 1095                        })?
 1096                        .transpose()?;
 1097                        Ok(())
 1098                    }
 1099                }
 1100            })
 1101            .detach();
 1102
 1103        language_server
 1104            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1105                let lsp_store = lsp_store.clone();
 1106                let request_id = Arc::new(AtomicUsize::new(0));
 1107                move |(), cx| {
 1108                    let lsp_store = lsp_store.clone();
 1109                    let request_id = request_id.clone();
 1110                    let mut cx = cx.clone();
 1111                    async move {
 1112                        lsp_store
 1113                            .update(&mut cx, |lsp_store, cx| {
 1114                                let request_id =
 1115                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1116                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1117                                    server_id,
 1118                                    request_id,
 1119                                });
 1120                                lsp_store
 1121                                    .downstream_client
 1122                                    .as_ref()
 1123                                    .map(|(client, project_id)| {
 1124                                        client.send(proto::RefreshSemanticTokens {
 1125                                            project_id: *project_id,
 1126                                            server_id: server_id.to_proto(),
 1127                                            request_id: request_id.map(|id| id as u64),
 1128                                        })
 1129                                    })
 1130                            })?
 1131                            .transpose()?;
 1132                        Ok(())
 1133                    }
 1134                }
 1135            })
 1136            .detach();
 1137
 1138        language_server
 1139            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1140                let this = lsp_store.clone();
 1141                move |(), cx| {
 1142                    let this = this.clone();
 1143                    let mut cx = cx.clone();
 1144                    async move {
 1145                        this.update(&mut cx, |lsp_store, cx| {
 1146                            lsp_store.pull_workspace_diagnostics(server_id);
 1147                            lsp_store
 1148                                .downstream_client
 1149                                .as_ref()
 1150                                .map(|(client, project_id)| {
 1151                                    client.send(proto::PullWorkspaceDiagnostics {
 1152                                        project_id: *project_id,
 1153                                        server_id: server_id.to_proto(),
 1154                                    })
 1155                                })
 1156                                .transpose()?;
 1157                            anyhow::Ok(
 1158                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1159                            )
 1160                        })??
 1161                        .await;
 1162                        Ok(())
 1163                    }
 1164                }
 1165            })
 1166            .detach();
 1167
 1168        language_server
 1169            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1170                let this = lsp_store.clone();
 1171                let name = name.to_string();
 1172                let adapter = adapter.clone();
 1173                move |params, cx| {
 1174                    let this = this.clone();
 1175                    let name = name.to_string();
 1176                    let adapter = adapter.clone();
 1177                    let mut cx = cx.clone();
 1178                    async move {
 1179                        let actions = params.actions.unwrap_or_default();
 1180                        let message = params.message.clone();
 1181                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1182                        let level = match params.typ {
 1183                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1184                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1185                            _ => PromptLevel::Info,
 1186                        };
 1187                        let request = LanguageServerPromptRequest::new(
 1188                            level,
 1189                            params.message,
 1190                            actions,
 1191                            name.clone(),
 1192                            tx,
 1193                        );
 1194
 1195                        let did_update = this
 1196                            .update(&mut cx, |_, cx| {
 1197                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1198                            })
 1199                            .is_ok();
 1200                        if did_update {
 1201                            let response = rx.recv().await.ok();
 1202                            if let Some(ref selected_action) = response {
 1203                                let context = language::PromptResponseContext {
 1204                                    message,
 1205                                    selected_action: selected_action.clone(),
 1206                                };
 1207                                adapter.process_prompt_response(&context, &mut cx)
 1208                            }
 1209
 1210                            Ok(response)
 1211                        } else {
 1212                            Ok(None)
 1213                        }
 1214                    }
 1215                }
 1216            })
 1217            .detach();
 1218        language_server
 1219            .on_notification::<lsp::notification::ShowMessage, _>({
 1220                let this = lsp_store.clone();
 1221                let name = name.to_string();
 1222                move |params, cx| {
 1223                    let this = this.clone();
 1224                    let name = name.to_string();
 1225                    let mut cx = cx.clone();
 1226
 1227                    let (tx, _) = smol::channel::bounded(1);
 1228                    let level = match params.typ {
 1229                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1230                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1231                        _ => PromptLevel::Info,
 1232                    };
 1233                    let request =
 1234                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1235
 1236                    let _ = this.update(&mut cx, |_, cx| {
 1237                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1238                    });
 1239                }
 1240            })
 1241            .detach();
 1242
 1243        let disk_based_diagnostics_progress_token =
 1244            adapter.disk_based_diagnostics_progress_token.clone();
 1245
 1246        language_server
 1247            .on_notification::<lsp::notification::Progress, _>({
 1248                let this = lsp_store.clone();
 1249                move |params, cx| {
 1250                    if let Some(this) = this.upgrade() {
 1251                        this.update(cx, |this, cx| {
 1252                            this.on_lsp_progress(
 1253                                params,
 1254                                server_id,
 1255                                disk_based_diagnostics_progress_token.clone(),
 1256                                cx,
 1257                            );
 1258                        });
 1259                    }
 1260                }
 1261            })
 1262            .detach();
 1263
 1264        language_server
 1265            .on_notification::<lsp::notification::LogMessage, _>({
 1266                let this = lsp_store.clone();
 1267                move |params, cx| {
 1268                    if let Some(this) = this.upgrade() {
 1269                        this.update(cx, |_, cx| {
 1270                            cx.emit(LspStoreEvent::LanguageServerLog(
 1271                                server_id,
 1272                                LanguageServerLogType::Log(params.typ),
 1273                                params.message,
 1274                            ));
 1275                        });
 1276                    }
 1277                }
 1278            })
 1279            .detach();
 1280
 1281        language_server
 1282            .on_notification::<lsp::notification::LogTrace, _>({
 1283                let this = lsp_store.clone();
 1284                move |params, cx| {
 1285                    let mut cx = cx.clone();
 1286                    if let Some(this) = this.upgrade() {
 1287                        this.update(&mut cx, |_, cx| {
 1288                            cx.emit(LspStoreEvent::LanguageServerLog(
 1289                                server_id,
 1290                                LanguageServerLogType::Trace {
 1291                                    verbose_info: params.verbose,
 1292                                },
 1293                                params.message,
 1294                            ));
 1295                        });
 1296                    }
 1297                }
 1298            })
 1299            .detach();
 1300
 1301        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1303        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1304        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1305    }
 1306
 1307    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1308        let shutdown_futures = self
 1309            .language_servers
 1310            .drain()
 1311            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1312            .collect::<Vec<_>>();
 1313
 1314        async move {
 1315            join_all(shutdown_futures).await;
 1316        }
 1317    }
 1318
 1319    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1320        match server_state {
 1321            LanguageServerState::Running { server, .. } => {
 1322                if let Some(shutdown) = server.shutdown() {
 1323                    shutdown.await;
 1324                }
 1325            }
 1326            LanguageServerState::Starting { startup, .. } => {
 1327                if let Some(server) = startup.await
 1328                    && let Some(shutdown) = server.shutdown()
 1329                {
 1330                    shutdown.await;
 1331                }
 1332            }
 1333        }
 1334        Ok(())
 1335    }
 1336
 1337    fn language_servers_for_worktree(
 1338        &self,
 1339        worktree_id: WorktreeId,
 1340    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1341        self.language_server_ids
 1342            .iter()
 1343            .filter_map(move |(seed, state)| {
 1344                if seed.worktree_id != worktree_id {
 1345                    return None;
 1346                }
 1347
 1348                if let Some(LanguageServerState::Running { server, .. }) =
 1349                    self.language_servers.get(&state.id)
 1350                {
 1351                    Some(server)
 1352                } else {
 1353                    None
 1354                }
 1355            })
 1356    }
 1357
 1358    fn language_server_ids_for_project_path(
 1359        &self,
 1360        project_path: ProjectPath,
 1361        language: &Language,
 1362        cx: &mut App,
 1363    ) -> Vec<LanguageServerId> {
 1364        let Some(worktree) = self
 1365            .worktree_store
 1366            .read(cx)
 1367            .worktree_for_id(project_path.worktree_id, cx)
 1368        else {
 1369            return Vec::new();
 1370        };
 1371        let delegate: Arc<dyn ManifestDelegate> =
 1372            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1373
 1374        self.lsp_tree
 1375            .get(
 1376                project_path,
 1377                language.name(),
 1378                language.manifest(),
 1379                &delegate,
 1380                cx,
 1381            )
 1382            .collect::<Vec<_>>()
 1383    }
 1384
 1385    fn language_server_ids_for_buffer(
 1386        &self,
 1387        buffer: &Buffer,
 1388        cx: &mut App,
 1389    ) -> Vec<LanguageServerId> {
 1390        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1391            let worktree_id = file.worktree_id(cx);
 1392
 1393            let path: Arc<RelPath> = file
 1394                .path()
 1395                .parent()
 1396                .map(Arc::from)
 1397                .unwrap_or_else(|| file.path().clone());
 1398            let worktree_path = ProjectPath { worktree_id, path };
 1399            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1400        } else {
 1401            Vec::new()
 1402        }
 1403    }
 1404
 1405    fn language_servers_for_buffer<'a>(
 1406        &'a self,
 1407        buffer: &'a Buffer,
 1408        cx: &'a mut App,
 1409    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1410        self.language_server_ids_for_buffer(buffer, cx)
 1411            .into_iter()
 1412            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1413                LanguageServerState::Running {
 1414                    adapter, server, ..
 1415                } => Some((adapter, server)),
 1416                _ => None,
 1417            })
 1418    }
 1419
 1420    async fn execute_code_action_kind_locally(
 1421        lsp_store: WeakEntity<LspStore>,
 1422        mut buffers: Vec<Entity<Buffer>>,
 1423        kind: CodeActionKind,
 1424        push_to_history: bool,
 1425        cx: &mut AsyncApp,
 1426    ) -> anyhow::Result<ProjectTransaction> {
 1427        // Do not allow multiple concurrent code actions requests for the
 1428        // same buffer.
 1429        lsp_store.update(cx, |this, cx| {
 1430            let this = this.as_local_mut().unwrap();
 1431            buffers.retain(|buffer| {
 1432                this.buffers_being_formatted
 1433                    .insert(buffer.read(cx).remote_id())
 1434            });
 1435        })?;
 1436        let _cleanup = defer({
 1437            let this = lsp_store.clone();
 1438            let mut cx = cx.clone();
 1439            let buffers = &buffers;
 1440            move || {
 1441                this.update(&mut cx, |this, cx| {
 1442                    let this = this.as_local_mut().unwrap();
 1443                    for buffer in buffers {
 1444                        this.buffers_being_formatted
 1445                            .remove(&buffer.read(cx).remote_id());
 1446                    }
 1447                })
 1448                .ok();
 1449            }
 1450        });
 1451        let mut project_transaction = ProjectTransaction::default();
 1452
 1453        for buffer in &buffers {
 1454            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1455                buffer.update(cx, |buffer, cx| {
 1456                    lsp_store
 1457                        .as_local()
 1458                        .unwrap()
 1459                        .language_servers_for_buffer(buffer, cx)
 1460                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1461                        .collect::<Vec<_>>()
 1462                })
 1463            })?;
 1464            for (_, language_server) in adapters_and_servers.iter() {
 1465                let actions = Self::get_server_code_actions_from_action_kinds(
 1466                    &lsp_store,
 1467                    language_server.server_id(),
 1468                    vec![kind.clone()],
 1469                    buffer,
 1470                    cx,
 1471                )
 1472                .await?;
 1473                Self::execute_code_actions_on_server(
 1474                    &lsp_store,
 1475                    language_server,
 1476                    actions,
 1477                    push_to_history,
 1478                    &mut project_transaction,
 1479                    cx,
 1480                )
 1481                .await?;
 1482            }
 1483        }
 1484        Ok(project_transaction)
 1485    }
 1486
 1487    async fn format_locally(
 1488        lsp_store: WeakEntity<LspStore>,
 1489        mut buffers: Vec<FormattableBuffer>,
 1490        push_to_history: bool,
 1491        trigger: FormatTrigger,
 1492        logger: zlog::Logger,
 1493        cx: &mut AsyncApp,
 1494    ) -> anyhow::Result<ProjectTransaction> {
 1495        // Do not allow multiple concurrent formatting requests for the
 1496        // same buffer.
 1497        lsp_store.update(cx, |this, cx| {
 1498            let this = this.as_local_mut().unwrap();
 1499            buffers.retain(|buffer| {
 1500                this.buffers_being_formatted
 1501                    .insert(buffer.handle.read(cx).remote_id())
 1502            });
 1503        })?;
 1504
 1505        let _cleanup = defer({
 1506            let this = lsp_store.clone();
 1507            let mut cx = cx.clone();
 1508            let buffers = &buffers;
 1509            move || {
 1510                this.update(&mut cx, |this, cx| {
 1511                    let this = this.as_local_mut().unwrap();
 1512                    for buffer in buffers {
 1513                        this.buffers_being_formatted
 1514                            .remove(&buffer.handle.read(cx).remote_id());
 1515                    }
 1516                })
 1517                .ok();
 1518            }
 1519        });
 1520
 1521        let mut project_transaction = ProjectTransaction::default();
 1522
 1523        for buffer in &buffers {
 1524            zlog::debug!(
 1525                logger =>
 1526                "formatting buffer '{:?}'",
 1527                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1528            );
 1529            // Create an empty transaction to hold all of the formatting edits.
 1530            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1531                // ensure no transactions created while formatting are
 1532                // grouped with the previous transaction in the history
 1533                // based on the transaction group interval
 1534                buffer.finalize_last_transaction();
 1535                buffer
 1536                    .start_transaction()
 1537                    .context("transaction already open")?;
 1538                buffer.end_transaction(cx);
 1539                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1540                buffer.finalize_last_transaction();
 1541                anyhow::Ok(transaction_id)
 1542            })?;
 1543
 1544            let result = Self::format_buffer_locally(
 1545                lsp_store.clone(),
 1546                buffer,
 1547                formatting_transaction_id,
 1548                trigger,
 1549                logger,
 1550                cx,
 1551            )
 1552            .await;
 1553
 1554            buffer.handle.update(cx, |buffer, cx| {
 1555                let Some(formatting_transaction) =
 1556                    buffer.get_transaction(formatting_transaction_id).cloned()
 1557                else {
 1558                    zlog::warn!(logger => "no formatting transaction");
 1559                    return;
 1560                };
 1561                if formatting_transaction.edit_ids.is_empty() {
 1562                    zlog::debug!(logger => "no changes made while formatting");
 1563                    buffer.forget_transaction(formatting_transaction_id);
 1564                    return;
 1565                }
 1566                if !push_to_history {
 1567                    zlog::trace!(logger => "forgetting format transaction");
 1568                    buffer.forget_transaction(formatting_transaction.id);
 1569                }
 1570                project_transaction
 1571                    .0
 1572                    .insert(cx.entity(), formatting_transaction);
 1573            });
 1574
 1575            result?;
 1576        }
 1577
 1578        Ok(project_transaction)
 1579    }
 1580
 1581    async fn format_buffer_locally(
 1582        lsp_store: WeakEntity<LspStore>,
 1583        buffer: &FormattableBuffer,
 1584        formatting_transaction_id: clock::Lamport,
 1585        trigger: FormatTrigger,
 1586        logger: zlog::Logger,
 1587        cx: &mut AsyncApp,
 1588    ) -> Result<()> {
 1589        let (adapters_and_servers, settings, request_timeout) =
 1590            lsp_store.update(cx, |lsp_store, cx| {
 1591                buffer.handle.update(cx, |buffer, cx| {
 1592                    let adapters_and_servers = lsp_store
 1593                        .as_local()
 1594                        .unwrap()
 1595                        .language_servers_for_buffer(buffer, cx)
 1596                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1597                        .collect::<Vec<_>>();
 1598                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1599                    let request_timeout = ProjectSettings::get_global(cx)
 1600                        .global_lsp_settings
 1601                        .get_request_timeout();
 1602                    (adapters_and_servers, settings, request_timeout)
 1603                })
 1604            })?;
 1605
 1606        // handle whitespace formatting
 1607        if settings.remove_trailing_whitespace_on_save {
 1608            zlog::trace!(logger => "removing trailing whitespace");
 1609            let diff = buffer
 1610                .handle
 1611                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1612                .await;
 1613            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1614                buffer.apply_diff(diff, cx);
 1615            })?;
 1616        }
 1617
 1618        if settings.ensure_final_newline_on_save {
 1619            zlog::trace!(logger => "ensuring final newline");
 1620            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1621                buffer.ensure_final_newline(cx);
 1622            })?;
 1623        }
 1624
 1625        // Formatter for `code_actions_on_format` that runs before
 1626        // the rest of the formatters
 1627        let mut code_actions_on_format_formatters = None;
 1628        let should_run_code_actions_on_format = !matches!(
 1629            (trigger, &settings.format_on_save),
 1630            (FormatTrigger::Save, &FormatOnSave::Off)
 1631        );
 1632        if should_run_code_actions_on_format {
 1633            let have_code_actions_to_run_on_format = settings
 1634                .code_actions_on_format
 1635                .values()
 1636                .any(|enabled| *enabled);
 1637            if have_code_actions_to_run_on_format {
 1638                zlog::trace!(logger => "going to run code actions on format");
 1639                code_actions_on_format_formatters = Some(
 1640                    settings
 1641                        .code_actions_on_format
 1642                        .iter()
 1643                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1644                        .cloned()
 1645                        .map(Formatter::CodeAction)
 1646                        .collect::<Vec<_>>(),
 1647                );
 1648            }
 1649        }
 1650
 1651        let formatters = match (trigger, &settings.format_on_save) {
 1652            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1653            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1654                settings.formatter.as_ref()
 1655            }
 1656        };
 1657
 1658        let formatters = code_actions_on_format_formatters
 1659            .iter()
 1660            .flatten()
 1661            .chain(formatters);
 1662
 1663        for formatter in formatters {
 1664            let formatter = if formatter == &Formatter::Auto {
 1665                if settings.prettier.allowed {
 1666                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1667                    &Formatter::Prettier
 1668                } else {
 1669                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1670                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1671                }
 1672            } else {
 1673                formatter
 1674            };
 1675            if let Err(err) = Self::apply_formatter(
 1676                formatter,
 1677                &lsp_store,
 1678                buffer,
 1679                formatting_transaction_id,
 1680                &adapters_and_servers,
 1681                &settings,
 1682                request_timeout,
 1683                logger,
 1684                cx,
 1685            )
 1686            .await
 1687            {
 1688                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1689            }
 1690        }
 1691
 1692        Ok(())
 1693    }
 1694
 1695    async fn apply_formatter(
 1696        formatter: &Formatter,
 1697        lsp_store: &WeakEntity<LspStore>,
 1698        buffer: &FormattableBuffer,
 1699        formatting_transaction_id: clock::Lamport,
 1700        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1701        settings: &LanguageSettings,
 1702        request_timeout: Duration,
 1703        logger: zlog::Logger,
 1704        cx: &mut AsyncApp,
 1705    ) -> anyhow::Result<()> {
 1706        match formatter {
 1707            Formatter::None => {
 1708                zlog::trace!(logger => "skipping formatter 'none'");
 1709                return Ok(());
 1710            }
 1711            Formatter::Auto => {
 1712                debug_panic!("Auto resolved above");
 1713                return Ok(());
 1714            }
 1715            Formatter::Prettier => {
 1716                let logger = zlog::scoped!(logger => "prettier");
 1717                zlog::trace!(logger => "formatting");
 1718                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1719
 1720                // When selection ranges are provided (via FormatSelections), we pass the
 1721                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1722                // After diffing, we filter the resulting edits to only keep those that
 1723                // overlap with the original byte-level selection ranges.
 1724                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1725                    Some(ranges) if !ranges.is_empty() => {
 1726                        let (utf16_range, byte_ranges) =
 1727                            buffer.handle.read_with(cx, |buffer, _cx| {
 1728                                let snapshot = buffer.snapshot();
 1729                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1730                                let mut max_end_utf16 = OffsetUtf16(0);
 1731                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1732                                for range in ranges {
 1733                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1734                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1735                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1736                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1737
 1738                                    let start_byte = range.start.to_offset(&snapshot);
 1739                                    let end_byte = range.end.to_offset(&snapshot);
 1740                                    byte_ranges.push(start_byte..end_byte);
 1741                                }
 1742                                (min_start_utf16..max_end_utf16, byte_ranges)
 1743                            });
 1744                        (Some(utf16_range), Some(byte_ranges))
 1745                    }
 1746                    _ => (None, None),
 1747                };
 1748
 1749                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1750                    lsp_store.prettier_store().unwrap().downgrade()
 1751                })?;
 1752                let diff = prettier_store::format_with_prettier(
 1753                    &prettier,
 1754                    &buffer.handle,
 1755                    range_utf16,
 1756                    cx,
 1757                )
 1758                .await
 1759                .transpose()?;
 1760                let Some(mut diff) = diff else {
 1761                    zlog::trace!(logger => "No changes");
 1762                    return Ok(());
 1763                };
 1764
 1765                if let Some(byte_ranges) = byte_ranges {
 1766                    diff.edits.retain(|(edit_range, _)| {
 1767                        byte_ranges.iter().any(|selection_range| {
 1768                            edit_range.start < selection_range.end
 1769                                && edit_range.end > selection_range.start
 1770                        })
 1771                    });
 1772                    if diff.edits.is_empty() {
 1773                        zlog::trace!(logger => "No changes within selection");
 1774                        return Ok(());
 1775                    }
 1776                }
 1777
 1778                extend_formatting_transaction(
 1779                    buffer,
 1780                    formatting_transaction_id,
 1781                    cx,
 1782                    |buffer, cx| {
 1783                        buffer.apply_diff(diff, cx);
 1784                    },
 1785                )?;
 1786            }
 1787            Formatter::External { command, arguments } => {
 1788                let logger = zlog::scoped!(logger => "command");
 1789
 1790                if buffer.ranges.is_some() {
 1791                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1792                    return Ok(());
 1793                }
 1794
 1795                zlog::trace!(logger => "formatting");
 1796                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1797
 1798                let diff =
 1799                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1800                        .await
 1801                        .with_context(|| {
 1802                            format!("Failed to format buffer via external command: {}", command)
 1803                        })?;
 1804                let Some(diff) = diff else {
 1805                    zlog::trace!(logger => "No changes");
 1806                    return Ok(());
 1807                };
 1808
 1809                extend_formatting_transaction(
 1810                    buffer,
 1811                    formatting_transaction_id,
 1812                    cx,
 1813                    |buffer, cx| {
 1814                        buffer.apply_diff(diff, cx);
 1815                    },
 1816                )?;
 1817            }
 1818            Formatter::LanguageServer(specifier) => {
 1819                let logger = zlog::scoped!(logger => "language-server");
 1820                zlog::trace!(logger => "formatting");
 1821                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1822
 1823                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1824                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1825                    return Ok(());
 1826                };
 1827
 1828                let language_server = match specifier {
 1829                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1830                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1831                            if adapter.name.0.as_ref() == name {
 1832                                Some(server.clone())
 1833                            } else {
 1834                                None
 1835                            }
 1836                        })
 1837                    }
 1838                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1839                        .iter()
 1840                        .find(|(_, server)| Self::server_supports_formatting(server))
 1841                        .map(|(_, server)| server.clone()),
 1842                };
 1843
 1844                let Some(language_server) = language_server else {
 1845                    log::debug!(
 1846                        "No language server found to format buffer '{:?}'. Skipping",
 1847                        buffer_path_abs.as_path().to_string_lossy()
 1848                    );
 1849                    return Ok(());
 1850                };
 1851
 1852                zlog::trace!(
 1853                    logger =>
 1854                    "Formatting buffer '{:?}' using language server '{:?}'",
 1855                    buffer_path_abs.as_path().to_string_lossy(),
 1856                    language_server.name()
 1857                );
 1858
 1859                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1860                    zlog::trace!(logger => "formatting ranges");
 1861                    Self::format_ranges_via_lsp(
 1862                        &lsp_store,
 1863                        &buffer.handle,
 1864                        ranges,
 1865                        buffer_path_abs,
 1866                        &language_server,
 1867                        &settings,
 1868                        cx,
 1869                    )
 1870                    .await
 1871                    .context("Failed to format ranges via language server")?
 1872                } else {
 1873                    zlog::trace!(logger => "formatting full");
 1874                    Self::format_via_lsp(
 1875                        &lsp_store,
 1876                        &buffer.handle,
 1877                        buffer_path_abs,
 1878                        &language_server,
 1879                        &settings,
 1880                        cx,
 1881                    )
 1882                    .await
 1883                    .context("failed to format via language server")?
 1884                };
 1885
 1886                if edits.is_empty() {
 1887                    zlog::trace!(logger => "No changes");
 1888                    return Ok(());
 1889                }
 1890                extend_formatting_transaction(
 1891                    buffer,
 1892                    formatting_transaction_id,
 1893                    cx,
 1894                    |buffer, cx| {
 1895                        buffer.edit(edits, None, cx);
 1896                    },
 1897                )?;
 1898            }
 1899            Formatter::CodeAction(code_action_name) => {
 1900                let logger = zlog::scoped!(logger => "code-actions");
 1901                zlog::trace!(logger => "formatting");
 1902                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1903
 1904                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1905                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1906                    return Ok(());
 1907                };
 1908
 1909                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1910                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1911
 1912                let mut actions_and_servers = Vec::new();
 1913
 1914                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1915                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1916                        &lsp_store,
 1917                        language_server.server_id(),
 1918                        vec![code_action_kind.clone()],
 1919                        &buffer.handle,
 1920                        cx,
 1921                    )
 1922                    .await
 1923                    .with_context(|| {
 1924                        format!(
 1925                            "Failed to resolve code action {:?} with language server {}",
 1926                            code_action_kind,
 1927                            language_server.name()
 1928                        )
 1929                    });
 1930                    let Ok(actions) = actions_result else {
 1931                        // note: it may be better to set result to the error and break formatters here
 1932                        // but for now we try to execute the actions that we can resolve and skip the rest
 1933                        zlog::error!(
 1934                            logger =>
 1935                            "Failed to resolve code action {:?} with language server {}",
 1936                            code_action_kind,
 1937                            language_server.name()
 1938                        );
 1939                        continue;
 1940                    };
 1941                    for action in actions {
 1942                        actions_and_servers.push((action, index));
 1943                    }
 1944                }
 1945
 1946                if actions_and_servers.is_empty() {
 1947                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1948                    return Ok(());
 1949                }
 1950
 1951                'actions: for (mut action, server_index) in actions_and_servers {
 1952                    let server = &adapters_and_servers[server_index].1;
 1953
 1954                    let describe_code_action = |action: &CodeAction| {
 1955                        format!(
 1956                            "code action '{}' with title \"{}\" on server {}",
 1957                            action
 1958                                .lsp_action
 1959                                .action_kind()
 1960                                .unwrap_or("unknown".into())
 1961                                .as_str(),
 1962                            action.lsp_action.title(),
 1963                            server.name(),
 1964                        )
 1965                    };
 1966
 1967                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1968
 1969                    if let Err(err) =
 1970                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1971                    {
 1972                        zlog::error!(
 1973                            logger =>
 1974                            "Failed to resolve {}. Error: {}",
 1975                            describe_code_action(&action),
 1976                            err
 1977                        );
 1978                        continue;
 1979                    }
 1980
 1981                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1982                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1983                        // but filters out and logs warnings for code actions that require unreasonably
 1984                        // difficult handling on our part, such as:
 1985                        // - applying edits that call commands
 1986                        //   which can result in arbitrary workspace edits being sent from the server that
 1987                        //   have no way of being tied back to the command that initiated them (i.e. we
 1988                        //   can't know which edits are part of the format request, or if the server is done sending
 1989                        //   actions in response to the command)
 1990                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1991                        //   as we then would need to handle such changes correctly in the local history as well
 1992                        //   as the remote history through the ProjectTransaction
 1993                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1994                        // Supporting these actions is not impossible, but not supported as of yet.
 1995                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1996                            zlog::trace!(
 1997                                logger =>
 1998                                "No changes for code action. Skipping {}",
 1999                                describe_code_action(&action),
 2000                            );
 2001                            continue;
 2002                        }
 2003
 2004                        let mut operations = Vec::new();
 2005                        if let Some(document_changes) = edit.document_changes {
 2006                            match document_changes {
 2007                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2008                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2009                                ),
 2010                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2011                            }
 2012                        } else if let Some(changes) = edit.changes {
 2013                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2014                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2015                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2016                                        uri,
 2017                                        version: None,
 2018                                    },
 2019                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2020                                })
 2021                            }));
 2022                        }
 2023
 2024                        let mut edits = Vec::with_capacity(operations.len());
 2025
 2026                        if operations.is_empty() {
 2027                            zlog::trace!(
 2028                                logger =>
 2029                                "No changes for code action. Skipping {}",
 2030                                describe_code_action(&action),
 2031                            );
 2032                            continue;
 2033                        }
 2034                        for operation in operations {
 2035                            let op = match operation {
 2036                                lsp::DocumentChangeOperation::Edit(op) => op,
 2037                                lsp::DocumentChangeOperation::Op(_) => {
 2038                                    zlog::warn!(
 2039                                        logger =>
 2040                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2041                                        describe_code_action(&action),
 2042                                    );
 2043                                    continue 'actions;
 2044                                }
 2045                            };
 2046                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2047                                zlog::warn!(
 2048                                    logger =>
 2049                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2050                                    &op.text_document.uri,
 2051                                    describe_code_action(&action),
 2052                                );
 2053                                continue 'actions;
 2054                            };
 2055                            if &file_path != buffer_path_abs {
 2056                                zlog::warn!(
 2057                                    logger =>
 2058                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2059                                    file_path,
 2060                                    buffer_path_abs,
 2061                                    describe_code_action(&action),
 2062                                );
 2063                                continue 'actions;
 2064                            }
 2065
 2066                            let mut lsp_edits = Vec::new();
 2067                            for edit in op.edits {
 2068                                match edit {
 2069                                    Edit::Plain(edit) => {
 2070                                        if !lsp_edits.contains(&edit) {
 2071                                            lsp_edits.push(edit);
 2072                                        }
 2073                                    }
 2074                                    Edit::Annotated(edit) => {
 2075                                        if !lsp_edits.contains(&edit.text_edit) {
 2076                                            lsp_edits.push(edit.text_edit);
 2077                                        }
 2078                                    }
 2079                                    Edit::Snippet(_) => {
 2080                                        zlog::warn!(
 2081                                            logger =>
 2082                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2083                                            describe_code_action(&action),
 2084                                        );
 2085                                        continue 'actions;
 2086                                    }
 2087                                }
 2088                            }
 2089                            let edits_result = lsp_store
 2090                                .update(cx, |lsp_store, cx| {
 2091                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2092                                        &buffer.handle,
 2093                                        lsp_edits,
 2094                                        server.server_id(),
 2095                                        op.text_document.version,
 2096                                        cx,
 2097                                    )
 2098                                })?
 2099                                .await;
 2100                            let Ok(resolved_edits) = edits_result else {
 2101                                zlog::warn!(
 2102                                    logger =>
 2103                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2104                                    buffer_path_abs.as_path(),
 2105                                    describe_code_action(&action),
 2106                                );
 2107                                continue 'actions;
 2108                            };
 2109                            edits.extend(resolved_edits);
 2110                        }
 2111
 2112                        if edits.is_empty() {
 2113                            zlog::warn!(logger => "No edits resolved from LSP");
 2114                            continue;
 2115                        }
 2116
 2117                        extend_formatting_transaction(
 2118                            buffer,
 2119                            formatting_transaction_id,
 2120                            cx,
 2121                            |buffer, cx| {
 2122                                zlog::info!(
 2123                                    "Applying edits {edits:?}. Content: {:?}",
 2124                                    buffer.text()
 2125                                );
 2126                                buffer.edit(edits, None, cx);
 2127                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2128                            },
 2129                        )?;
 2130                    }
 2131
 2132                    let Some(command) = action.lsp_action.command() else {
 2133                        continue;
 2134                    };
 2135
 2136                    zlog::warn!(
 2137                        logger =>
 2138                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2139                        &command.command,
 2140                    );
 2141
 2142                    let server_capabilities = server.capabilities();
 2143                    let available_commands = server_capabilities
 2144                        .execute_command_provider
 2145                        .as_ref()
 2146                        .map(|options| options.commands.as_slice())
 2147                        .unwrap_or_default();
 2148                    if !available_commands.contains(&command.command) {
 2149                        zlog::warn!(
 2150                            logger =>
 2151                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2152                            command.command,
 2153                            server.name(),
 2154                        );
 2155                        continue;
 2156                    }
 2157
 2158                    extend_formatting_transaction(
 2159                        buffer,
 2160                        formatting_transaction_id,
 2161                        cx,
 2162                        |_, _| {},
 2163                    )?;
 2164                    zlog::info!(logger => "Executing command {}", &command.command);
 2165
 2166                    lsp_store.update(cx, |this, _| {
 2167                        this.as_local_mut()
 2168                            .unwrap()
 2169                            .last_workspace_edits_by_language_server
 2170                            .remove(&server.server_id());
 2171                    })?;
 2172
 2173                    let execute_command_result = server
 2174                        .request::<lsp::request::ExecuteCommand>(
 2175                            lsp::ExecuteCommandParams {
 2176                                command: command.command.clone(),
 2177                                arguments: command.arguments.clone().unwrap_or_default(),
 2178                                ..Default::default()
 2179                            },
 2180                            request_timeout,
 2181                        )
 2182                        .await
 2183                        .into_response();
 2184
 2185                    if execute_command_result.is_err() {
 2186                        zlog::error!(
 2187                            logger =>
 2188                            "Failed to execute command '{}' as part of {}",
 2189                            &command.command,
 2190                            describe_code_action(&action),
 2191                        );
 2192                        continue 'actions;
 2193                    }
 2194
 2195                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2196                        this.as_local_mut()
 2197                            .unwrap()
 2198                            .last_workspace_edits_by_language_server
 2199                            .remove(&server.server_id())
 2200                            .unwrap_or_default()
 2201                    })?;
 2202
 2203                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2204                    {
 2205                        zlog::trace!(
 2206                            logger =>
 2207                            "Successfully captured {} edits that resulted from command {}",
 2208                            transaction.edit_ids.len(),
 2209                            &command.command,
 2210                        );
 2211                        let transaction_id_project_transaction = transaction.id;
 2212                        buffer.handle.update(cx, |buffer, _| {
 2213                            // it may have been removed from history if push_to_history was
 2214                            // false in deserialize_workspace_edit. If so push it so we
 2215                            // can merge it with the format transaction
 2216                            // and pop the combined transaction off the history stack
 2217                            // later if push_to_history is false
 2218                            if buffer.get_transaction(transaction.id).is_none() {
 2219                                buffer.push_transaction(transaction, Instant::now());
 2220                            }
 2221                            buffer.merge_transactions(
 2222                                transaction_id_project_transaction,
 2223                                formatting_transaction_id,
 2224                            );
 2225                        });
 2226                    }
 2227
 2228                    if project_transaction_command.0.is_empty() {
 2229                        continue;
 2230                    }
 2231
 2232                    let mut extra_buffers = String::new();
 2233                    for buffer in project_transaction_command.0.keys() {
 2234                        buffer.read_with(cx, |b, cx| {
 2235                            let Some(path) = b.project_path(cx) else {
 2236                                return;
 2237                            };
 2238
 2239                            if !extra_buffers.is_empty() {
 2240                                extra_buffers.push_str(", ");
 2241                            }
 2242                            extra_buffers.push_str(path.path.as_unix_str());
 2243                        });
 2244                    }
 2245                    zlog::warn!(
 2246                        logger =>
 2247                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2248                        &command.command,
 2249                        extra_buffers,
 2250                    );
 2251                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2252                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2253                    // add it so it's included, and merge it into the format transaction when its created later
 2254                }
 2255            }
 2256        }
 2257
 2258        Ok(())
 2259    }
 2260
 2261    pub async fn format_ranges_via_lsp(
 2262        this: &WeakEntity<LspStore>,
 2263        buffer_handle: &Entity<Buffer>,
 2264        ranges: &[Range<Anchor>],
 2265        abs_path: &Path,
 2266        language_server: &Arc<LanguageServer>,
 2267        settings: &LanguageSettings,
 2268        cx: &mut AsyncApp,
 2269    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2270        let capabilities = &language_server.capabilities();
 2271        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2272        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2273            anyhow::bail!(
 2274                "{} language server does not support range formatting",
 2275                language_server.name()
 2276            );
 2277        }
 2278
 2279        let uri = file_path_to_lsp_url(abs_path)?;
 2280        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2281
 2282        let request_timeout = cx.update(|app| {
 2283            ProjectSettings::get_global(app)
 2284                .global_lsp_settings
 2285                .get_request_timeout()
 2286        });
 2287        let lsp_edits = {
 2288            let mut lsp_ranges = Vec::new();
 2289            this.update(cx, |_this, cx| {
 2290                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2291                // not have been sent to the language server. This seems like a fairly systemic
 2292                // issue, though, the resolution probably is not specific to formatting.
 2293                //
 2294                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2295                // LSP.
 2296                let snapshot = buffer_handle.read(cx).snapshot();
 2297                for range in ranges {
 2298                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2299                }
 2300                anyhow::Ok(())
 2301            })??;
 2302
 2303            let mut edits = None;
 2304            for range in lsp_ranges {
 2305                if let Some(mut edit) = language_server
 2306                    .request::<lsp::request::RangeFormatting>(
 2307                        lsp::DocumentRangeFormattingParams {
 2308                            text_document: text_document.clone(),
 2309                            range,
 2310                            options: lsp_command::lsp_formatting_options(settings),
 2311                            work_done_progress_params: Default::default(),
 2312                        },
 2313                        request_timeout,
 2314                    )
 2315                    .await
 2316                    .into_response()?
 2317                {
 2318                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2319                }
 2320            }
 2321            edits
 2322        };
 2323
 2324        if let Some(lsp_edits) = lsp_edits {
 2325            this.update(cx, |this, cx| {
 2326                this.as_local_mut().unwrap().edits_from_lsp(
 2327                    buffer_handle,
 2328                    lsp_edits,
 2329                    language_server.server_id(),
 2330                    None,
 2331                    cx,
 2332                )
 2333            })?
 2334            .await
 2335        } else {
 2336            Ok(Vec::with_capacity(0))
 2337        }
 2338    }
 2339
 2340    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2341        let capabilities = server.capabilities();
 2342        let formatting = capabilities.document_formatting_provider.as_ref();
 2343        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2344        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2345            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2346    }
 2347
 2348    async fn format_via_lsp(
 2349        this: &WeakEntity<LspStore>,
 2350        buffer: &Entity<Buffer>,
 2351        abs_path: &Path,
 2352        language_server: &Arc<LanguageServer>,
 2353        settings: &LanguageSettings,
 2354        cx: &mut AsyncApp,
 2355    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2356        let logger = zlog::scoped!("lsp_format");
 2357        zlog::debug!(logger => "Formatting via LSP");
 2358
 2359        let uri = file_path_to_lsp_url(abs_path)?;
 2360        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2361        let capabilities = &language_server.capabilities();
 2362
 2363        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2364        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2365
 2366        let request_timeout = cx.update(|app| {
 2367            ProjectSettings::get_global(app)
 2368                .global_lsp_settings
 2369                .get_request_timeout()
 2370        });
 2371
 2372        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2373            let _timer = zlog::time!(logger => "format-full");
 2374            language_server
 2375                .request::<lsp::request::Formatting>(
 2376                    lsp::DocumentFormattingParams {
 2377                        text_document,
 2378                        options: lsp_command::lsp_formatting_options(settings),
 2379                        work_done_progress_params: Default::default(),
 2380                    },
 2381                    request_timeout,
 2382                )
 2383                .await
 2384                .into_response()?
 2385        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2386            let _timer = zlog::time!(logger => "format-range");
 2387            let buffer_start = lsp::Position::new(0, 0);
 2388            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2389            language_server
 2390                .request::<lsp::request::RangeFormatting>(
 2391                    lsp::DocumentRangeFormattingParams {
 2392                        text_document: text_document.clone(),
 2393                        range: lsp::Range::new(buffer_start, buffer_end),
 2394                        options: lsp_command::lsp_formatting_options(settings),
 2395                        work_done_progress_params: Default::default(),
 2396                    },
 2397                    request_timeout,
 2398                )
 2399                .await
 2400                .into_response()?
 2401        } else {
 2402            None
 2403        };
 2404
 2405        if let Some(lsp_edits) = lsp_edits {
 2406            this.update(cx, |this, cx| {
 2407                this.as_local_mut().unwrap().edits_from_lsp(
 2408                    buffer,
 2409                    lsp_edits,
 2410                    language_server.server_id(),
 2411                    None,
 2412                    cx,
 2413                )
 2414            })?
 2415            .await
 2416        } else {
 2417            Ok(Vec::with_capacity(0))
 2418        }
 2419    }
 2420
 2421    async fn format_via_external_command(
 2422        buffer: &FormattableBuffer,
 2423        command: &str,
 2424        arguments: Option<&[String]>,
 2425        cx: &mut AsyncApp,
 2426    ) -> Result<Option<Diff>> {
 2427        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2428            let file = File::from_dyn(buffer.file())?;
 2429            let worktree = file.worktree.read(cx);
 2430            let mut worktree_path = worktree.abs_path().to_path_buf();
 2431            if worktree.root_entry()?.is_file() {
 2432                worktree_path.pop();
 2433            }
 2434            Some(worktree_path)
 2435        });
 2436
 2437        use util::command::Stdio;
 2438        let mut child = util::command::new_command(command);
 2439
 2440        if let Some(buffer_env) = buffer.env.as_ref() {
 2441            child.envs(buffer_env);
 2442        }
 2443
 2444        if let Some(working_dir_path) = working_dir_path {
 2445            child.current_dir(working_dir_path);
 2446        }
 2447
 2448        if let Some(arguments) = arguments {
 2449            child.args(arguments.iter().map(|arg| {
 2450                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2451                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2452                } else {
 2453                    arg.replace("{buffer_path}", "Untitled")
 2454                }
 2455            }));
 2456        }
 2457
 2458        let mut child = child
 2459            .stdin(Stdio::piped())
 2460            .stdout(Stdio::piped())
 2461            .stderr(Stdio::piped())
 2462            .spawn()?;
 2463
 2464        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2465        let text = buffer
 2466            .handle
 2467            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2468        for chunk in text.chunks() {
 2469            stdin.write_all(chunk.as_bytes()).await?;
 2470        }
 2471        stdin.flush().await?;
 2472
 2473        let output = child.output().await?;
 2474        anyhow::ensure!(
 2475            output.status.success(),
 2476            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2477            output.status.code(),
 2478            String::from_utf8_lossy(&output.stdout),
 2479            String::from_utf8_lossy(&output.stderr),
 2480        );
 2481
 2482        let stdout = String::from_utf8(output.stdout)?;
 2483        Ok(Some(
 2484            buffer
 2485                .handle
 2486                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2487                .await,
 2488        ))
 2489    }
 2490
 2491    async fn try_resolve_code_action(
 2492        lang_server: &LanguageServer,
 2493        action: &mut CodeAction,
 2494        request_timeout: Duration,
 2495    ) -> anyhow::Result<()> {
 2496        match &mut action.lsp_action {
 2497            LspAction::Action(lsp_action) => {
 2498                if !action.resolved
 2499                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2500                    && lsp_action.data.is_some()
 2501                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2502                {
 2503                    **lsp_action = lang_server
 2504                        .request::<lsp::request::CodeActionResolveRequest>(
 2505                            *lsp_action.clone(),
 2506                            request_timeout,
 2507                        )
 2508                        .await
 2509                        .into_response()?;
 2510                }
 2511            }
 2512            LspAction::CodeLens(lens) => {
 2513                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2514                    *lens = lang_server
 2515                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2516                        .await
 2517                        .into_response()?;
 2518                }
 2519            }
 2520            LspAction::Command(_) => {}
 2521        }
 2522
 2523        action.resolved = true;
 2524        anyhow::Ok(())
 2525    }
 2526
 2527    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2528        let buffer = buffer_handle.read(cx);
 2529
 2530        let file = buffer.file().cloned();
 2531
 2532        let Some(file) = File::from_dyn(file.as_ref()) else {
 2533            return;
 2534        };
 2535        if !file.is_local() {
 2536            return;
 2537        }
 2538        let path = ProjectPath::from_file(file, cx);
 2539        let worktree_id = file.worktree_id(cx);
 2540        let language = buffer.language().cloned();
 2541
 2542        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2543            for (server_id, diagnostics) in
 2544                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2545            {
 2546                self.update_buffer_diagnostics(
 2547                    buffer_handle,
 2548                    server_id,
 2549                    None,
 2550                    None,
 2551                    None,
 2552                    Vec::new(),
 2553                    diagnostics,
 2554                    cx,
 2555                )
 2556                .log_err();
 2557            }
 2558        }
 2559        let Some(language) = language else {
 2560            return;
 2561        };
 2562        let Some(snapshot) = self
 2563            .worktree_store
 2564            .read(cx)
 2565            .worktree_for_id(worktree_id, cx)
 2566            .map(|worktree| worktree.read(cx).snapshot())
 2567        else {
 2568            return;
 2569        };
 2570        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2571
 2572        for server_id in
 2573            self.lsp_tree
 2574                .get(path, language.name(), language.manifest(), &delegate, cx)
 2575        {
 2576            let server = self
 2577                .language_servers
 2578                .get(&server_id)
 2579                .and_then(|server_state| {
 2580                    if let LanguageServerState::Running { server, .. } = server_state {
 2581                        Some(server.clone())
 2582                    } else {
 2583                        None
 2584                    }
 2585                });
 2586            let server = match server {
 2587                Some(server) => server,
 2588                None => continue,
 2589            };
 2590
 2591            buffer_handle.update(cx, |buffer, cx| {
 2592                buffer.set_completion_triggers(
 2593                    server.server_id(),
 2594                    server
 2595                        .capabilities()
 2596                        .completion_provider
 2597                        .as_ref()
 2598                        .and_then(|provider| {
 2599                            provider
 2600                                .trigger_characters
 2601                                .as_ref()
 2602                                .map(|characters| characters.iter().cloned().collect())
 2603                        })
 2604                        .unwrap_or_default(),
 2605                    cx,
 2606                );
 2607            });
 2608        }
 2609    }
 2610
 2611    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2612        buffer.update(cx, |buffer, cx| {
 2613            let Some(language) = buffer.language() else {
 2614                return;
 2615            };
 2616            let path = ProjectPath {
 2617                worktree_id: old_file.worktree_id(cx),
 2618                path: old_file.path.clone(),
 2619            };
 2620            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2621                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2622                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2623            }
 2624        });
 2625    }
 2626
 2627    fn update_buffer_diagnostics(
 2628        &mut self,
 2629        buffer: &Entity<Buffer>,
 2630        server_id: LanguageServerId,
 2631        registration_id: Option<Option<SharedString>>,
 2632        result_id: Option<SharedString>,
 2633        version: Option<i32>,
 2634        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2636        cx: &mut Context<LspStore>,
 2637    ) -> Result<()> {
 2638        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2639            Ordering::Equal
 2640                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2641                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2642                .then_with(|| a.severity.cmp(&b.severity))
 2643                .then_with(|| a.message.cmp(&b.message))
 2644        }
 2645
 2646        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2647        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2648        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2649
 2650        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2651            Ordering::Equal
 2652                .then_with(|| a.range.start.cmp(&b.range.start))
 2653                .then_with(|| b.range.end.cmp(&a.range.end))
 2654                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2655        });
 2656
 2657        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2658
 2659        let edits_since_save = std::cell::LazyCell::new(|| {
 2660            let saved_version = buffer.read(cx).saved_version();
 2661            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2662        });
 2663
 2664        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2665
 2666        for (new_diagnostic, entry) in diagnostics {
 2667            let start;
 2668            let end;
 2669            if new_diagnostic && entry.diagnostic.is_disk_based {
 2670                // Some diagnostics are based on files on disk instead of buffers'
 2671                // current contents. Adjust these diagnostics' ranges to reflect
 2672                // any unsaved edits.
 2673                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2674                // and were properly adjusted on reuse.
 2675                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2676                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2677            } else {
 2678                start = entry.range.start;
 2679                end = entry.range.end;
 2680            }
 2681
 2682            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2683                ..snapshot.clip_point_utf16(end, Bias::Right);
 2684
 2685            // Expand empty ranges by one codepoint
 2686            if range.start == range.end {
 2687                // This will be go to the next boundary when being clipped
 2688                range.end.column += 1;
 2689                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2690                if range.start == range.end && range.end.column > 0 {
 2691                    range.start.column -= 1;
 2692                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2693                }
 2694            }
 2695
 2696            sanitized_diagnostics.push(DiagnosticEntry {
 2697                range,
 2698                diagnostic: entry.diagnostic,
 2699            });
 2700        }
 2701        drop(edits_since_save);
 2702
 2703        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2704        buffer.update(cx, |buffer, cx| {
 2705            if let Some(registration_id) = registration_id {
 2706                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2707                    self.buffer_pull_diagnostics_result_ids
 2708                        .entry(server_id)
 2709                        .or_default()
 2710                        .entry(registration_id)
 2711                        .or_default()
 2712                        .insert(abs_path, result_id);
 2713                }
 2714            }
 2715
 2716            buffer.update_diagnostics(server_id, set, cx)
 2717        });
 2718
 2719        Ok(())
 2720    }
 2721
 2722    fn register_language_server_for_invisible_worktree(
 2723        &mut self,
 2724        worktree: &Entity<Worktree>,
 2725        language_server_id: LanguageServerId,
 2726        cx: &mut App,
 2727    ) {
 2728        let worktree = worktree.read(cx);
 2729        let worktree_id = worktree.id();
 2730        debug_assert!(!worktree.is_visible());
 2731        let Some(mut origin_seed) = self
 2732            .language_server_ids
 2733            .iter()
 2734            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2735        else {
 2736            return;
 2737        };
 2738        origin_seed.worktree_id = worktree_id;
 2739        self.language_server_ids
 2740            .entry(origin_seed)
 2741            .or_insert_with(|| UnifiedLanguageServer {
 2742                id: language_server_id,
 2743                project_roots: Default::default(),
 2744            });
 2745    }
 2746
 2747    fn register_buffer_with_language_servers(
 2748        &mut self,
 2749        buffer_handle: &Entity<Buffer>,
 2750        only_register_servers: HashSet<LanguageServerSelector>,
 2751        cx: &mut Context<LspStore>,
 2752    ) {
 2753        let buffer = buffer_handle.read(cx);
 2754        let buffer_id = buffer.remote_id();
 2755
 2756        let Some(file) = File::from_dyn(buffer.file()) else {
 2757            return;
 2758        };
 2759        if !file.is_local() {
 2760            return;
 2761        }
 2762
 2763        let abs_path = file.abs_path(cx);
 2764        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2765            return;
 2766        };
 2767        let initial_snapshot = buffer.text_snapshot();
 2768        let worktree_id = file.worktree_id(cx);
 2769
 2770        let Some(language) = buffer.language().cloned() else {
 2771            return;
 2772        };
 2773        let path: Arc<RelPath> = file
 2774            .path()
 2775            .parent()
 2776            .map(Arc::from)
 2777            .unwrap_or_else(|| file.path().clone());
 2778        let Some(worktree) = self
 2779            .worktree_store
 2780            .read(cx)
 2781            .worktree_for_id(worktree_id, cx)
 2782        else {
 2783            return;
 2784        };
 2785        let language_name = language.name();
 2786        let (reused, delegate, servers) = self
 2787            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2788            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2789            .unwrap_or_else(|| {
 2790                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2791                let delegate: Arc<dyn ManifestDelegate> =
 2792                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2793
 2794                let servers = self
 2795                    .lsp_tree
 2796                    .walk(
 2797                        ProjectPath { worktree_id, path },
 2798                        language.name(),
 2799                        language.manifest(),
 2800                        &delegate,
 2801                        cx,
 2802                    )
 2803                    .collect::<Vec<_>>();
 2804                (false, lsp_delegate, servers)
 2805            });
 2806        let servers_and_adapters = servers
 2807            .into_iter()
 2808            .filter_map(|server_node| {
 2809                if reused && server_node.server_id().is_none() {
 2810                    return None;
 2811                }
 2812                if !only_register_servers.is_empty() {
 2813                    if let Some(server_id) = server_node.server_id()
 2814                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2815                    {
 2816                        return None;
 2817                    }
 2818                    if let Some(name) = server_node.name()
 2819                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2820                    {
 2821                        return None;
 2822                    }
 2823                }
 2824
 2825                let server_id = server_node.server_id_or_init(|disposition| {
 2826                    let path = &disposition.path;
 2827
 2828                    {
 2829                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2830
 2831                        let server_id = self.get_or_insert_language_server(
 2832                            &worktree,
 2833                            delegate.clone(),
 2834                            disposition,
 2835                            &language_name,
 2836                            cx,
 2837                        );
 2838
 2839                        if let Some(state) = self.language_servers.get(&server_id)
 2840                            && let Ok(uri) = uri
 2841                        {
 2842                            state.add_workspace_folder(uri);
 2843                        };
 2844                        server_id
 2845                    }
 2846                })?;
 2847                let server_state = self.language_servers.get(&server_id)?;
 2848                if let LanguageServerState::Running {
 2849                    server, adapter, ..
 2850                } = server_state
 2851                {
 2852                    Some((server.clone(), adapter.clone()))
 2853                } else {
 2854                    None
 2855                }
 2856            })
 2857            .collect::<Vec<_>>();
 2858        for (server, adapter) in servers_and_adapters {
 2859            buffer_handle.update(cx, |buffer, cx| {
 2860                buffer.set_completion_triggers(
 2861                    server.server_id(),
 2862                    server
 2863                        .capabilities()
 2864                        .completion_provider
 2865                        .as_ref()
 2866                        .and_then(|provider| {
 2867                            provider
 2868                                .trigger_characters
 2869                                .as_ref()
 2870                                .map(|characters| characters.iter().cloned().collect())
 2871                        })
 2872                        .unwrap_or_default(),
 2873                    cx,
 2874                );
 2875            });
 2876
 2877            let snapshot = LspBufferSnapshot {
 2878                version: 0,
 2879                snapshot: initial_snapshot.clone(),
 2880            };
 2881
 2882            let mut registered = false;
 2883            self.buffer_snapshots
 2884                .entry(buffer_id)
 2885                .or_default()
 2886                .entry(server.server_id())
 2887                .or_insert_with(|| {
 2888                    registered = true;
 2889                    server.register_buffer(
 2890                        uri.clone(),
 2891                        adapter.language_id(&language.name()),
 2892                        0,
 2893                        initial_snapshot.text(),
 2894                    );
 2895
 2896                    vec![snapshot]
 2897                });
 2898
 2899            self.buffers_opened_in_servers
 2900                .entry(buffer_id)
 2901                .or_default()
 2902                .insert(server.server_id());
 2903            if registered {
 2904                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2905                    language_server_id: server.server_id(),
 2906                    name: None,
 2907                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2908                        proto::RegisteredForBuffer {
 2909                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2910                            buffer_id: buffer_id.to_proto(),
 2911                        },
 2912                    ),
 2913                });
 2914            }
 2915        }
 2916    }
 2917
 2918    fn reuse_existing_language_server<'lang_name>(
 2919        &self,
 2920        server_tree: &LanguageServerTree,
 2921        worktree: &Entity<Worktree>,
 2922        language_name: &'lang_name LanguageName,
 2923        cx: &mut App,
 2924    ) -> Option<(
 2925        Arc<LocalLspAdapterDelegate>,
 2926        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2927    )> {
 2928        if worktree.read(cx).is_visible() {
 2929            return None;
 2930        }
 2931
 2932        let worktree_store = self.worktree_store.read(cx);
 2933        let servers = server_tree
 2934            .instances
 2935            .iter()
 2936            .filter(|(worktree_id, _)| {
 2937                worktree_store
 2938                    .worktree_for_id(**worktree_id, cx)
 2939                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2940            })
 2941            .flat_map(|(worktree_id, servers)| {
 2942                servers
 2943                    .roots
 2944                    .iter()
 2945                    .flat_map(|(_, language_servers)| language_servers)
 2946                    .map(move |(_, (server_node, server_languages))| {
 2947                        (worktree_id, server_node, server_languages)
 2948                    })
 2949                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2950                    .map(|(worktree_id, server_node, _)| {
 2951                        (
 2952                            *worktree_id,
 2953                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2954                        )
 2955                    })
 2956            })
 2957            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2958                acc.entry(worktree_id)
 2959                    .or_insert_with(Vec::new)
 2960                    .push(server_node);
 2961                acc
 2962            })
 2963            .into_values()
 2964            .max_by_key(|servers| servers.len())?;
 2965
 2966        let worktree_id = worktree.read(cx).id();
 2967        let apply = move |tree: &mut LanguageServerTree| {
 2968            for server_node in &servers {
 2969                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2970            }
 2971            servers
 2972        };
 2973
 2974        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2975        Some((delegate, apply))
 2976    }
 2977
 2978    pub(crate) fn unregister_old_buffer_from_language_servers(
 2979        &mut self,
 2980        buffer: &Entity<Buffer>,
 2981        old_file: &File,
 2982        cx: &mut App,
 2983    ) {
 2984        let old_path = match old_file.as_local() {
 2985            Some(local) => local.abs_path(cx),
 2986            None => return,
 2987        };
 2988
 2989        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2990            debug_panic!("{old_path:?} is not parseable as an URI");
 2991            return;
 2992        };
 2993        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2994    }
 2995
 2996    pub(crate) fn unregister_buffer_from_language_servers(
 2997        &mut self,
 2998        buffer: &Entity<Buffer>,
 2999        file_url: &lsp::Uri,
 3000        cx: &mut App,
 3001    ) {
 3002        buffer.update(cx, |buffer, cx| {
 3003            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3004
 3005            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3006                if snapshots
 3007                    .as_mut()
 3008                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3009                {
 3010                    language_server.unregister_buffer(file_url.clone());
 3011                }
 3012            }
 3013        });
 3014    }
 3015
 3016    fn buffer_snapshot_for_lsp_version(
 3017        &mut self,
 3018        buffer: &Entity<Buffer>,
 3019        server_id: LanguageServerId,
 3020        version: Option<i32>,
 3021        cx: &App,
 3022    ) -> Result<TextBufferSnapshot> {
 3023        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3024
 3025        if let Some(version) = version {
 3026            let buffer_id = buffer.read(cx).remote_id();
 3027            let snapshots = if let Some(snapshots) = self
 3028                .buffer_snapshots
 3029                .get_mut(&buffer_id)
 3030                .and_then(|m| m.get_mut(&server_id))
 3031            {
 3032                snapshots
 3033            } else if version == 0 {
 3034                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3035                // We detect this case and treat it as if the version was `None`.
 3036                return Ok(buffer.read(cx).text_snapshot());
 3037            } else {
 3038                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3039            };
 3040
 3041            let found_snapshot = snapshots
 3042                    .binary_search_by_key(&version, |e| e.version)
 3043                    .map(|ix| snapshots[ix].snapshot.clone())
 3044                    .map_err(|_| {
 3045                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3046                    })?;
 3047
 3048            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3049            Ok(found_snapshot)
 3050        } else {
 3051            Ok((buffer.read(cx)).text_snapshot())
 3052        }
 3053    }
 3054
 3055    async fn get_server_code_actions_from_action_kinds(
 3056        lsp_store: &WeakEntity<LspStore>,
 3057        language_server_id: LanguageServerId,
 3058        code_action_kinds: Vec<lsp::CodeActionKind>,
 3059        buffer: &Entity<Buffer>,
 3060        cx: &mut AsyncApp,
 3061    ) -> Result<Vec<CodeAction>> {
 3062        let actions = lsp_store
 3063            .update(cx, move |this, cx| {
 3064                let request = GetCodeActions {
 3065                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3066                    kinds: Some(code_action_kinds),
 3067                };
 3068                let server = LanguageServerToQuery::Other(language_server_id);
 3069                this.request_lsp(buffer.clone(), server, request, cx)
 3070            })?
 3071            .await?;
 3072        Ok(actions)
 3073    }
 3074
 3075    pub async fn execute_code_actions_on_server(
 3076        lsp_store: &WeakEntity<LspStore>,
 3077        language_server: &Arc<LanguageServer>,
 3078        actions: Vec<CodeAction>,
 3079        push_to_history: bool,
 3080        project_transaction: &mut ProjectTransaction,
 3081        cx: &mut AsyncApp,
 3082    ) -> anyhow::Result<()> {
 3083        let request_timeout = cx.update(|app| {
 3084            ProjectSettings::get_global(app)
 3085                .global_lsp_settings
 3086                .get_request_timeout()
 3087        });
 3088
 3089        for mut action in actions {
 3090            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3091                .await
 3092                .context("resolving a formatting code action")?;
 3093
 3094            if let Some(edit) = action.lsp_action.edit() {
 3095                if edit.changes.is_none() && edit.document_changes.is_none() {
 3096                    continue;
 3097                }
 3098
 3099                let new = Self::deserialize_workspace_edit(
 3100                    lsp_store.upgrade().context("project dropped")?,
 3101                    edit.clone(),
 3102                    push_to_history,
 3103                    language_server.clone(),
 3104                    cx,
 3105                )
 3106                .await?;
 3107                project_transaction.0.extend(new.0);
 3108            }
 3109
 3110            let Some(command) = action.lsp_action.command() else {
 3111                continue;
 3112            };
 3113
 3114            let server_capabilities = language_server.capabilities();
 3115            let available_commands = server_capabilities
 3116                .execute_command_provider
 3117                .as_ref()
 3118                .map(|options| options.commands.as_slice())
 3119                .unwrap_or_default();
 3120            if !available_commands.contains(&command.command) {
 3121                log::warn!(
 3122                    "Cannot execute a command {} not listed in the language server capabilities",
 3123                    command.command
 3124                );
 3125                continue;
 3126            }
 3127
 3128            lsp_store.update(cx, |lsp_store, _| {
 3129                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3130                    mode.last_workspace_edits_by_language_server
 3131                        .remove(&language_server.server_id());
 3132                }
 3133            })?;
 3134
 3135            language_server
 3136                .request::<lsp::request::ExecuteCommand>(
 3137                    lsp::ExecuteCommandParams {
 3138                        command: command.command.clone(),
 3139                        arguments: command.arguments.clone().unwrap_or_default(),
 3140                        ..Default::default()
 3141                    },
 3142                    request_timeout,
 3143                )
 3144                .await
 3145                .into_response()
 3146                .context("execute command")?;
 3147
 3148            lsp_store.update(cx, |this, _| {
 3149                if let LspStoreMode::Local(mode) = &mut this.mode {
 3150                    project_transaction.0.extend(
 3151                        mode.last_workspace_edits_by_language_server
 3152                            .remove(&language_server.server_id())
 3153                            .unwrap_or_default()
 3154                            .0,
 3155                    )
 3156                }
 3157            })?;
 3158        }
 3159        Ok(())
 3160    }
 3161
 3162    pub async fn deserialize_text_edits(
 3163        this: Entity<LspStore>,
 3164        buffer_to_edit: Entity<Buffer>,
 3165        edits: Vec<lsp::TextEdit>,
 3166        push_to_history: bool,
 3167        _: Arc<CachedLspAdapter>,
 3168        language_server: Arc<LanguageServer>,
 3169        cx: &mut AsyncApp,
 3170    ) -> Result<Option<Transaction>> {
 3171        let edits = this
 3172            .update(cx, |this, cx| {
 3173                this.as_local_mut().unwrap().edits_from_lsp(
 3174                    &buffer_to_edit,
 3175                    edits,
 3176                    language_server.server_id(),
 3177                    None,
 3178                    cx,
 3179                )
 3180            })
 3181            .await?;
 3182
 3183        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3184            buffer.finalize_last_transaction();
 3185            buffer.start_transaction();
 3186            for (range, text) in edits {
 3187                buffer.edit([(range, text)], None, cx);
 3188            }
 3189
 3190            if buffer.end_transaction(cx).is_some() {
 3191                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3192                if !push_to_history {
 3193                    buffer.forget_transaction(transaction.id);
 3194                }
 3195                Some(transaction)
 3196            } else {
 3197                None
 3198            }
 3199        });
 3200
 3201        Ok(transaction)
 3202    }
 3203
 3204    #[allow(clippy::type_complexity)]
 3205    pub fn edits_from_lsp(
 3206        &mut self,
 3207        buffer: &Entity<Buffer>,
 3208        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3209        server_id: LanguageServerId,
 3210        version: Option<i32>,
 3211        cx: &mut Context<LspStore>,
 3212    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3213        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3214        cx.background_spawn(async move {
 3215            let snapshot = snapshot?;
 3216            let mut lsp_edits = lsp_edits
 3217                .into_iter()
 3218                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3219                .collect::<Vec<_>>();
 3220
 3221            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3222
 3223            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3224            let mut edits = Vec::new();
 3225            while let Some((range, mut new_text)) = lsp_edits.next() {
 3226                // Clip invalid ranges provided by the language server.
 3227                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3228                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3229
 3230                // Combine any LSP edits that are adjacent.
 3231                //
 3232                // Also, combine LSP edits that are separated from each other by only
 3233                // a newline. This is important because for some code actions,
 3234                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3235                // are separated by unchanged newline characters.
 3236                //
 3237                // In order for the diffing logic below to work properly, any edits that
 3238                // cancel each other out must be combined into one.
 3239                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3240                    if next_range.start.0 > range.end {
 3241                        if next_range.start.0.row > range.end.row + 1
 3242                            || next_range.start.0.column > 0
 3243                            || snapshot.clip_point_utf16(
 3244                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3245                                Bias::Left,
 3246                            ) > range.end
 3247                        {
 3248                            break;
 3249                        }
 3250                        new_text.push('\n');
 3251                    }
 3252                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3253                    new_text.push_str(next_text);
 3254                    lsp_edits.next();
 3255                }
 3256
 3257                // For multiline edits, perform a diff of the old and new text so that
 3258                // we can identify the changes more precisely, preserving the locations
 3259                // of any anchors positioned in the unchanged regions.
 3260                if range.end.row > range.start.row {
 3261                    let offset = range.start.to_offset(&snapshot);
 3262                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3263                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3264                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3265                        (
 3266                            snapshot.anchor_after(offset + range.start)
 3267                                ..snapshot.anchor_before(offset + range.end),
 3268                            replacement,
 3269                        )
 3270                    }));
 3271                } else if range.end == range.start {
 3272                    let anchor = snapshot.anchor_after(range.start);
 3273                    edits.push((anchor..anchor, new_text.into()));
 3274                } else {
 3275                    let edit_start = snapshot.anchor_after(range.start);
 3276                    let edit_end = snapshot.anchor_before(range.end);
 3277                    edits.push((edit_start..edit_end, new_text.into()));
 3278                }
 3279            }
 3280
 3281            Ok(edits)
 3282        })
 3283    }
 3284
 3285    pub(crate) async fn deserialize_workspace_edit(
 3286        this: Entity<LspStore>,
 3287        edit: lsp::WorkspaceEdit,
 3288        push_to_history: bool,
 3289        language_server: Arc<LanguageServer>,
 3290        cx: &mut AsyncApp,
 3291    ) -> Result<ProjectTransaction> {
 3292        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3293
 3294        let mut operations = Vec::new();
 3295        if let Some(document_changes) = edit.document_changes {
 3296            match document_changes {
 3297                lsp::DocumentChanges::Edits(edits) => {
 3298                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3299                }
 3300                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3301            }
 3302        } else if let Some(changes) = edit.changes {
 3303            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3304                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3305                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3306                        uri,
 3307                        version: None,
 3308                    },
 3309                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3310                })
 3311            }));
 3312        }
 3313
 3314        let mut project_transaction = ProjectTransaction::default();
 3315        for operation in operations {
 3316            match operation {
 3317                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3318                    let abs_path = op
 3319                        .uri
 3320                        .to_file_path()
 3321                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3322
 3323                    if let Some(parent_path) = abs_path.parent() {
 3324                        fs.create_dir(parent_path).await?;
 3325                    }
 3326                    if abs_path.ends_with("/") {
 3327                        fs.create_dir(&abs_path).await?;
 3328                    } else {
 3329                        fs.create_file(
 3330                            &abs_path,
 3331                            op.options
 3332                                .map(|options| fs::CreateOptions {
 3333                                    overwrite: options.overwrite.unwrap_or(false),
 3334                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3335                                })
 3336                                .unwrap_or_default(),
 3337                        )
 3338                        .await?;
 3339                    }
 3340                }
 3341
 3342                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3343                    let source_abs_path = op
 3344                        .old_uri
 3345                        .to_file_path()
 3346                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3347                    let target_abs_path = op
 3348                        .new_uri
 3349                        .to_file_path()
 3350                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3351
 3352                    let options = fs::RenameOptions {
 3353                        overwrite: op
 3354                            .options
 3355                            .as_ref()
 3356                            .and_then(|options| options.overwrite)
 3357                            .unwrap_or(false),
 3358                        ignore_if_exists: op
 3359                            .options
 3360                            .as_ref()
 3361                            .and_then(|options| options.ignore_if_exists)
 3362                            .unwrap_or(false),
 3363                        create_parents: true,
 3364                    };
 3365
 3366                    fs.rename(&source_abs_path, &target_abs_path, options)
 3367                        .await?;
 3368                }
 3369
 3370                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3371                    let abs_path = op
 3372                        .uri
 3373                        .to_file_path()
 3374                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3375                    let options = op
 3376                        .options
 3377                        .map(|options| fs::RemoveOptions {
 3378                            recursive: options.recursive.unwrap_or(false),
 3379                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3380                        })
 3381                        .unwrap_or_default();
 3382                    if abs_path.ends_with("/") {
 3383                        fs.remove_dir(&abs_path, options).await?;
 3384                    } else {
 3385                        fs.remove_file(&abs_path, options).await?;
 3386                    }
 3387                }
 3388
 3389                lsp::DocumentChangeOperation::Edit(op) => {
 3390                    let buffer_to_edit = this
 3391                        .update(cx, |this, cx| {
 3392                            this.open_local_buffer_via_lsp(
 3393                                op.text_document.uri.clone(),
 3394                                language_server.server_id(),
 3395                                cx,
 3396                            )
 3397                        })
 3398                        .await?;
 3399
 3400                    let edits = this
 3401                        .update(cx, |this, cx| {
 3402                            let path = buffer_to_edit.read(cx).project_path(cx);
 3403                            let active_entry = this.active_entry;
 3404                            let is_active_entry = path.is_some_and(|project_path| {
 3405                                this.worktree_store
 3406                                    .read(cx)
 3407                                    .entry_for_path(&project_path, cx)
 3408                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3409                            });
 3410                            let local = this.as_local_mut().unwrap();
 3411
 3412                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3413                            for edit in op.edits {
 3414                                match edit {
 3415                                    Edit::Plain(edit) => {
 3416                                        if !edits.contains(&edit) {
 3417                                            edits.push(edit)
 3418                                        }
 3419                                    }
 3420                                    Edit::Annotated(edit) => {
 3421                                        if !edits.contains(&edit.text_edit) {
 3422                                            edits.push(edit.text_edit)
 3423                                        }
 3424                                    }
 3425                                    Edit::Snippet(edit) => {
 3426                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3427                                        else {
 3428                                            continue;
 3429                                        };
 3430
 3431                                        if is_active_entry {
 3432                                            snippet_edits.push((edit.range, snippet));
 3433                                        } else {
 3434                                            // Since this buffer is not focused, apply a normal edit.
 3435                                            let new_edit = TextEdit {
 3436                                                range: edit.range,
 3437                                                new_text: snippet.text,
 3438                                            };
 3439                                            if !edits.contains(&new_edit) {
 3440                                                edits.push(new_edit);
 3441                                            }
 3442                                        }
 3443                                    }
 3444                                }
 3445                            }
 3446                            if !snippet_edits.is_empty() {
 3447                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3448                                let version = if let Some(buffer_version) = op.text_document.version
 3449                                {
 3450                                    local
 3451                                        .buffer_snapshot_for_lsp_version(
 3452                                            &buffer_to_edit,
 3453                                            language_server.server_id(),
 3454                                            Some(buffer_version),
 3455                                            cx,
 3456                                        )
 3457                                        .ok()
 3458                                        .map(|snapshot| snapshot.version)
 3459                                } else {
 3460                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3461                                };
 3462
 3463                                let most_recent_edit =
 3464                                    version.and_then(|version| version.most_recent());
 3465                                // Check if the edit that triggered that edit has been made by this participant.
 3466
 3467                                if let Some(most_recent_edit) = most_recent_edit {
 3468                                    cx.emit(LspStoreEvent::SnippetEdit {
 3469                                        buffer_id,
 3470                                        edits: snippet_edits,
 3471                                        most_recent_edit,
 3472                                    });
 3473                                }
 3474                            }
 3475
 3476                            local.edits_from_lsp(
 3477                                &buffer_to_edit,
 3478                                edits,
 3479                                language_server.server_id(),
 3480                                op.text_document.version,
 3481                                cx,
 3482                            )
 3483                        })
 3484                        .await?;
 3485
 3486                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3487                        buffer.finalize_last_transaction();
 3488                        buffer.start_transaction();
 3489                        for (range, text) in edits {
 3490                            buffer.edit([(range, text)], None, cx);
 3491                        }
 3492
 3493                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3494                            if push_to_history {
 3495                                buffer.finalize_last_transaction();
 3496                                buffer.get_transaction(transaction_id).cloned()
 3497                            } else {
 3498                                buffer.forget_transaction(transaction_id)
 3499                            }
 3500                        })
 3501                    });
 3502                    if let Some(transaction) = transaction {
 3503                        project_transaction.0.insert(buffer_to_edit, transaction);
 3504                    }
 3505                }
 3506            }
 3507        }
 3508
 3509        Ok(project_transaction)
 3510    }
 3511
 3512    async fn on_lsp_workspace_edit(
 3513        this: WeakEntity<LspStore>,
 3514        params: lsp::ApplyWorkspaceEditParams,
 3515        server_id: LanguageServerId,
 3516        cx: &mut AsyncApp,
 3517    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3518        let this = this.upgrade().context("project project closed")?;
 3519        let language_server = this
 3520            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3521            .context("language server not found")?;
 3522        let transaction = Self::deserialize_workspace_edit(
 3523            this.clone(),
 3524            params.edit,
 3525            true,
 3526            language_server.clone(),
 3527            cx,
 3528        )
 3529        .await
 3530        .log_err();
 3531        this.update(cx, |this, cx| {
 3532            if let Some(transaction) = transaction {
 3533                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3534
 3535                this.as_local_mut()
 3536                    .unwrap()
 3537                    .last_workspace_edits_by_language_server
 3538                    .insert(server_id, transaction);
 3539            }
 3540        });
 3541        Ok(lsp::ApplyWorkspaceEditResponse {
 3542            applied: true,
 3543            failed_change: None,
 3544            failure_reason: None,
 3545        })
 3546    }
 3547
 3548    fn remove_worktree(
 3549        &mut self,
 3550        id_to_remove: WorktreeId,
 3551        cx: &mut Context<LspStore>,
 3552    ) -> Vec<LanguageServerId> {
 3553        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3554        self.diagnostics.remove(&id_to_remove);
 3555        self.prettier_store.update(cx, |prettier_store, cx| {
 3556            prettier_store.remove_worktree(id_to_remove, cx);
 3557        });
 3558
 3559        let mut servers_to_remove = BTreeSet::default();
 3560        let mut servers_to_preserve = HashSet::default();
 3561        for (seed, state) in &self.language_server_ids {
 3562            if seed.worktree_id == id_to_remove {
 3563                servers_to_remove.insert(state.id);
 3564            } else {
 3565                servers_to_preserve.insert(state.id);
 3566            }
 3567        }
 3568        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3569        self.language_server_ids
 3570            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3571        for server_id_to_remove in &servers_to_remove {
 3572            self.language_server_watched_paths
 3573                .remove(server_id_to_remove);
 3574            self.language_server_paths_watched_for_rename
 3575                .remove(server_id_to_remove);
 3576            self.last_workspace_edits_by_language_server
 3577                .remove(server_id_to_remove);
 3578            self.language_servers.remove(server_id_to_remove);
 3579            self.buffer_pull_diagnostics_result_ids
 3580                .remove(server_id_to_remove);
 3581            self.workspace_pull_diagnostics_result_ids
 3582                .remove(server_id_to_remove);
 3583            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3584                buffer_servers.remove(server_id_to_remove);
 3585            }
 3586            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3587        }
 3588        servers_to_remove.into_iter().collect()
 3589    }
 3590
 3591    fn rebuild_watched_paths_inner<'a>(
 3592        &'a self,
 3593        language_server_id: LanguageServerId,
 3594        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3595        cx: &mut Context<LspStore>,
 3596    ) -> LanguageServerWatchedPathsBuilder {
 3597        let worktrees = self
 3598            .worktree_store
 3599            .read(cx)
 3600            .worktrees()
 3601            .filter_map(|worktree| {
 3602                self.language_servers_for_worktree(worktree.read(cx).id())
 3603                    .find(|server| server.server_id() == language_server_id)
 3604                    .map(|_| worktree)
 3605            })
 3606            .collect::<Vec<_>>();
 3607
 3608        let mut worktree_globs = HashMap::default();
 3609        let mut abs_globs = HashMap::default();
 3610        log::trace!(
 3611            "Processing new watcher paths for language server with id {}",
 3612            language_server_id
 3613        );
 3614
 3615        for watcher in watchers {
 3616            if let Some((worktree, literal_prefix, pattern)) =
 3617                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3618            {
 3619                worktree.update(cx, |worktree, _| {
 3620                    if let Some((tree, glob)) =
 3621                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3622                    {
 3623                        tree.add_path_prefix_to_scan(literal_prefix);
 3624                        worktree_globs
 3625                            .entry(tree.id())
 3626                            .or_insert_with(GlobSetBuilder::new)
 3627                            .add(glob);
 3628                    }
 3629                });
 3630            } else {
 3631                let (path, pattern) = match &watcher.glob_pattern {
 3632                    lsp::GlobPattern::String(s) => {
 3633                        let watcher_path = SanitizedPath::new(s);
 3634                        let path = glob_literal_prefix(watcher_path.as_path());
 3635                        let pattern = watcher_path
 3636                            .as_path()
 3637                            .strip_prefix(&path)
 3638                            .map(|p| p.to_string_lossy().into_owned())
 3639                            .unwrap_or_else(|e| {
 3640                                debug_panic!(
 3641                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3642                                    s,
 3643                                    path.display(),
 3644                                    e
 3645                                );
 3646                                watcher_path.as_path().to_string_lossy().into_owned()
 3647                            });
 3648                        (path, pattern)
 3649                    }
 3650                    lsp::GlobPattern::Relative(rp) => {
 3651                        let Ok(mut base_uri) = match &rp.base_uri {
 3652                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3653                            lsp::OneOf::Right(base_uri) => base_uri,
 3654                        }
 3655                        .to_file_path() else {
 3656                            continue;
 3657                        };
 3658
 3659                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3660                        let pattern = Path::new(&rp.pattern)
 3661                            .strip_prefix(&path)
 3662                            .map(|p| p.to_string_lossy().into_owned())
 3663                            .unwrap_or_else(|e| {
 3664                                debug_panic!(
 3665                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3666                                    rp.pattern,
 3667                                    path.display(),
 3668                                    e
 3669                                );
 3670                                rp.pattern.clone()
 3671                            });
 3672                        base_uri.push(path);
 3673                        (base_uri, pattern)
 3674                    }
 3675                };
 3676
 3677                if let Some(glob) = Glob::new(&pattern).log_err() {
 3678                    if !path
 3679                        .components()
 3680                        .any(|c| matches!(c, path::Component::Normal(_)))
 3681                    {
 3682                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3683                        // rather than adding a new watcher for `/`.
 3684                        for worktree in &worktrees {
 3685                            worktree_globs
 3686                                .entry(worktree.read(cx).id())
 3687                                .or_insert_with(GlobSetBuilder::new)
 3688                                .add(glob.clone());
 3689                        }
 3690                    } else {
 3691                        abs_globs
 3692                            .entry(path.into())
 3693                            .or_insert_with(GlobSetBuilder::new)
 3694                            .add(glob);
 3695                    }
 3696                }
 3697            }
 3698        }
 3699
 3700        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3701        for (worktree_id, builder) in worktree_globs {
 3702            if let Ok(globset) = builder.build() {
 3703                watch_builder.watch_worktree(worktree_id, globset);
 3704            }
 3705        }
 3706        for (abs_path, builder) in abs_globs {
 3707            if let Ok(globset) = builder.build() {
 3708                watch_builder.watch_abs_path(abs_path, globset);
 3709            }
 3710        }
 3711        watch_builder
 3712    }
 3713
 3714    fn worktree_and_path_for_file_watcher(
 3715        worktrees: &[Entity<Worktree>],
 3716        watcher: &FileSystemWatcher,
 3717        cx: &App,
 3718    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3719        worktrees.iter().find_map(|worktree| {
 3720            let tree = worktree.read(cx);
 3721            let worktree_root_path = tree.abs_path();
 3722            let path_style = tree.path_style();
 3723            match &watcher.glob_pattern {
 3724                lsp::GlobPattern::String(s) => {
 3725                    let watcher_path = SanitizedPath::new(s);
 3726                    let relative = watcher_path
 3727                        .as_path()
 3728                        .strip_prefix(&worktree_root_path)
 3729                        .ok()?;
 3730                    let literal_prefix = glob_literal_prefix(relative);
 3731                    Some((
 3732                        worktree.clone(),
 3733                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3734                        relative.to_string_lossy().into_owned(),
 3735                    ))
 3736                }
 3737                lsp::GlobPattern::Relative(rp) => {
 3738                    let base_uri = match &rp.base_uri {
 3739                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3740                        lsp::OneOf::Right(base_uri) => base_uri,
 3741                    }
 3742                    .to_file_path()
 3743                    .ok()?;
 3744                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3745                    let mut literal_prefix = relative.to_owned();
 3746                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3747                    Some((
 3748                        worktree.clone(),
 3749                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3750                        rp.pattern.clone(),
 3751                    ))
 3752                }
 3753            }
 3754        })
 3755    }
 3756
 3757    fn rebuild_watched_paths(
 3758        &mut self,
 3759        language_server_id: LanguageServerId,
 3760        cx: &mut Context<LspStore>,
 3761    ) {
 3762        let Some(registrations) = self
 3763            .language_server_dynamic_registrations
 3764            .get(&language_server_id)
 3765        else {
 3766            return;
 3767        };
 3768
 3769        let watch_builder = self.rebuild_watched_paths_inner(
 3770            language_server_id,
 3771            registrations.did_change_watched_files.values().flatten(),
 3772            cx,
 3773        );
 3774        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3775        self.language_server_watched_paths
 3776            .insert(language_server_id, watcher);
 3777
 3778        cx.notify();
 3779    }
 3780
 3781    fn on_lsp_did_change_watched_files(
 3782        &mut self,
 3783        language_server_id: LanguageServerId,
 3784        registration_id: &str,
 3785        params: DidChangeWatchedFilesRegistrationOptions,
 3786        cx: &mut Context<LspStore>,
 3787    ) {
 3788        let registrations = self
 3789            .language_server_dynamic_registrations
 3790            .entry(language_server_id)
 3791            .or_default();
 3792
 3793        registrations
 3794            .did_change_watched_files
 3795            .insert(registration_id.to_string(), params.watchers);
 3796
 3797        self.rebuild_watched_paths(language_server_id, cx);
 3798    }
 3799
 3800    fn on_lsp_unregister_did_change_watched_files(
 3801        &mut self,
 3802        language_server_id: LanguageServerId,
 3803        registration_id: &str,
 3804        cx: &mut Context<LspStore>,
 3805    ) {
 3806        let registrations = self
 3807            .language_server_dynamic_registrations
 3808            .entry(language_server_id)
 3809            .or_default();
 3810
 3811        if registrations
 3812            .did_change_watched_files
 3813            .remove(registration_id)
 3814            .is_some()
 3815        {
 3816            log::info!(
 3817                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3818                language_server_id,
 3819                registration_id
 3820            );
 3821        } else {
 3822            log::warn!(
 3823                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3824                language_server_id,
 3825                registration_id
 3826            );
 3827        }
 3828
 3829        self.rebuild_watched_paths(language_server_id, cx);
 3830    }
 3831
 3832    async fn initialization_options_for_adapter(
 3833        adapter: Arc<dyn LspAdapter>,
 3834        delegate: &Arc<dyn LspAdapterDelegate>,
 3835        cx: &mut AsyncApp,
 3836    ) -> Result<Option<serde_json::Value>> {
 3837        let Some(mut initialization_config) =
 3838            adapter.clone().initialization_options(delegate, cx).await?
 3839        else {
 3840            return Ok(None);
 3841        };
 3842
 3843        for other_adapter in delegate.registered_lsp_adapters() {
 3844            if other_adapter.name() == adapter.name() {
 3845                continue;
 3846            }
 3847            if let Ok(Some(target_config)) = other_adapter
 3848                .clone()
 3849                .additional_initialization_options(adapter.name(), delegate)
 3850                .await
 3851            {
 3852                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3853            }
 3854        }
 3855
 3856        Ok(Some(initialization_config))
 3857    }
 3858
 3859    async fn workspace_configuration_for_adapter(
 3860        adapter: Arc<dyn LspAdapter>,
 3861        delegate: &Arc<dyn LspAdapterDelegate>,
 3862        toolchain: Option<Toolchain>,
 3863        requested_uri: Option<Uri>,
 3864        cx: &mut AsyncApp,
 3865    ) -> Result<serde_json::Value> {
 3866        let mut workspace_config = adapter
 3867            .clone()
 3868            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3869            .await?;
 3870
 3871        for other_adapter in delegate.registered_lsp_adapters() {
 3872            if other_adapter.name() == adapter.name() {
 3873                continue;
 3874            }
 3875            if let Ok(Some(target_config)) = other_adapter
 3876                .clone()
 3877                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3878                .await
 3879            {
 3880                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3881            }
 3882        }
 3883
 3884        Ok(workspace_config)
 3885    }
 3886
 3887    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3888        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3889            Some(server.clone())
 3890        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3891            Some(Arc::clone(server))
 3892        } else {
 3893            None
 3894        }
 3895    }
 3896}
 3897
 3898fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3899    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3900        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3901            language_server_id: server.server_id(),
 3902            name: Some(server.name()),
 3903            message: proto::update_language_server::Variant::MetadataUpdated(
 3904                proto::ServerMetadataUpdated {
 3905                    capabilities: Some(capabilities),
 3906                    binary: Some(proto::LanguageServerBinaryInfo {
 3907                        path: server.binary().path.to_string_lossy().into_owned(),
 3908                        arguments: server
 3909                            .binary()
 3910                            .arguments
 3911                            .iter()
 3912                            .map(|arg| arg.to_string_lossy().into_owned())
 3913                            .collect(),
 3914                    }),
 3915                    configuration: serde_json::to_string(server.configuration()).ok(),
 3916                    workspace_folders: server
 3917                        .workspace_folders()
 3918                        .iter()
 3919                        .map(|uri| uri.to_string())
 3920                        .collect(),
 3921                },
 3922            ),
 3923        });
 3924    }
 3925}
 3926
 3927#[derive(Debug)]
 3928pub struct FormattableBuffer {
 3929    handle: Entity<Buffer>,
 3930    abs_path: Option<PathBuf>,
 3931    env: Option<HashMap<String, String>>,
 3932    ranges: Option<Vec<Range<Anchor>>>,
 3933}
 3934
 3935pub struct RemoteLspStore {
 3936    upstream_client: Option<AnyProtoClient>,
 3937    upstream_project_id: u64,
 3938}
 3939
 3940pub(crate) enum LspStoreMode {
 3941    Local(LocalLspStore),   // ssh host and collab host
 3942    Remote(RemoteLspStore), // collab guest
 3943}
 3944
 3945impl LspStoreMode {
 3946    fn is_local(&self) -> bool {
 3947        matches!(self, LspStoreMode::Local(_))
 3948    }
 3949}
 3950
 3951pub struct LspStore {
 3952    mode: LspStoreMode,
 3953    last_formatting_failure: Option<String>,
 3954    downstream_client: Option<(AnyProtoClient, u64)>,
 3955    nonce: u128,
 3956    buffer_store: Entity<BufferStore>,
 3957    worktree_store: Entity<WorktreeStore>,
 3958    pub languages: Arc<LanguageRegistry>,
 3959    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3960    active_entry: Option<ProjectEntryId>,
 3961    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3962    _maintain_buffer_languages: Task<()>,
 3963    diagnostic_summaries:
 3964        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3965    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3966    semantic_token_config: SemanticTokenConfig,
 3967    lsp_data: HashMap<BufferId, BufferLspData>,
 3968    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3969    next_hint_id: Arc<AtomicUsize>,
 3970}
 3971
 3972#[derive(Debug)]
 3973pub struct BufferLspData {
 3974    buffer_version: Global,
 3975    document_colors: Option<DocumentColorData>,
 3976    code_lens: Option<CodeLensData>,
 3977    semantic_tokens: Option<SemanticTokensData>,
 3978    folding_ranges: Option<FoldingRangeData>,
 3979    document_symbols: Option<DocumentSymbolsData>,
 3980    inlay_hints: BufferInlayHints,
 3981    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3982    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3983}
 3984
 3985#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3986struct LspKey {
 3987    request_type: TypeId,
 3988    server_queried: Option<LanguageServerId>,
 3989}
 3990
 3991impl BufferLspData {
 3992    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3993        Self {
 3994            buffer_version: buffer.read(cx).version(),
 3995            document_colors: None,
 3996            code_lens: None,
 3997            semantic_tokens: None,
 3998            folding_ranges: None,
 3999            document_symbols: None,
 4000            inlay_hints: BufferInlayHints::new(buffer, cx),
 4001            lsp_requests: HashMap::default(),
 4002            chunk_lsp_requests: HashMap::default(),
 4003        }
 4004    }
 4005
 4006    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4007        if let Some(document_colors) = &mut self.document_colors {
 4008            document_colors.remove_server_data(for_server);
 4009        }
 4010
 4011        if let Some(code_lens) = &mut self.code_lens {
 4012            code_lens.remove_server_data(for_server);
 4013        }
 4014
 4015        self.inlay_hints.remove_server_data(for_server);
 4016
 4017        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4018            semantic_tokens.remove_server_data(for_server);
 4019        }
 4020
 4021        if let Some(folding_ranges) = &mut self.folding_ranges {
 4022            folding_ranges.ranges.remove(&for_server);
 4023        }
 4024
 4025        if let Some(document_symbols) = &mut self.document_symbols {
 4026            document_symbols.remove_server_data(for_server);
 4027        }
 4028    }
 4029
 4030    #[cfg(any(test, feature = "test-support"))]
 4031    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4032        &self.inlay_hints
 4033    }
 4034}
 4035
 4036#[derive(Debug)]
 4037pub enum LspStoreEvent {
 4038    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4039    LanguageServerRemoved(LanguageServerId),
 4040    LanguageServerUpdate {
 4041        language_server_id: LanguageServerId,
 4042        name: Option<LanguageServerName>,
 4043        message: proto::update_language_server::Variant,
 4044    },
 4045    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4046    LanguageServerPrompt(LanguageServerPromptRequest),
 4047    LanguageDetected {
 4048        buffer: Entity<Buffer>,
 4049        new_language: Option<Arc<Language>>,
 4050    },
 4051    Notification(String),
 4052    RefreshInlayHints {
 4053        server_id: LanguageServerId,
 4054        request_id: Option<usize>,
 4055    },
 4056    RefreshSemanticTokens {
 4057        server_id: LanguageServerId,
 4058        request_id: Option<usize>,
 4059    },
 4060    RefreshCodeLens,
 4061    DiagnosticsUpdated {
 4062        server_id: LanguageServerId,
 4063        paths: Vec<ProjectPath>,
 4064    },
 4065    DiskBasedDiagnosticsStarted {
 4066        language_server_id: LanguageServerId,
 4067    },
 4068    DiskBasedDiagnosticsFinished {
 4069        language_server_id: LanguageServerId,
 4070    },
 4071    SnippetEdit {
 4072        buffer_id: BufferId,
 4073        edits: Vec<(lsp::Range, Snippet)>,
 4074        most_recent_edit: clock::Lamport,
 4075    },
 4076    WorkspaceEditApplied(ProjectTransaction),
 4077}
 4078
 4079#[derive(Clone, Debug, Serialize)]
 4080pub struct LanguageServerStatus {
 4081    pub name: LanguageServerName,
 4082    pub server_version: Option<SharedString>,
 4083    pub server_readable_version: Option<SharedString>,
 4084    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4085    pub has_pending_diagnostic_updates: bool,
 4086    pub progress_tokens: HashSet<ProgressToken>,
 4087    pub worktree: Option<WorktreeId>,
 4088    pub binary: Option<LanguageServerBinary>,
 4089    pub configuration: Option<Value>,
 4090    pub workspace_folders: BTreeSet<Uri>,
 4091    pub process_id: Option<u32>,
 4092}
 4093
 4094#[derive(Clone, Debug)]
 4095struct CoreSymbol {
 4096    pub language_server_name: LanguageServerName,
 4097    pub source_worktree_id: WorktreeId,
 4098    pub source_language_server_id: LanguageServerId,
 4099    pub path: SymbolLocation,
 4100    pub name: String,
 4101    pub kind: lsp::SymbolKind,
 4102    pub range: Range<Unclipped<PointUtf16>>,
 4103    pub container_name: Option<String>,
 4104}
 4105
 4106#[derive(Clone, Debug, PartialEq, Eq)]
 4107pub enum SymbolLocation {
 4108    InProject(ProjectPath),
 4109    OutsideProject {
 4110        abs_path: Arc<Path>,
 4111        signature: [u8; 32],
 4112    },
 4113}
 4114
 4115impl SymbolLocation {
 4116    fn file_name(&self) -> Option<&str> {
 4117        match self {
 4118            Self::InProject(path) => path.path.file_name(),
 4119            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4120        }
 4121    }
 4122}
 4123
 4124impl LspStore {
 4125    pub fn init(client: &AnyProtoClient) {
 4126        client.add_entity_request_handler(Self::handle_lsp_query);
 4127        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4128        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4129        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4130        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4131        client.add_entity_message_handler(Self::handle_start_language_server);
 4132        client.add_entity_message_handler(Self::handle_update_language_server);
 4133        client.add_entity_message_handler(Self::handle_language_server_log);
 4134        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4135        client.add_entity_request_handler(Self::handle_format_buffers);
 4136        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4137        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4138        client.add_entity_request_handler(Self::handle_apply_code_action);
 4139        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4140        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4141        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4142        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4143        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4144        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4145        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4146        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4147        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4148        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4149        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4150        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4151        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4156        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4157
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4162        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4163        client.add_entity_request_handler(
 4164            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4165        );
 4166        client.add_entity_request_handler(
 4167            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4168        );
 4169        client.add_entity_request_handler(
 4170            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4171        );
 4172    }
 4173
 4174    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4175        match &self.mode {
 4176            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4177            _ => None,
 4178        }
 4179    }
 4180
 4181    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4182        match &self.mode {
 4183            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4184            _ => None,
 4185        }
 4186    }
 4187
 4188    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4189        match &mut self.mode {
 4190            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4191            _ => None,
 4192        }
 4193    }
 4194
 4195    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4196        match &self.mode {
 4197            LspStoreMode::Remote(RemoteLspStore {
 4198                upstream_client: Some(upstream_client),
 4199                upstream_project_id,
 4200                ..
 4201            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4202
 4203            LspStoreMode::Remote(RemoteLspStore {
 4204                upstream_client: None,
 4205                ..
 4206            }) => None,
 4207            LspStoreMode::Local(_) => None,
 4208        }
 4209    }
 4210
 4211    pub fn new_local(
 4212        buffer_store: Entity<BufferStore>,
 4213        worktree_store: Entity<WorktreeStore>,
 4214        prettier_store: Entity<PrettierStore>,
 4215        toolchain_store: Entity<LocalToolchainStore>,
 4216        environment: Entity<ProjectEnvironment>,
 4217        manifest_tree: Entity<ManifestTree>,
 4218        languages: Arc<LanguageRegistry>,
 4219        http_client: Arc<dyn HttpClient>,
 4220        fs: Arc<dyn Fs>,
 4221        cx: &mut Context<Self>,
 4222    ) -> Self {
 4223        let yarn = YarnPathStore::new(fs.clone(), cx);
 4224        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4225            .detach();
 4226        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4227            .detach();
 4228        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4229            .detach();
 4230        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4231            .detach();
 4232        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4233            .detach();
 4234        subscribe_to_binary_statuses(&languages, cx).detach();
 4235
 4236        let _maintain_workspace_config = {
 4237            let (sender, receiver) = watch::channel();
 4238            (Self::maintain_workspace_config(receiver, cx), sender)
 4239        };
 4240
 4241        Self {
 4242            mode: LspStoreMode::Local(LocalLspStore {
 4243                weak: cx.weak_entity(),
 4244                worktree_store: worktree_store.clone(),
 4245
 4246                supplementary_language_servers: Default::default(),
 4247                languages: languages.clone(),
 4248                language_server_ids: Default::default(),
 4249                language_servers: Default::default(),
 4250                last_workspace_edits_by_language_server: Default::default(),
 4251                language_server_watched_paths: Default::default(),
 4252                language_server_paths_watched_for_rename: Default::default(),
 4253                language_server_dynamic_registrations: Default::default(),
 4254                buffers_being_formatted: Default::default(),
 4255                buffers_to_refresh_hash_set: HashSet::default(),
 4256                buffers_to_refresh_queue: VecDeque::new(),
 4257                _background_diagnostics_worker: Task::ready(()).shared(),
 4258                buffer_snapshots: Default::default(),
 4259                prettier_store,
 4260                environment,
 4261                http_client,
 4262                fs,
 4263                yarn,
 4264                next_diagnostic_group_id: Default::default(),
 4265                diagnostics: Default::default(),
 4266                _subscription: cx.on_app_quit(|this, _| {
 4267                    this.as_local_mut()
 4268                        .unwrap()
 4269                        .shutdown_language_servers_on_quit()
 4270                }),
 4271                lsp_tree: LanguageServerTree::new(
 4272                    manifest_tree,
 4273                    languages.clone(),
 4274                    toolchain_store.clone(),
 4275                ),
 4276                toolchain_store,
 4277                registered_buffers: HashMap::default(),
 4278                buffers_opened_in_servers: HashMap::default(),
 4279                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4280                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4281                restricted_worktrees_tasks: HashMap::default(),
 4282                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4283                    .manifest_file_names(),
 4284            }),
 4285            last_formatting_failure: None,
 4286            downstream_client: None,
 4287            buffer_store,
 4288            worktree_store,
 4289            languages: languages.clone(),
 4290            language_server_statuses: Default::default(),
 4291            nonce: StdRng::from_os_rng().random(),
 4292            diagnostic_summaries: HashMap::default(),
 4293            lsp_server_capabilities: HashMap::default(),
 4294            semantic_token_config: SemanticTokenConfig::new(cx),
 4295            lsp_data: HashMap::default(),
 4296            buffer_reload_tasks: HashMap::default(),
 4297            next_hint_id: Arc::default(),
 4298            active_entry: None,
 4299            _maintain_workspace_config,
 4300            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4301        }
 4302    }
 4303
 4304    fn send_lsp_proto_request<R: LspCommand>(
 4305        &self,
 4306        buffer: Entity<Buffer>,
 4307        client: AnyProtoClient,
 4308        upstream_project_id: u64,
 4309        request: R,
 4310        cx: &mut Context<LspStore>,
 4311    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4312        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4313            return Task::ready(Ok(R::Response::default()));
 4314        }
 4315        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4316        cx.spawn(async move |this, cx| {
 4317            let response = client.request(message).await?;
 4318            let this = this.upgrade().context("project dropped")?;
 4319            request
 4320                .response_from_proto(response, this, buffer, cx.clone())
 4321                .await
 4322        })
 4323    }
 4324
 4325    pub(super) fn new_remote(
 4326        buffer_store: Entity<BufferStore>,
 4327        worktree_store: Entity<WorktreeStore>,
 4328        languages: Arc<LanguageRegistry>,
 4329        upstream_client: AnyProtoClient,
 4330        project_id: u64,
 4331        cx: &mut Context<Self>,
 4332    ) -> Self {
 4333        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4334            .detach();
 4335        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4336            .detach();
 4337        subscribe_to_binary_statuses(&languages, cx).detach();
 4338        let _maintain_workspace_config = {
 4339            let (sender, receiver) = watch::channel();
 4340            (Self::maintain_workspace_config(receiver, cx), sender)
 4341        };
 4342        Self {
 4343            mode: LspStoreMode::Remote(RemoteLspStore {
 4344                upstream_client: Some(upstream_client),
 4345                upstream_project_id: project_id,
 4346            }),
 4347            downstream_client: None,
 4348            last_formatting_failure: None,
 4349            buffer_store,
 4350            worktree_store,
 4351            languages: languages.clone(),
 4352            language_server_statuses: Default::default(),
 4353            nonce: StdRng::from_os_rng().random(),
 4354            diagnostic_summaries: HashMap::default(),
 4355            lsp_server_capabilities: HashMap::default(),
 4356            semantic_token_config: SemanticTokenConfig::new(cx),
 4357            next_hint_id: Arc::default(),
 4358            lsp_data: HashMap::default(),
 4359            buffer_reload_tasks: HashMap::default(),
 4360            active_entry: None,
 4361
 4362            _maintain_workspace_config,
 4363            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4364        }
 4365    }
 4366
 4367    fn on_buffer_store_event(
 4368        &mut self,
 4369        _: Entity<BufferStore>,
 4370        event: &BufferStoreEvent,
 4371        cx: &mut Context<Self>,
 4372    ) {
 4373        match event {
 4374            BufferStoreEvent::BufferAdded(buffer) => {
 4375                self.on_buffer_added(buffer, cx).log_err();
 4376            }
 4377            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4378                let buffer_id = buffer.read(cx).remote_id();
 4379                if let Some(local) = self.as_local_mut()
 4380                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4381                {
 4382                    local.reset_buffer(buffer, old_file, cx);
 4383
 4384                    if local.registered_buffers.contains_key(&buffer_id) {
 4385                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4386                    }
 4387                }
 4388
 4389                self.detect_language_for_buffer(buffer, cx);
 4390                if let Some(local) = self.as_local_mut() {
 4391                    local.initialize_buffer(buffer, cx);
 4392                    if local.registered_buffers.contains_key(&buffer_id) {
 4393                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4394                    }
 4395                }
 4396            }
 4397            _ => {}
 4398        }
 4399    }
 4400
 4401    fn on_worktree_store_event(
 4402        &mut self,
 4403        _: Entity<WorktreeStore>,
 4404        event: &WorktreeStoreEvent,
 4405        cx: &mut Context<Self>,
 4406    ) {
 4407        match event {
 4408            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4409                if !worktree.read(cx).is_local() {
 4410                    return;
 4411                }
 4412                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4413                    worktree::Event::UpdatedEntries(changes) => {
 4414                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4415                    }
 4416                    worktree::Event::UpdatedGitRepositories(_)
 4417                    | worktree::Event::DeletedEntry(_)
 4418                    | worktree::Event::Deleted
 4419                    | worktree::Event::UpdatedRootRepoCommonDir => {}
 4420                })
 4421                .detach()
 4422            }
 4423            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4424            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4425                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4426            }
 4427            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4428                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4429            }
 4430            WorktreeStoreEvent::WorktreeReleased(..)
 4431            | WorktreeStoreEvent::WorktreeOrderChanged
 4432            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4433            | WorktreeStoreEvent::WorktreeDeletedEntry(..)
 4434            | WorktreeStoreEvent::WorktreeUpdatedRootRepoCommonDir(..) => {}
 4435        }
 4436    }
 4437
 4438    fn on_prettier_store_event(
 4439        &mut self,
 4440        _: Entity<PrettierStore>,
 4441        event: &PrettierStoreEvent,
 4442        cx: &mut Context<Self>,
 4443    ) {
 4444        match event {
 4445            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4446                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4447            }
 4448            PrettierStoreEvent::LanguageServerAdded {
 4449                new_server_id,
 4450                name,
 4451                prettier_server,
 4452            } => {
 4453                self.register_supplementary_language_server(
 4454                    *new_server_id,
 4455                    name.clone(),
 4456                    prettier_server.clone(),
 4457                    cx,
 4458                );
 4459            }
 4460        }
 4461    }
 4462
 4463    fn on_toolchain_store_event(
 4464        &mut self,
 4465        _: Entity<LocalToolchainStore>,
 4466        event: &ToolchainStoreEvent,
 4467        _: &mut Context<Self>,
 4468    ) {
 4469        if let ToolchainStoreEvent::ToolchainActivated = event {
 4470            self.request_workspace_config_refresh()
 4471        }
 4472    }
 4473
 4474    fn request_workspace_config_refresh(&mut self) {
 4475        *self._maintain_workspace_config.1.borrow_mut() = ();
 4476    }
 4477
 4478    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4479        self.as_local().map(|local| local.prettier_store.clone())
 4480    }
 4481
 4482    fn on_buffer_event(
 4483        &mut self,
 4484        buffer: Entity<Buffer>,
 4485        event: &language::BufferEvent,
 4486        cx: &mut Context<Self>,
 4487    ) {
 4488        match event {
 4489            language::BufferEvent::Edited { .. } => {
 4490                self.on_buffer_edited(buffer, cx);
 4491            }
 4492
 4493            language::BufferEvent::Saved => {
 4494                self.on_buffer_saved(buffer, cx);
 4495            }
 4496
 4497            language::BufferEvent::Reloaded => {
 4498                self.on_buffer_reloaded(buffer, cx);
 4499            }
 4500
 4501            _ => {}
 4502        }
 4503    }
 4504
 4505    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4506        buffer
 4507            .read(cx)
 4508            .set_language_registry(self.languages.clone());
 4509
 4510        cx.subscribe(buffer, |this, buffer, event, cx| {
 4511            this.on_buffer_event(buffer, event, cx);
 4512        })
 4513        .detach();
 4514
 4515        self.parse_modeline(buffer, cx);
 4516        self.detect_language_for_buffer(buffer, cx);
 4517        if let Some(local) = self.as_local_mut() {
 4518            local.initialize_buffer(buffer, cx);
 4519        }
 4520
 4521        Ok(())
 4522    }
 4523
 4524    pub fn refresh_background_diagnostics_for_buffers(
 4525        &mut self,
 4526        buffers: HashSet<BufferId>,
 4527        cx: &mut Context<Self>,
 4528    ) -> Shared<Task<()>> {
 4529        let Some(local) = self.as_local_mut() else {
 4530            return Task::ready(()).shared();
 4531        };
 4532        for buffer in buffers {
 4533            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4534                local.buffers_to_refresh_queue.push_back(buffer);
 4535                if local.buffers_to_refresh_queue.len() == 1 {
 4536                    local._background_diagnostics_worker =
 4537                        Self::background_diagnostics_worker(cx).shared();
 4538                }
 4539            }
 4540        }
 4541
 4542        local._background_diagnostics_worker.clone()
 4543    }
 4544
 4545    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4546        let buffer_store = self.buffer_store.clone();
 4547        let local = self.as_local_mut()?;
 4548        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4549            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4550            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4551                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4552            }
 4553        }
 4554        None
 4555    }
 4556
 4557    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4558        cx.spawn(async move |this, cx| {
 4559            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4560                task.await.log_err();
 4561            }
 4562        })
 4563    }
 4564
 4565    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4566        if self.parse_modeline(&buffer, cx) {
 4567            self.detect_language_for_buffer(&buffer, cx);
 4568        }
 4569
 4570        let buffer_id = buffer.read(cx).remote_id();
 4571        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4572        self.buffer_reload_tasks.insert(buffer_id, task);
 4573    }
 4574
 4575    pub(crate) fn register_buffer_with_language_servers(
 4576        &mut self,
 4577        buffer: &Entity<Buffer>,
 4578        only_register_servers: HashSet<LanguageServerSelector>,
 4579        ignore_refcounts: bool,
 4580        cx: &mut Context<Self>,
 4581    ) -> OpenLspBufferHandle {
 4582        let buffer_id = buffer.read(cx).remote_id();
 4583        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4584        if let Some(local) = self.as_local_mut() {
 4585            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4586            if !ignore_refcounts {
 4587                *refcount += 1;
 4588            }
 4589
 4590            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4591            // 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
 4592            // 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
 4593            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4594            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4595                return handle;
 4596            };
 4597            if !file.is_local() {
 4598                return handle;
 4599            }
 4600
 4601            if ignore_refcounts || *refcount == 1 {
 4602                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4603            }
 4604            if !ignore_refcounts {
 4605                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4606                    let refcount = {
 4607                        let local = lsp_store.as_local_mut().unwrap();
 4608                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4609                            debug_panic!("bad refcounting");
 4610                            return;
 4611                        };
 4612
 4613                        *refcount -= 1;
 4614                        *refcount
 4615                    };
 4616                    if refcount == 0 {
 4617                        lsp_store.lsp_data.remove(&buffer_id);
 4618                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4619                        let local = lsp_store.as_local_mut().unwrap();
 4620                        local.registered_buffers.remove(&buffer_id);
 4621
 4622                        local.buffers_opened_in_servers.remove(&buffer_id);
 4623                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4624                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4625
 4626                            let buffer_abs_path = file.abs_path(cx);
 4627                            for (_, buffer_pull_diagnostics_result_ids) in
 4628                                &mut local.buffer_pull_diagnostics_result_ids
 4629                            {
 4630                                buffer_pull_diagnostics_result_ids.retain(
 4631                                    |_, buffer_result_ids| {
 4632                                        buffer_result_ids.remove(&buffer_abs_path);
 4633                                        !buffer_result_ids.is_empty()
 4634                                    },
 4635                                );
 4636                            }
 4637
 4638                            let diagnostic_updates = local
 4639                                .language_servers
 4640                                .keys()
 4641                                .cloned()
 4642                                .map(|server_id| DocumentDiagnosticsUpdate {
 4643                                    diagnostics: DocumentDiagnostics {
 4644                                        document_abs_path: buffer_abs_path.clone(),
 4645                                        version: None,
 4646                                        diagnostics: Vec::new(),
 4647                                    },
 4648                                    result_id: None,
 4649                                    registration_id: None,
 4650                                    server_id,
 4651                                    disk_based_sources: Cow::Borrowed(&[]),
 4652                                })
 4653                                .collect::<Vec<_>>();
 4654
 4655                            lsp_store
 4656                                .merge_diagnostic_entries(
 4657                                    diagnostic_updates,
 4658                                    |_, diagnostic, _| {
 4659                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4660                                    },
 4661                                    cx,
 4662                                )
 4663                                .context("Clearing diagnostics for the closed buffer")
 4664                                .log_err();
 4665                        }
 4666                    }
 4667                })
 4668                .detach();
 4669            }
 4670        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4671            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4672            cx.background_spawn(async move {
 4673                upstream_client
 4674                    .request(proto::RegisterBufferWithLanguageServers {
 4675                        project_id: upstream_project_id,
 4676                        buffer_id,
 4677                        only_servers: only_register_servers
 4678                            .into_iter()
 4679                            .map(|selector| {
 4680                                let selector = match selector {
 4681                                    LanguageServerSelector::Id(language_server_id) => {
 4682                                        proto::language_server_selector::Selector::ServerId(
 4683                                            language_server_id.to_proto(),
 4684                                        )
 4685                                    }
 4686                                    LanguageServerSelector::Name(language_server_name) => {
 4687                                        proto::language_server_selector::Selector::Name(
 4688                                            language_server_name.to_string(),
 4689                                        )
 4690                                    }
 4691                                };
 4692                                proto::LanguageServerSelector {
 4693                                    selector: Some(selector),
 4694                                }
 4695                            })
 4696                            .collect(),
 4697                    })
 4698                    .await
 4699            })
 4700            .detach();
 4701        } else {
 4702            // Our remote connection got closed
 4703        }
 4704        handle
 4705    }
 4706
 4707    fn maintain_buffer_languages(
 4708        languages: Arc<LanguageRegistry>,
 4709        cx: &mut Context<Self>,
 4710    ) -> Task<()> {
 4711        let mut subscription = languages.subscribe();
 4712        let mut prev_reload_count = languages.reload_count();
 4713        cx.spawn(async move |this, cx| {
 4714            while let Some(()) = subscription.next().await {
 4715                if let Some(this) = this.upgrade() {
 4716                    // If the language registry has been reloaded, then remove and
 4717                    // re-assign the languages on all open buffers.
 4718                    let reload_count = languages.reload_count();
 4719                    if reload_count > prev_reload_count {
 4720                        prev_reload_count = reload_count;
 4721                        this.update(cx, |this, cx| {
 4722                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4723                                for buffer in buffer_store.buffers() {
 4724                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4725                                    {
 4726                                        buffer.update(cx, |buffer, cx| {
 4727                                            buffer.set_language_async(None, cx)
 4728                                        });
 4729                                        if let Some(local) = this.as_local_mut() {
 4730                                            local.reset_buffer(&buffer, &f, cx);
 4731
 4732                                            if local
 4733                                                .registered_buffers
 4734                                                .contains_key(&buffer.read(cx).remote_id())
 4735                                                && let Some(file_url) =
 4736                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4737                                            {
 4738                                                local.unregister_buffer_from_language_servers(
 4739                                                    &buffer, &file_url, cx,
 4740                                                );
 4741                                            }
 4742                                        }
 4743                                    }
 4744                                }
 4745                            });
 4746                        });
 4747                    }
 4748
 4749                    this.update(cx, |this, cx| {
 4750                        let mut plain_text_buffers = Vec::new();
 4751                        let mut buffers_with_unknown_injections = Vec::new();
 4752                        for handle in this.buffer_store.read(cx).buffers() {
 4753                            let buffer = handle.read(cx);
 4754                            if buffer.language().is_none()
 4755                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4756                            {
 4757                                plain_text_buffers.push(handle);
 4758                            } else if buffer.contains_unknown_injections() {
 4759                                buffers_with_unknown_injections.push(handle);
 4760                            }
 4761                        }
 4762
 4763                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4764                        // and reused later in the invisible worktrees.
 4765                        plain_text_buffers.sort_by_key(|buffer| {
 4766                            Reverse(
 4767                                File::from_dyn(buffer.read(cx).file())
 4768                                    .map(|file| file.worktree.read(cx).is_visible()),
 4769                            )
 4770                        });
 4771
 4772                        for buffer in plain_text_buffers {
 4773                            this.detect_language_for_buffer(&buffer, cx);
 4774                            if let Some(local) = this.as_local_mut() {
 4775                                local.initialize_buffer(&buffer, cx);
 4776                                if local
 4777                                    .registered_buffers
 4778                                    .contains_key(&buffer.read(cx).remote_id())
 4779                                {
 4780                                    local.register_buffer_with_language_servers(
 4781                                        &buffer,
 4782                                        HashSet::default(),
 4783                                        cx,
 4784                                    );
 4785                                }
 4786                            }
 4787                        }
 4788
 4789                        for buffer in buffers_with_unknown_injections {
 4790                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4791                        }
 4792                    });
 4793                }
 4794            }
 4795        })
 4796    }
 4797
 4798    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4799        let buffer = buffer_handle.read(cx);
 4800        let content = buffer.as_rope();
 4801
 4802        let modeline_settings = {
 4803            let settings_store = cx.global::<SettingsStore>();
 4804            let modeline_lines = settings_store
 4805                .raw_user_settings()
 4806                .and_then(|s| s.content.modeline_lines)
 4807                .or(settings_store.raw_default_settings().modeline_lines)
 4808                .unwrap_or(5);
 4809
 4810            const MAX_MODELINE_BYTES: usize = 1024;
 4811
 4812            let first_bytes =
 4813                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4814            let mut first_lines = Vec::new();
 4815            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4816            for _ in 0..modeline_lines {
 4817                if let Some(line) = lines.next() {
 4818                    first_lines.push(line.to_string());
 4819                } else {
 4820                    break;
 4821                }
 4822            }
 4823            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4824
 4825            let last_start =
 4826                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4827            let mut last_lines = Vec::new();
 4828            let mut lines = content
 4829                .reversed_chunks_in_range(last_start..content.len())
 4830                .lines();
 4831            for _ in 0..modeline_lines {
 4832                if let Some(line) = lines.next() {
 4833                    last_lines.push(line.to_string());
 4834                } else {
 4835                    break;
 4836                }
 4837            }
 4838            let last_lines_ref: Vec<_> =
 4839                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4840            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4841        };
 4842
 4843        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4844
 4845        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4846    }
 4847
 4848    fn detect_language_for_buffer(
 4849        &mut self,
 4850        buffer_handle: &Entity<Buffer>,
 4851        cx: &mut Context<Self>,
 4852    ) -> Option<language::AvailableLanguage> {
 4853        // If the buffer has a language, set it and start the language server if we haven't already.
 4854        let buffer = buffer_handle.read(cx);
 4855        let file = buffer.file()?;
 4856        let content = buffer.as_rope();
 4857        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4858
 4859        let available_language = if let Some(ModelineSettings {
 4860            mode: Some(mode_name),
 4861            ..
 4862        }) = modeline_settings
 4863        {
 4864            self.languages
 4865                .available_language_for_modeline_name(mode_name)
 4866        } else {
 4867            self.languages.language_for_file(file, Some(content), cx)
 4868        };
 4869        if let Some(available_language) = &available_language {
 4870            if let Some(Ok(Ok(new_language))) = self
 4871                .languages
 4872                .load_language(available_language)
 4873                .now_or_never()
 4874            {
 4875                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4876            }
 4877        } else {
 4878            cx.emit(LspStoreEvent::LanguageDetected {
 4879                buffer: buffer_handle.clone(),
 4880                new_language: None,
 4881            });
 4882        }
 4883
 4884        available_language
 4885    }
 4886
 4887    pub(crate) fn set_language_for_buffer(
 4888        &mut self,
 4889        buffer_entity: &Entity<Buffer>,
 4890        new_language: Arc<Language>,
 4891        cx: &mut Context<Self>,
 4892    ) {
 4893        let buffer = buffer_entity.read(cx);
 4894        let buffer_file = buffer.file().cloned();
 4895        let buffer_id = buffer.remote_id();
 4896        if let Some(local_store) = self.as_local_mut()
 4897            && local_store.registered_buffers.contains_key(&buffer_id)
 4898            && let Some(abs_path) =
 4899                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4900            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4901        {
 4902            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4903        }
 4904        buffer_entity.update(cx, |buffer, cx| {
 4905            if buffer
 4906                .language()
 4907                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4908            {
 4909                buffer.set_language_async(Some(new_language.clone()), cx);
 4910            }
 4911        });
 4912
 4913        let settings = LanguageSettings::resolve(
 4914            Some(&buffer_entity.read(cx)),
 4915            Some(&new_language.name()),
 4916            cx,
 4917        )
 4918        .into_owned();
 4919        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4920
 4921        let worktree_id = if let Some(file) = buffer_file {
 4922            let worktree = file.worktree.clone();
 4923
 4924            if let Some(local) = self.as_local_mut()
 4925                && local.registered_buffers.contains_key(&buffer_id)
 4926            {
 4927                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4928            }
 4929            Some(worktree.read(cx).id())
 4930        } else {
 4931            None
 4932        };
 4933
 4934        if settings.prettier.allowed
 4935            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4936        {
 4937            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4938            if let Some(prettier_store) = prettier_store {
 4939                prettier_store.update(cx, |prettier_store, cx| {
 4940                    prettier_store.install_default_prettier(
 4941                        worktree_id,
 4942                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4943                        cx,
 4944                    )
 4945                })
 4946            }
 4947        }
 4948
 4949        cx.emit(LspStoreEvent::LanguageDetected {
 4950            buffer: buffer_entity.clone(),
 4951            new_language: Some(new_language),
 4952        })
 4953    }
 4954
 4955    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4956        self.buffer_store.clone()
 4957    }
 4958
 4959    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4960        self.active_entry = active_entry;
 4961    }
 4962
 4963    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4964        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4965            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4966        {
 4967            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4968                summaries
 4969                    .iter()
 4970                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4971            });
 4972            if let Some(summary) = summaries.next() {
 4973                client
 4974                    .send(proto::UpdateDiagnosticSummary {
 4975                        project_id: downstream_project_id,
 4976                        worktree_id: worktree.id().to_proto(),
 4977                        summary: Some(summary),
 4978                        more_summaries: summaries.collect(),
 4979                    })
 4980                    .log_err();
 4981            }
 4982        }
 4983    }
 4984
 4985    fn is_capable_for_proto_request<R>(
 4986        &self,
 4987        buffer: &Entity<Buffer>,
 4988        request: &R,
 4989        cx: &App,
 4990    ) -> bool
 4991    where
 4992        R: LspCommand,
 4993    {
 4994        self.check_if_capable_for_proto_request(
 4995            buffer,
 4996            |capabilities| {
 4997                request.check_capabilities(AdapterServerCapabilities {
 4998                    server_capabilities: capabilities.clone(),
 4999                    code_action_kinds: None,
 5000                })
 5001            },
 5002            cx,
 5003        )
 5004    }
 5005
 5006    fn check_if_capable_for_proto_request<F>(
 5007        &self,
 5008        buffer: &Entity<Buffer>,
 5009        check: F,
 5010        cx: &App,
 5011    ) -> bool
 5012    where
 5013        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5014    {
 5015        let Some(language) = buffer.read(cx).language().cloned() else {
 5016            return false;
 5017        };
 5018        let registered_language_servers = self
 5019            .languages
 5020            .lsp_adapters(&language.name())
 5021            .into_iter()
 5022            .map(|lsp_adapter| lsp_adapter.name())
 5023            .collect::<HashSet<_>>();
 5024        self.language_server_statuses
 5025            .iter()
 5026            .filter_map(|(server_id, server_status)| {
 5027                // Include servers that are either registered for this language OR
 5028                // available to be loaded (for SSH remote mode where adapters like
 5029                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5030                // but only loaded on the server side)
 5031                let is_relevant = registered_language_servers.contains(&server_status.name)
 5032                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5033                is_relevant.then_some(server_id)
 5034            })
 5035            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5036            .any(check)
 5037    }
 5038
 5039    fn all_capable_for_proto_request<F>(
 5040        &self,
 5041        buffer: &Entity<Buffer>,
 5042        mut check: F,
 5043        cx: &App,
 5044    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5045    where
 5046        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5047    {
 5048        let Some(language) = buffer.read(cx).language().cloned() else {
 5049            return Vec::default();
 5050        };
 5051        let registered_language_servers = self
 5052            .languages
 5053            .lsp_adapters(&language.name())
 5054            .into_iter()
 5055            .map(|lsp_adapter| lsp_adapter.name())
 5056            .collect::<HashSet<_>>();
 5057        self.language_server_statuses
 5058            .iter()
 5059            .filter_map(|(server_id, server_status)| {
 5060                // Include servers that are either registered for this language OR
 5061                // available to be loaded (for SSH remote mode where adapters like
 5062                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5063                // but only loaded on the server side)
 5064                let is_relevant = registered_language_servers.contains(&server_status.name)
 5065                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5066                is_relevant.then_some((server_id, &server_status.name))
 5067            })
 5068            .filter_map(|(server_id, server_name)| {
 5069                self.lsp_server_capabilities
 5070                    .get(server_id)
 5071                    .map(|c| (server_id, server_name, c))
 5072            })
 5073            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5074            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5075            .collect()
 5076    }
 5077
 5078    pub fn request_lsp<R>(
 5079        &mut self,
 5080        buffer: Entity<Buffer>,
 5081        server: LanguageServerToQuery,
 5082        request: R,
 5083        cx: &mut Context<Self>,
 5084    ) -> Task<Result<R::Response>>
 5085    where
 5086        R: LspCommand,
 5087        <R::LspRequest as lsp::request::Request>::Result: Send,
 5088        <R::LspRequest as lsp::request::Request>::Params: Send,
 5089    {
 5090        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5091            return self.send_lsp_proto_request(
 5092                buffer,
 5093                upstream_client,
 5094                upstream_project_id,
 5095                request,
 5096                cx,
 5097            );
 5098        }
 5099
 5100        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5101            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5102                local
 5103                    .language_servers_for_buffer(buffer, cx)
 5104                    .find(|(_, server)| {
 5105                        request.check_capabilities(server.adapter_server_capabilities())
 5106                    })
 5107                    .map(|(_, server)| server.clone())
 5108            }),
 5109            LanguageServerToQuery::Other(id) => self
 5110                .language_server_for_local_buffer(buffer, id, cx)
 5111                .and_then(|(_, server)| {
 5112                    request
 5113                        .check_capabilities(server.adapter_server_capabilities())
 5114                        .then(|| Arc::clone(server))
 5115                }),
 5116        }) else {
 5117            return Task::ready(Ok(Default::default()));
 5118        };
 5119
 5120        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5121
 5122        let Some(file) = file else {
 5123            return Task::ready(Ok(Default::default()));
 5124        };
 5125
 5126        let lsp_params = match request.to_lsp_params_or_response(
 5127            &file.abs_path(cx),
 5128            buffer.read(cx),
 5129            &language_server,
 5130            cx,
 5131        ) {
 5132            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5133            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5134            Err(err) => {
 5135                let message = format!(
 5136                    "{} via {} failed: {}",
 5137                    request.display_name(),
 5138                    language_server.name(),
 5139                    err
 5140                );
 5141                // rust-analyzer likes to error with this when its still loading up
 5142                if !message.ends_with("content modified") {
 5143                    log::warn!("{message}");
 5144                }
 5145                return Task::ready(Err(anyhow!(message)));
 5146            }
 5147        };
 5148
 5149        let status = request.status();
 5150        let request_timeout = ProjectSettings::get_global(cx)
 5151            .global_lsp_settings
 5152            .get_request_timeout();
 5153
 5154        cx.spawn(async move |this, cx| {
 5155            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5156
 5157            let id = lsp_request.id();
 5158            let _cleanup = if status.is_some() {
 5159                cx.update(|cx| {
 5160                    this.update(cx, |this, cx| {
 5161                        this.on_lsp_work_start(
 5162                            language_server.server_id(),
 5163                            ProgressToken::Number(id),
 5164                            LanguageServerProgress {
 5165                                is_disk_based_diagnostics_progress: false,
 5166                                is_cancellable: false,
 5167                                title: None,
 5168                                message: status.clone(),
 5169                                percentage: None,
 5170                                last_update_at: cx.background_executor().now(),
 5171                            },
 5172                            cx,
 5173                        );
 5174                    })
 5175                })
 5176                .log_err();
 5177
 5178                Some(defer(|| {
 5179                    cx.update(|cx| {
 5180                        this.update(cx, |this, cx| {
 5181                            this.on_lsp_work_end(
 5182                                language_server.server_id(),
 5183                                ProgressToken::Number(id),
 5184                                cx,
 5185                            );
 5186                        })
 5187                    })
 5188                    .log_err();
 5189                }))
 5190            } else {
 5191                None
 5192            };
 5193
 5194            let result = lsp_request.await.into_response();
 5195
 5196            let response = result.map_err(|err| {
 5197                let message = format!(
 5198                    "{} via {} failed: {}",
 5199                    request.display_name(),
 5200                    language_server.name(),
 5201                    err
 5202                );
 5203                // rust-analyzer likes to error with this when its still loading up
 5204                if !message.ends_with("content modified") {
 5205                    log::warn!("{message}");
 5206                }
 5207                anyhow::anyhow!(message)
 5208            })?;
 5209
 5210            request
 5211                .response_from_lsp(
 5212                    response,
 5213                    this.upgrade().context("no app context")?,
 5214                    buffer,
 5215                    language_server.server_id(),
 5216                    cx.clone(),
 5217                )
 5218                .await
 5219        })
 5220    }
 5221
 5222    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5223        let mut language_formatters_to_check = Vec::new();
 5224        for buffer in self.buffer_store.read(cx).buffers() {
 5225            let buffer = buffer.read(cx);
 5226            let settings = LanguageSettings::for_buffer(buffer, cx);
 5227            if buffer.language().is_some() {
 5228                let buffer_file = File::from_dyn(buffer.file());
 5229                language_formatters_to_check.push((
 5230                    buffer_file.map(|f| f.worktree_id(cx)),
 5231                    settings.into_owned(),
 5232                ));
 5233            }
 5234        }
 5235
 5236        self.request_workspace_config_refresh();
 5237
 5238        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5239            prettier_store.update(cx, |prettier_store, cx| {
 5240                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5241            })
 5242        }
 5243
 5244        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5245            .global_lsp_settings
 5246            .semantic_token_rules
 5247            .clone();
 5248        self.semantic_token_config
 5249            .update_rules(new_semantic_token_rules);
 5250        // Always clear cached stylizers so that changes to language-specific
 5251        // semantic token rules (e.g. from extension install/uninstall) are
 5252        // picked up. Stylizers are recreated lazily, so this is cheap.
 5253        self.semantic_token_config.clear_stylizers();
 5254
 5255        let new_global_semantic_tokens_mode =
 5256            all_language_settings(None, cx).defaults.semantic_tokens;
 5257        if self
 5258            .semantic_token_config
 5259            .update_global_mode(new_global_semantic_tokens_mode)
 5260        {
 5261            self.restart_all_language_servers(cx);
 5262        }
 5263
 5264        cx.notify();
 5265    }
 5266
 5267    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5268        let buffer_store = self.buffer_store.clone();
 5269        let Some(local) = self.as_local_mut() else {
 5270            return;
 5271        };
 5272        let mut adapters = BTreeMap::default();
 5273        let get_adapter = {
 5274            let languages = local.languages.clone();
 5275            let environment = local.environment.clone();
 5276            let weak = local.weak.clone();
 5277            let worktree_store = local.worktree_store.clone();
 5278            let http_client = local.http_client.clone();
 5279            let fs = local.fs.clone();
 5280            move |worktree_id, cx: &mut App| {
 5281                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5282                Some(LocalLspAdapterDelegate::new(
 5283                    languages.clone(),
 5284                    &environment,
 5285                    weak.clone(),
 5286                    &worktree,
 5287                    http_client.clone(),
 5288                    fs.clone(),
 5289                    cx,
 5290                ))
 5291            }
 5292        };
 5293
 5294        let mut messages_to_report = Vec::new();
 5295        let (new_tree, to_stop) = {
 5296            let mut rebase = local.lsp_tree.rebase();
 5297            let buffers = buffer_store
 5298                .read(cx)
 5299                .buffers()
 5300                .filter_map(|buffer| {
 5301                    let raw_buffer = buffer.read(cx);
 5302                    if !local
 5303                        .registered_buffers
 5304                        .contains_key(&raw_buffer.remote_id())
 5305                    {
 5306                        return None;
 5307                    }
 5308                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5309                    let language = raw_buffer.language().cloned()?;
 5310                    Some((file, language, raw_buffer.remote_id()))
 5311                })
 5312                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5313            for (file, language, buffer_id) in buffers {
 5314                let worktree_id = file.worktree_id(cx);
 5315                let Some(worktree) = local
 5316                    .worktree_store
 5317                    .read(cx)
 5318                    .worktree_for_id(worktree_id, cx)
 5319                else {
 5320                    continue;
 5321                };
 5322
 5323                if let Some((_, apply)) = local.reuse_existing_language_server(
 5324                    rebase.server_tree(),
 5325                    &worktree,
 5326                    &language.name(),
 5327                    cx,
 5328                ) {
 5329                    (apply)(rebase.server_tree());
 5330                } else if let Some(lsp_delegate) = adapters
 5331                    .entry(worktree_id)
 5332                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5333                    .clone()
 5334                {
 5335                    let delegate =
 5336                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5337                    let path = file
 5338                        .path()
 5339                        .parent()
 5340                        .map(Arc::from)
 5341                        .unwrap_or_else(|| file.path().clone());
 5342                    let worktree_path = ProjectPath { worktree_id, path };
 5343                    let abs_path = file.abs_path(cx);
 5344                    let nodes = rebase
 5345                        .walk(
 5346                            worktree_path,
 5347                            language.name(),
 5348                            language.manifest(),
 5349                            delegate.clone(),
 5350                            cx,
 5351                        )
 5352                        .collect::<Vec<_>>();
 5353                    for node in nodes {
 5354                        let server_id = node.server_id_or_init(|disposition| {
 5355                            let path = &disposition.path;
 5356                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5357                            let key = LanguageServerSeed {
 5358                                worktree_id,
 5359                                name: disposition.server_name.clone(),
 5360                                settings: LanguageServerSeedSettings {
 5361                                    binary: disposition.settings.binary.clone(),
 5362                                    initialization_options: disposition
 5363                                        .settings
 5364                                        .initialization_options
 5365                                        .clone(),
 5366                                },
 5367                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5368                                    path.worktree_id,
 5369                                    &path.path,
 5370                                    language.name(),
 5371                                ),
 5372                            };
 5373                            local.language_server_ids.remove(&key);
 5374
 5375                            let server_id = local.get_or_insert_language_server(
 5376                                &worktree,
 5377                                lsp_delegate.clone(),
 5378                                disposition,
 5379                                &language.name(),
 5380                                cx,
 5381                            );
 5382                            if let Some(state) = local.language_servers.get(&server_id)
 5383                                && let Ok(uri) = uri
 5384                            {
 5385                                state.add_workspace_folder(uri);
 5386                            };
 5387                            server_id
 5388                        });
 5389
 5390                        if let Some(language_server_id) = server_id {
 5391                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5392                                language_server_id,
 5393                                name: node.name(),
 5394                                message:
 5395                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5396                                        proto::RegisteredForBuffer {
 5397                                            buffer_abs_path: abs_path
 5398                                                .to_string_lossy()
 5399                                                .into_owned(),
 5400                                            buffer_id: buffer_id.to_proto(),
 5401                                        },
 5402                                    ),
 5403                            });
 5404                        }
 5405                    }
 5406                } else {
 5407                    continue;
 5408                }
 5409            }
 5410            rebase.finish()
 5411        };
 5412        for message in messages_to_report {
 5413            cx.emit(message);
 5414        }
 5415        local.lsp_tree = new_tree;
 5416        for (id, _) in to_stop {
 5417            self.stop_local_language_server(id, cx).detach();
 5418        }
 5419    }
 5420
 5421    pub fn apply_code_action(
 5422        &self,
 5423        buffer_handle: Entity<Buffer>,
 5424        mut action: CodeAction,
 5425        push_to_history: bool,
 5426        cx: &mut Context<Self>,
 5427    ) -> Task<Result<ProjectTransaction>> {
 5428        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5429            let request = proto::ApplyCodeAction {
 5430                project_id,
 5431                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5432                action: Some(Self::serialize_code_action(&action)),
 5433            };
 5434            let buffer_store = self.buffer_store();
 5435            cx.spawn(async move |_, cx| {
 5436                let response = upstream_client
 5437                    .request(request)
 5438                    .await?
 5439                    .transaction
 5440                    .context("missing transaction")?;
 5441
 5442                buffer_store
 5443                    .update(cx, |buffer_store, cx| {
 5444                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5445                    })
 5446                    .await
 5447            })
 5448        } else if self.mode.is_local() {
 5449            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5450                let request_timeout = ProjectSettings::get_global(cx)
 5451                    .global_lsp_settings
 5452                    .get_request_timeout();
 5453                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5454                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5455            }) else {
 5456                return Task::ready(Ok(ProjectTransaction::default()));
 5457            };
 5458
 5459            cx.spawn(async move |this, cx| {
 5460                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5461                    .await
 5462                    .context("resolving a code action")?;
 5463                if let Some(edit) = action.lsp_action.edit()
 5464                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5465                        return LocalLspStore::deserialize_workspace_edit(
 5466                            this.upgrade().context("no app present")?,
 5467                            edit.clone(),
 5468                            push_to_history,
 5469
 5470                            lang_server.clone(),
 5471                            cx,
 5472                        )
 5473                        .await;
 5474                    }
 5475
 5476                let Some(command) = action.lsp_action.command() else {
 5477                    return Ok(ProjectTransaction::default())
 5478                };
 5479
 5480                let server_capabilities = lang_server.capabilities();
 5481                let available_commands = server_capabilities
 5482                    .execute_command_provider
 5483                    .as_ref()
 5484                    .map(|options| options.commands.as_slice())
 5485                    .unwrap_or_default();
 5486
 5487                if !available_commands.contains(&command.command) {
 5488                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5489                    return Ok(ProjectTransaction::default())
 5490                }
 5491
 5492                let request_timeout = cx.update(|app|
 5493                    ProjectSettings::get_global(app)
 5494                    .global_lsp_settings
 5495                    .get_request_timeout()
 5496                );
 5497
 5498                this.update(cx, |this, _| {
 5499                    this.as_local_mut()
 5500                        .unwrap()
 5501                        .last_workspace_edits_by_language_server
 5502                        .remove(&lang_server.server_id());
 5503                })?;
 5504
 5505                let _result = lang_server
 5506                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5507                        command: command.command.clone(),
 5508                        arguments: command.arguments.clone().unwrap_or_default(),
 5509                        ..lsp::ExecuteCommandParams::default()
 5510                    }, request_timeout)
 5511                    .await.into_response()
 5512                    .context("execute command")?;
 5513
 5514                return this.update(cx, |this, _| {
 5515                    this.as_local_mut()
 5516                        .unwrap()
 5517                        .last_workspace_edits_by_language_server
 5518                        .remove(&lang_server.server_id())
 5519                        .unwrap_or_default()
 5520                });
 5521            })
 5522        } else {
 5523            Task::ready(Err(anyhow!("no upstream client and not local")))
 5524        }
 5525    }
 5526
 5527    pub fn apply_code_action_kind(
 5528        &mut self,
 5529        buffers: HashSet<Entity<Buffer>>,
 5530        kind: CodeActionKind,
 5531        push_to_history: bool,
 5532        cx: &mut Context<Self>,
 5533    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5534        if self.as_local().is_some() {
 5535            cx.spawn(async move |lsp_store, cx| {
 5536                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5537                let result = LocalLspStore::execute_code_action_kind_locally(
 5538                    lsp_store.clone(),
 5539                    buffers,
 5540                    kind,
 5541                    push_to_history,
 5542                    cx,
 5543                )
 5544                .await;
 5545                lsp_store.update(cx, |lsp_store, _| {
 5546                    lsp_store.update_last_formatting_failure(&result);
 5547                })?;
 5548                result
 5549            })
 5550        } else if let Some((client, project_id)) = self.upstream_client() {
 5551            let buffer_store = self.buffer_store();
 5552            cx.spawn(async move |lsp_store, cx| {
 5553                let result = client
 5554                    .request(proto::ApplyCodeActionKind {
 5555                        project_id,
 5556                        kind: kind.as_str().to_owned(),
 5557                        buffer_ids: buffers
 5558                            .iter()
 5559                            .map(|buffer| {
 5560                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5561                            })
 5562                            .collect(),
 5563                    })
 5564                    .await
 5565                    .and_then(|result| result.transaction.context("missing transaction"));
 5566                lsp_store.update(cx, |lsp_store, _| {
 5567                    lsp_store.update_last_formatting_failure(&result);
 5568                })?;
 5569
 5570                let transaction_response = result?;
 5571                buffer_store
 5572                    .update(cx, |buffer_store, cx| {
 5573                        buffer_store.deserialize_project_transaction(
 5574                            transaction_response,
 5575                            push_to_history,
 5576                            cx,
 5577                        )
 5578                    })
 5579                    .await
 5580            })
 5581        } else {
 5582            Task::ready(Ok(ProjectTransaction::default()))
 5583        }
 5584    }
 5585
 5586    pub fn resolved_hint(
 5587        &mut self,
 5588        buffer_id: BufferId,
 5589        id: InlayId,
 5590        cx: &mut Context<Self>,
 5591    ) -> Option<ResolvedHint> {
 5592        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5593
 5594        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5595        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5596        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5597        let (server_id, resolve_data) = match &hint.resolve_state {
 5598            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5599            ResolveState::Resolving => {
 5600                return Some(ResolvedHint::Resolving(
 5601                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5602                ));
 5603            }
 5604            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5605        };
 5606
 5607        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5608        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5609        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5610            id,
 5611            cx.spawn(async move |lsp_store, cx| {
 5612                let resolved_hint = resolve_task.await;
 5613                lsp_store
 5614                    .update(cx, |lsp_store, _| {
 5615                        if let Some(old_inlay_hint) = lsp_store
 5616                            .lsp_data
 5617                            .get_mut(&buffer_id)
 5618                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5619                        {
 5620                            match resolved_hint {
 5621                                Ok(resolved_hint) => {
 5622                                    *old_inlay_hint = resolved_hint;
 5623                                }
 5624                                Err(e) => {
 5625                                    old_inlay_hint.resolve_state =
 5626                                        ResolveState::CanResolve(server_id, resolve_data);
 5627                                    log::error!("Inlay hint resolve failed: {e:#}");
 5628                                }
 5629                            }
 5630                        }
 5631                    })
 5632                    .ok();
 5633            })
 5634            .shared(),
 5635        );
 5636        debug_assert!(
 5637            previous_task.is_none(),
 5638            "Did not change hint's resolve state after spawning its resolve"
 5639        );
 5640        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5641        None
 5642    }
 5643
 5644    pub(crate) fn linked_edits(
 5645        &mut self,
 5646        buffer: &Entity<Buffer>,
 5647        position: Anchor,
 5648        cx: &mut Context<Self>,
 5649    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5650        let snapshot = buffer.read(cx).snapshot();
 5651        let scope = snapshot.language_scope_at(position);
 5652        let Some(server_id) = self
 5653            .as_local()
 5654            .and_then(|local| {
 5655                buffer.update(cx, |buffer, cx| {
 5656                    local
 5657                        .language_servers_for_buffer(buffer, cx)
 5658                        .filter(|(_, server)| {
 5659                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5660                        })
 5661                        .filter(|(adapter, _)| {
 5662                            scope
 5663                                .as_ref()
 5664                                .map(|scope| scope.language_allowed(&adapter.name))
 5665                                .unwrap_or(true)
 5666                        })
 5667                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5668                        .next()
 5669                })
 5670            })
 5671            .or_else(|| {
 5672                self.upstream_client()
 5673                    .is_some()
 5674                    .then_some(LanguageServerToQuery::FirstCapable)
 5675            })
 5676            .filter(|_| {
 5677                maybe!({
 5678                    buffer.read(cx).language_at(position)?;
 5679                    Some(
 5680                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5681                            .linked_edits,
 5682                    )
 5683                }) == Some(true)
 5684            })
 5685        else {
 5686            return Task::ready(Ok(Vec::new()));
 5687        };
 5688
 5689        self.request_lsp(
 5690            buffer.clone(),
 5691            server_id,
 5692            LinkedEditingRange { position },
 5693            cx,
 5694        )
 5695    }
 5696
 5697    fn apply_on_type_formatting(
 5698        &mut self,
 5699        buffer: Entity<Buffer>,
 5700        position: Anchor,
 5701        trigger: String,
 5702        cx: &mut Context<Self>,
 5703    ) -> Task<Result<Option<Transaction>>> {
 5704        if let Some((client, project_id)) = self.upstream_client() {
 5705            if !self.check_if_capable_for_proto_request(
 5706                &buffer,
 5707                |capabilities| {
 5708                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5709                },
 5710                cx,
 5711            ) {
 5712                return Task::ready(Ok(None));
 5713            }
 5714            let request = proto::OnTypeFormatting {
 5715                project_id,
 5716                buffer_id: buffer.read(cx).remote_id().into(),
 5717                position: Some(serialize_anchor(&position)),
 5718                trigger,
 5719                version: serialize_version(&buffer.read(cx).version()),
 5720            };
 5721            cx.background_spawn(async move {
 5722                client
 5723                    .request(request)
 5724                    .await?
 5725                    .transaction
 5726                    .map(language::proto::deserialize_transaction)
 5727                    .transpose()
 5728            })
 5729        } else if let Some(local) = self.as_local_mut() {
 5730            let buffer_id = buffer.read(cx).remote_id();
 5731            local.buffers_being_formatted.insert(buffer_id);
 5732            cx.spawn(async move |this, cx| {
 5733                let _cleanup = defer({
 5734                    let this = this.clone();
 5735                    let mut cx = cx.clone();
 5736                    move || {
 5737                        this.update(&mut cx, |this, _| {
 5738                            if let Some(local) = this.as_local_mut() {
 5739                                local.buffers_being_formatted.remove(&buffer_id);
 5740                            }
 5741                        })
 5742                        .ok();
 5743                    }
 5744                });
 5745
 5746                buffer
 5747                    .update(cx, |buffer, _| {
 5748                        buffer.wait_for_edits(Some(position.timestamp()))
 5749                    })
 5750                    .await?;
 5751                this.update(cx, |this, cx| {
 5752                    let position = position.to_point_utf16(buffer.read(cx));
 5753                    this.on_type_format(buffer, position, trigger, false, cx)
 5754                })?
 5755                .await
 5756            })
 5757        } else {
 5758            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5759        }
 5760    }
 5761
 5762    pub fn on_type_format<T: ToPointUtf16>(
 5763        &mut self,
 5764        buffer: Entity<Buffer>,
 5765        position: T,
 5766        trigger: String,
 5767        push_to_history: bool,
 5768        cx: &mut Context<Self>,
 5769    ) -> Task<Result<Option<Transaction>>> {
 5770        let position = position.to_point_utf16(buffer.read(cx));
 5771        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5772    }
 5773
 5774    fn on_type_format_impl(
 5775        &mut self,
 5776        buffer: Entity<Buffer>,
 5777        position: PointUtf16,
 5778        trigger: String,
 5779        push_to_history: bool,
 5780        cx: &mut Context<Self>,
 5781    ) -> Task<Result<Option<Transaction>>> {
 5782        let options = buffer.update(cx, |buffer, cx| {
 5783            lsp_command::lsp_formatting_options(
 5784                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5785            )
 5786        });
 5787
 5788        cx.spawn(async move |this, cx| {
 5789            if let Some(waiter) =
 5790                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5791            {
 5792                waiter.await?;
 5793            }
 5794            cx.update(|cx| {
 5795                this.update(cx, |this, cx| {
 5796                    this.request_lsp(
 5797                        buffer.clone(),
 5798                        LanguageServerToQuery::FirstCapable,
 5799                        OnTypeFormatting {
 5800                            position,
 5801                            trigger,
 5802                            options,
 5803                            push_to_history,
 5804                        },
 5805                        cx,
 5806                    )
 5807                })
 5808            })?
 5809            .await
 5810        })
 5811    }
 5812
 5813    pub fn definitions(
 5814        &mut self,
 5815        buffer: &Entity<Buffer>,
 5816        position: PointUtf16,
 5817        cx: &mut Context<Self>,
 5818    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5819        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5820            let request = GetDefinitions { position };
 5821            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5822                return Task::ready(Ok(None));
 5823            }
 5824
 5825            let request_timeout = ProjectSettings::get_global(cx)
 5826                .global_lsp_settings
 5827                .get_request_timeout();
 5828
 5829            let request_task = upstream_client.request_lsp(
 5830                project_id,
 5831                None,
 5832                request_timeout,
 5833                cx.background_executor().clone(),
 5834                request.to_proto(project_id, buffer.read(cx)),
 5835            );
 5836            let buffer = buffer.clone();
 5837            cx.spawn(async move |weak_lsp_store, cx| {
 5838                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5839                    return Ok(None);
 5840                };
 5841                let Some(responses) = request_task.await? else {
 5842                    return Ok(None);
 5843                };
 5844                let actions = join_all(responses.payload.into_iter().map(|response| {
 5845                    GetDefinitions { position }.response_from_proto(
 5846                        response.response,
 5847                        lsp_store.clone(),
 5848                        buffer.clone(),
 5849                        cx.clone(),
 5850                    )
 5851                }))
 5852                .await;
 5853
 5854                Ok(Some(
 5855                    actions
 5856                        .into_iter()
 5857                        .collect::<Result<Vec<Vec<_>>>>()?
 5858                        .into_iter()
 5859                        .flatten()
 5860                        .dedup()
 5861                        .collect(),
 5862                ))
 5863            })
 5864        } else {
 5865            let definitions_task = self.request_multiple_lsp_locally(
 5866                buffer,
 5867                Some(position),
 5868                GetDefinitions { position },
 5869                cx,
 5870            );
 5871            cx.background_spawn(async move {
 5872                Ok(Some(
 5873                    definitions_task
 5874                        .await
 5875                        .into_iter()
 5876                        .flat_map(|(_, definitions)| definitions)
 5877                        .dedup()
 5878                        .collect(),
 5879                ))
 5880            })
 5881        }
 5882    }
 5883
 5884    pub fn declarations(
 5885        &mut self,
 5886        buffer: &Entity<Buffer>,
 5887        position: PointUtf16,
 5888        cx: &mut Context<Self>,
 5889    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5890        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5891            let request = GetDeclarations { position };
 5892            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5893                return Task::ready(Ok(None));
 5894            }
 5895            let request_timeout = ProjectSettings::get_global(cx)
 5896                .global_lsp_settings
 5897                .get_request_timeout();
 5898            let request_task = upstream_client.request_lsp(
 5899                project_id,
 5900                None,
 5901                request_timeout,
 5902                cx.background_executor().clone(),
 5903                request.to_proto(project_id, buffer.read(cx)),
 5904            );
 5905            let buffer = buffer.clone();
 5906            cx.spawn(async move |weak_lsp_store, cx| {
 5907                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5908                    return Ok(None);
 5909                };
 5910                let Some(responses) = request_task.await? else {
 5911                    return Ok(None);
 5912                };
 5913                let actions = join_all(responses.payload.into_iter().map(|response| {
 5914                    GetDeclarations { position }.response_from_proto(
 5915                        response.response,
 5916                        lsp_store.clone(),
 5917                        buffer.clone(),
 5918                        cx.clone(),
 5919                    )
 5920                }))
 5921                .await;
 5922
 5923                Ok(Some(
 5924                    actions
 5925                        .into_iter()
 5926                        .collect::<Result<Vec<Vec<_>>>>()?
 5927                        .into_iter()
 5928                        .flatten()
 5929                        .dedup()
 5930                        .collect(),
 5931                ))
 5932            })
 5933        } else {
 5934            let declarations_task = self.request_multiple_lsp_locally(
 5935                buffer,
 5936                Some(position),
 5937                GetDeclarations { position },
 5938                cx,
 5939            );
 5940            cx.background_spawn(async move {
 5941                Ok(Some(
 5942                    declarations_task
 5943                        .await
 5944                        .into_iter()
 5945                        .flat_map(|(_, declarations)| declarations)
 5946                        .dedup()
 5947                        .collect(),
 5948                ))
 5949            })
 5950        }
 5951    }
 5952
 5953    pub fn type_definitions(
 5954        &mut self,
 5955        buffer: &Entity<Buffer>,
 5956        position: PointUtf16,
 5957        cx: &mut Context<Self>,
 5958    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5959        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5960            let request = GetTypeDefinitions { position };
 5961            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5962                return Task::ready(Ok(None));
 5963            }
 5964            let request_timeout = ProjectSettings::get_global(cx)
 5965                .global_lsp_settings
 5966                .get_request_timeout();
 5967            let request_task = upstream_client.request_lsp(
 5968                project_id,
 5969                None,
 5970                request_timeout,
 5971                cx.background_executor().clone(),
 5972                request.to_proto(project_id, buffer.read(cx)),
 5973            );
 5974            let buffer = buffer.clone();
 5975            cx.spawn(async move |weak_lsp_store, cx| {
 5976                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5977                    return Ok(None);
 5978                };
 5979                let Some(responses) = request_task.await? else {
 5980                    return Ok(None);
 5981                };
 5982                let actions = join_all(responses.payload.into_iter().map(|response| {
 5983                    GetTypeDefinitions { position }.response_from_proto(
 5984                        response.response,
 5985                        lsp_store.clone(),
 5986                        buffer.clone(),
 5987                        cx.clone(),
 5988                    )
 5989                }))
 5990                .await;
 5991
 5992                Ok(Some(
 5993                    actions
 5994                        .into_iter()
 5995                        .collect::<Result<Vec<Vec<_>>>>()?
 5996                        .into_iter()
 5997                        .flatten()
 5998                        .dedup()
 5999                        .collect(),
 6000                ))
 6001            })
 6002        } else {
 6003            let type_definitions_task = self.request_multiple_lsp_locally(
 6004                buffer,
 6005                Some(position),
 6006                GetTypeDefinitions { position },
 6007                cx,
 6008            );
 6009            cx.background_spawn(async move {
 6010                Ok(Some(
 6011                    type_definitions_task
 6012                        .await
 6013                        .into_iter()
 6014                        .flat_map(|(_, type_definitions)| type_definitions)
 6015                        .dedup()
 6016                        .collect(),
 6017                ))
 6018            })
 6019        }
 6020    }
 6021
 6022    pub fn implementations(
 6023        &mut self,
 6024        buffer: &Entity<Buffer>,
 6025        position: PointUtf16,
 6026        cx: &mut Context<Self>,
 6027    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6028        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6029            let request = GetImplementations { position };
 6030            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6031                return Task::ready(Ok(None));
 6032            }
 6033
 6034            let request_timeout = ProjectSettings::get_global(cx)
 6035                .global_lsp_settings
 6036                .get_request_timeout();
 6037            let request_task = upstream_client.request_lsp(
 6038                project_id,
 6039                None,
 6040                request_timeout,
 6041                cx.background_executor().clone(),
 6042                request.to_proto(project_id, buffer.read(cx)),
 6043            );
 6044            let buffer = buffer.clone();
 6045            cx.spawn(async move |weak_lsp_store, cx| {
 6046                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6047                    return Ok(None);
 6048                };
 6049                let Some(responses) = request_task.await? else {
 6050                    return Ok(None);
 6051                };
 6052                let actions = join_all(responses.payload.into_iter().map(|response| {
 6053                    GetImplementations { position }.response_from_proto(
 6054                        response.response,
 6055                        lsp_store.clone(),
 6056                        buffer.clone(),
 6057                        cx.clone(),
 6058                    )
 6059                }))
 6060                .await;
 6061
 6062                Ok(Some(
 6063                    actions
 6064                        .into_iter()
 6065                        .collect::<Result<Vec<Vec<_>>>>()?
 6066                        .into_iter()
 6067                        .flatten()
 6068                        .dedup()
 6069                        .collect(),
 6070                ))
 6071            })
 6072        } else {
 6073            let implementations_task = self.request_multiple_lsp_locally(
 6074                buffer,
 6075                Some(position),
 6076                GetImplementations { position },
 6077                cx,
 6078            );
 6079            cx.background_spawn(async move {
 6080                Ok(Some(
 6081                    implementations_task
 6082                        .await
 6083                        .into_iter()
 6084                        .flat_map(|(_, implementations)| implementations)
 6085                        .dedup()
 6086                        .collect(),
 6087                ))
 6088            })
 6089        }
 6090    }
 6091
 6092    pub fn references(
 6093        &mut self,
 6094        buffer: &Entity<Buffer>,
 6095        position: PointUtf16,
 6096        cx: &mut Context<Self>,
 6097    ) -> Task<Result<Option<Vec<Location>>>> {
 6098        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6099            let request = GetReferences { position };
 6100            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6101                return Task::ready(Ok(None));
 6102            }
 6103
 6104            let request_timeout = ProjectSettings::get_global(cx)
 6105                .global_lsp_settings
 6106                .get_request_timeout();
 6107            let request_task = upstream_client.request_lsp(
 6108                project_id,
 6109                None,
 6110                request_timeout,
 6111                cx.background_executor().clone(),
 6112                request.to_proto(project_id, buffer.read(cx)),
 6113            );
 6114            let buffer = buffer.clone();
 6115            cx.spawn(async move |weak_lsp_store, cx| {
 6116                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6117                    return Ok(None);
 6118                };
 6119                let Some(responses) = request_task.await? else {
 6120                    return Ok(None);
 6121                };
 6122
 6123                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6124                    GetReferences { position }.response_from_proto(
 6125                        lsp_response.response,
 6126                        lsp_store.clone(),
 6127                        buffer.clone(),
 6128                        cx.clone(),
 6129                    )
 6130                }))
 6131                .await
 6132                .into_iter()
 6133                .collect::<Result<Vec<Vec<_>>>>()?
 6134                .into_iter()
 6135                .flatten()
 6136                .dedup()
 6137                .collect();
 6138                Ok(Some(locations))
 6139            })
 6140        } else {
 6141            let references_task = self.request_multiple_lsp_locally(
 6142                buffer,
 6143                Some(position),
 6144                GetReferences { position },
 6145                cx,
 6146            );
 6147            cx.background_spawn(async move {
 6148                Ok(Some(
 6149                    references_task
 6150                        .await
 6151                        .into_iter()
 6152                        .flat_map(|(_, references)| references)
 6153                        .dedup()
 6154                        .collect(),
 6155                ))
 6156            })
 6157        }
 6158    }
 6159
 6160    pub fn code_actions(
 6161        &mut self,
 6162        buffer: &Entity<Buffer>,
 6163        range: Range<Anchor>,
 6164        kinds: Option<Vec<CodeActionKind>>,
 6165        cx: &mut Context<Self>,
 6166    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6167        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6168            let request = GetCodeActions {
 6169                range: range.clone(),
 6170                kinds: kinds.clone(),
 6171            };
 6172            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6173                return Task::ready(Ok(None));
 6174            }
 6175            let request_timeout = ProjectSettings::get_global(cx)
 6176                .global_lsp_settings
 6177                .get_request_timeout();
 6178            let request_task = upstream_client.request_lsp(
 6179                project_id,
 6180                None,
 6181                request_timeout,
 6182                cx.background_executor().clone(),
 6183                request.to_proto(project_id, buffer.read(cx)),
 6184            );
 6185            let buffer = buffer.clone();
 6186            cx.spawn(async move |weak_lsp_store, cx| {
 6187                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6188                    return Ok(None);
 6189                };
 6190                let Some(responses) = request_task.await? else {
 6191                    return Ok(None);
 6192                };
 6193                let actions = join_all(responses.payload.into_iter().map(|response| {
 6194                    GetCodeActions {
 6195                        range: range.clone(),
 6196                        kinds: kinds.clone(),
 6197                    }
 6198                    .response_from_proto(
 6199                        response.response,
 6200                        lsp_store.clone(),
 6201                        buffer.clone(),
 6202                        cx.clone(),
 6203                    )
 6204                }))
 6205                .await;
 6206
 6207                Ok(Some(
 6208                    actions
 6209                        .into_iter()
 6210                        .collect::<Result<Vec<Vec<_>>>>()?
 6211                        .into_iter()
 6212                        .flatten()
 6213                        .collect(),
 6214                ))
 6215            })
 6216        } else {
 6217            let all_actions_task = self.request_multiple_lsp_locally(
 6218                buffer,
 6219                Some(range.start),
 6220                GetCodeActions { range, kinds },
 6221                cx,
 6222            );
 6223            cx.background_spawn(async move {
 6224                Ok(Some(
 6225                    all_actions_task
 6226                        .await
 6227                        .into_iter()
 6228                        .flat_map(|(_, actions)| actions)
 6229                        .collect(),
 6230                ))
 6231            })
 6232        }
 6233    }
 6234
 6235    #[inline(never)]
 6236    pub fn completions(
 6237        &self,
 6238        buffer: &Entity<Buffer>,
 6239        position: PointUtf16,
 6240        context: CompletionContext,
 6241        cx: &mut Context<Self>,
 6242    ) -> Task<Result<Vec<CompletionResponse>>> {
 6243        let language_registry = self.languages.clone();
 6244
 6245        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6246            let snapshot = buffer.read(cx).snapshot();
 6247            let offset = position.to_offset(&snapshot);
 6248            let scope = snapshot.language_scope_at(offset);
 6249            let capable_lsps = self.all_capable_for_proto_request(
 6250                buffer,
 6251                |server_name, capabilities| {
 6252                    capabilities.completion_provider.is_some()
 6253                        && scope
 6254                            .as_ref()
 6255                            .map(|scope| scope.language_allowed(server_name))
 6256                            .unwrap_or(true)
 6257                },
 6258                cx,
 6259            );
 6260            if capable_lsps.is_empty() {
 6261                return Task::ready(Ok(Vec::new()));
 6262            }
 6263
 6264            let language = buffer.read(cx).language().cloned();
 6265
 6266            let buffer = buffer.clone();
 6267
 6268            cx.spawn(async move |this, cx| {
 6269                let requests = join_all(
 6270                    capable_lsps
 6271                        .into_iter()
 6272                        .map(|(id, server_name)| {
 6273                            let request = GetCompletions {
 6274                                position,
 6275                                context: context.clone(),
 6276                                server_id: Some(id),
 6277                            };
 6278                            let buffer = buffer.clone();
 6279                            let language = language.clone();
 6280                            let lsp_adapter = language.as_ref().and_then(|language| {
 6281                                let adapters = language_registry.lsp_adapters(&language.name());
 6282                                adapters
 6283                                    .iter()
 6284                                    .find(|adapter| adapter.name() == server_name)
 6285                                    .or_else(|| adapters.first())
 6286                                    .cloned()
 6287                            });
 6288                            let upstream_client = upstream_client.clone();
 6289                            let response = this
 6290                                .update(cx, |this, cx| {
 6291                                    this.send_lsp_proto_request(
 6292                                        buffer,
 6293                                        upstream_client,
 6294                                        project_id,
 6295                                        request,
 6296                                        cx,
 6297                                    )
 6298                                })
 6299                                .log_err();
 6300                            async move {
 6301                                let response = response?.await.log_err()?;
 6302
 6303                                let completions = populate_labels_for_completions(
 6304                                    response.completions,
 6305                                    language,
 6306                                    lsp_adapter,
 6307                                )
 6308                                .await;
 6309
 6310                                Some(CompletionResponse {
 6311                                    completions,
 6312                                    display_options: CompletionDisplayOptions::default(),
 6313                                    is_incomplete: response.is_incomplete,
 6314                                })
 6315                            }
 6316                        })
 6317                        .collect::<Vec<_>>(),
 6318                );
 6319                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6320            })
 6321        } else if let Some(local) = self.as_local() {
 6322            let snapshot = buffer.read(cx).snapshot();
 6323            let offset = position.to_offset(&snapshot);
 6324            let scope = snapshot.language_scope_at(offset);
 6325            let language = snapshot.language().cloned();
 6326            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6327                .completions
 6328                .clone();
 6329            if !completion_settings.lsp {
 6330                return Task::ready(Ok(Vec::new()));
 6331            }
 6332
 6333            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6334                local
 6335                    .language_servers_for_buffer(buffer, cx)
 6336                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6337                    .filter(|(adapter, _)| {
 6338                        scope
 6339                            .as_ref()
 6340                            .map(|scope| scope.language_allowed(&adapter.name))
 6341                            .unwrap_or(true)
 6342                    })
 6343                    .map(|(_, server)| server.server_id())
 6344                    .collect()
 6345            });
 6346
 6347            let buffer = buffer.clone();
 6348            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6349            let lsp_timeout = if lsp_timeout > 0 {
 6350                Some(Duration::from_millis(lsp_timeout))
 6351            } else {
 6352                None
 6353            };
 6354            cx.spawn(async move |this,  cx| {
 6355                let mut tasks = Vec::with_capacity(server_ids.len());
 6356                this.update(cx, |lsp_store, cx| {
 6357                    for server_id in server_ids {
 6358                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6359                        let lsp_timeout = lsp_timeout
 6360                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6361                        let mut timeout = cx.background_spawn(async move {
 6362                            match lsp_timeout {
 6363                                Some(lsp_timeout) => {
 6364                                    lsp_timeout.await;
 6365                                    true
 6366                                },
 6367                                None => false,
 6368                            }
 6369                        }).fuse();
 6370                        let mut lsp_request = lsp_store.request_lsp(
 6371                            buffer.clone(),
 6372                            LanguageServerToQuery::Other(server_id),
 6373                            GetCompletions {
 6374                                position,
 6375                                context: context.clone(),
 6376                                server_id: Some(server_id),
 6377                            },
 6378                            cx,
 6379                        ).fuse();
 6380                        let new_task = cx.background_spawn(async move {
 6381                            select_biased! {
 6382                                response = lsp_request => anyhow::Ok(Some(response?)),
 6383                                timeout_happened = timeout => {
 6384                                    if timeout_happened {
 6385                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6386                                        Ok(None)
 6387                                    } else {
 6388                                        let completions = lsp_request.await?;
 6389                                        Ok(Some(completions))
 6390                                    }
 6391                                },
 6392                            }
 6393                        });
 6394                        tasks.push((lsp_adapter, new_task));
 6395                    }
 6396                })?;
 6397
 6398                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6399                    let completion_response = task.await.ok()??;
 6400                    let completions = populate_labels_for_completions(
 6401                            completion_response.completions,
 6402                            language.clone(),
 6403                            lsp_adapter,
 6404                        )
 6405                        .await;
 6406                    Some(CompletionResponse {
 6407                        completions,
 6408                        display_options: CompletionDisplayOptions::default(),
 6409                        is_incomplete: completion_response.is_incomplete,
 6410                    })
 6411                });
 6412
 6413                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6414
 6415                Ok(responses.into_iter().flatten().collect())
 6416            })
 6417        } else {
 6418            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6419        }
 6420    }
 6421
 6422    pub fn resolve_completions(
 6423        &self,
 6424        buffer: Entity<Buffer>,
 6425        completion_indices: Vec<usize>,
 6426        completions: Rc<RefCell<Box<[Completion]>>>,
 6427        cx: &mut Context<Self>,
 6428    ) -> Task<Result<bool>> {
 6429        let client = self.upstream_client();
 6430        let buffer_id = buffer.read(cx).remote_id();
 6431        let buffer_snapshot = buffer.read(cx).snapshot();
 6432
 6433        if !self.check_if_capable_for_proto_request(
 6434            &buffer,
 6435            GetCompletions::can_resolve_completions,
 6436            cx,
 6437        ) {
 6438            return Task::ready(Ok(false));
 6439        }
 6440        cx.spawn(async move |lsp_store, cx| {
 6441            let request_timeout = cx.update(|app| {
 6442                ProjectSettings::get_global(app)
 6443                    .global_lsp_settings
 6444                    .get_request_timeout()
 6445            });
 6446
 6447            let mut did_resolve = false;
 6448            if let Some((client, project_id)) = client {
 6449                for completion_index in completion_indices {
 6450                    let server_id = {
 6451                        let completion = &completions.borrow()[completion_index];
 6452                        completion.source.server_id()
 6453                    };
 6454                    if let Some(server_id) = server_id {
 6455                        if Self::resolve_completion_remote(
 6456                            project_id,
 6457                            server_id,
 6458                            buffer_id,
 6459                            completions.clone(),
 6460                            completion_index,
 6461                            client.clone(),
 6462                        )
 6463                        .await
 6464                        .log_err()
 6465                        .is_some()
 6466                        {
 6467                            did_resolve = true;
 6468                        }
 6469                    } else {
 6470                        resolve_word_completion(
 6471                            &buffer_snapshot,
 6472                            &mut completions.borrow_mut()[completion_index],
 6473                        );
 6474                    }
 6475                }
 6476            } else {
 6477                for completion_index in completion_indices {
 6478                    let server_id = {
 6479                        let completion = &completions.borrow()[completion_index];
 6480                        completion.source.server_id()
 6481                    };
 6482                    if let Some(server_id) = server_id {
 6483                        let server_and_adapter = lsp_store
 6484                            .read_with(cx, |lsp_store, _| {
 6485                                let server = lsp_store.language_server_for_id(server_id)?;
 6486                                let adapter =
 6487                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6488                                Some((server, adapter))
 6489                            })
 6490                            .ok()
 6491                            .flatten();
 6492                        let Some((server, adapter)) = server_and_adapter else {
 6493                            continue;
 6494                        };
 6495
 6496                        let resolved = Self::resolve_completion_local(
 6497                            server,
 6498                            completions.clone(),
 6499                            completion_index,
 6500                            request_timeout,
 6501                        )
 6502                        .await
 6503                        .log_err()
 6504                        .is_some();
 6505                        if resolved {
 6506                            Self::regenerate_completion_labels(
 6507                                adapter,
 6508                                &buffer_snapshot,
 6509                                completions.clone(),
 6510                                completion_index,
 6511                            )
 6512                            .await
 6513                            .log_err();
 6514                            did_resolve = true;
 6515                        }
 6516                    } else {
 6517                        resolve_word_completion(
 6518                            &buffer_snapshot,
 6519                            &mut completions.borrow_mut()[completion_index],
 6520                        );
 6521                    }
 6522                }
 6523            }
 6524
 6525            Ok(did_resolve)
 6526        })
 6527    }
 6528
 6529    async fn resolve_completion_local(
 6530        server: Arc<lsp::LanguageServer>,
 6531        completions: Rc<RefCell<Box<[Completion]>>>,
 6532        completion_index: usize,
 6533        request_timeout: Duration,
 6534    ) -> Result<()> {
 6535        let server_id = server.server_id();
 6536        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6537            return Ok(());
 6538        }
 6539
 6540        let request = {
 6541            let completion = &completions.borrow()[completion_index];
 6542            match &completion.source {
 6543                CompletionSource::Lsp {
 6544                    lsp_completion,
 6545                    resolved,
 6546                    server_id: completion_server_id,
 6547                    ..
 6548                } => {
 6549                    if *resolved {
 6550                        return Ok(());
 6551                    }
 6552                    anyhow::ensure!(
 6553                        server_id == *completion_server_id,
 6554                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6555                    );
 6556                    server.request::<lsp::request::ResolveCompletionItem>(
 6557                        *lsp_completion.clone(),
 6558                        request_timeout,
 6559                    )
 6560                }
 6561                CompletionSource::BufferWord { .. }
 6562                | CompletionSource::Dap { .. }
 6563                | CompletionSource::Custom => {
 6564                    return Ok(());
 6565                }
 6566            }
 6567        };
 6568        let resolved_completion = request
 6569            .await
 6570            .into_response()
 6571            .context("resolve completion")?;
 6572
 6573        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6574        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6575
 6576        let mut completions = completions.borrow_mut();
 6577        let completion = &mut completions[completion_index];
 6578        if let CompletionSource::Lsp {
 6579            lsp_completion,
 6580            resolved,
 6581            server_id: completion_server_id,
 6582            ..
 6583        } = &mut completion.source
 6584        {
 6585            if *resolved {
 6586                return Ok(());
 6587            }
 6588            anyhow::ensure!(
 6589                server_id == *completion_server_id,
 6590                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6591            );
 6592            **lsp_completion = resolved_completion;
 6593            *resolved = true;
 6594        }
 6595        Ok(())
 6596    }
 6597
 6598    async fn regenerate_completion_labels(
 6599        adapter: Arc<CachedLspAdapter>,
 6600        snapshot: &BufferSnapshot,
 6601        completions: Rc<RefCell<Box<[Completion]>>>,
 6602        completion_index: usize,
 6603    ) -> Result<()> {
 6604        let completion_item = completions.borrow()[completion_index]
 6605            .source
 6606            .lsp_completion(true)
 6607            .map(Cow::into_owned);
 6608        if let Some(lsp_documentation) = completion_item
 6609            .as_ref()
 6610            .and_then(|completion_item| completion_item.documentation.clone())
 6611        {
 6612            let mut completions = completions.borrow_mut();
 6613            let completion = &mut completions[completion_index];
 6614            completion.documentation = Some(lsp_documentation.into());
 6615        } else {
 6616            let mut completions = completions.borrow_mut();
 6617            let completion = &mut completions[completion_index];
 6618            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6619        }
 6620
 6621        let mut new_label = match completion_item {
 6622            Some(completion_item) => {
 6623                // Some language servers always return `detail` lazily via resolve, regardless of
 6624                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6625                // See: https://github.com/yioneko/vtsls/issues/213
 6626                let language = snapshot.language();
 6627                match language {
 6628                    Some(language) => {
 6629                        adapter
 6630                            .labels_for_completions(
 6631                                std::slice::from_ref(&completion_item),
 6632                                language,
 6633                            )
 6634                            .await?
 6635                    }
 6636                    None => Vec::new(),
 6637                }
 6638                .pop()
 6639                .flatten()
 6640                .unwrap_or_else(|| {
 6641                    CodeLabel::fallback_for_completion(
 6642                        &completion_item,
 6643                        language.map(|language| language.as_ref()),
 6644                    )
 6645                })
 6646            }
 6647            None => CodeLabel::plain(
 6648                completions.borrow()[completion_index].new_text.clone(),
 6649                None,
 6650            ),
 6651        };
 6652        ensure_uniform_list_compatible_label(&mut new_label);
 6653
 6654        let mut completions = completions.borrow_mut();
 6655        let completion = &mut completions[completion_index];
 6656        if completion.label.filter_text() == new_label.filter_text() {
 6657            completion.label = new_label;
 6658        } else {
 6659            log::error!(
 6660                "Resolved completion changed display label from {} to {}. \
 6661                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6662                completion.label.text(),
 6663                new_label.text(),
 6664                completion.label.filter_text(),
 6665                new_label.filter_text()
 6666            );
 6667        }
 6668
 6669        Ok(())
 6670    }
 6671
 6672    async fn resolve_completion_remote(
 6673        project_id: u64,
 6674        server_id: LanguageServerId,
 6675        buffer_id: BufferId,
 6676        completions: Rc<RefCell<Box<[Completion]>>>,
 6677        completion_index: usize,
 6678        client: AnyProtoClient,
 6679    ) -> Result<()> {
 6680        let lsp_completion = {
 6681            let completion = &completions.borrow()[completion_index];
 6682            match &completion.source {
 6683                CompletionSource::Lsp {
 6684                    lsp_completion,
 6685                    resolved,
 6686                    server_id: completion_server_id,
 6687                    ..
 6688                } => {
 6689                    anyhow::ensure!(
 6690                        server_id == *completion_server_id,
 6691                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6692                    );
 6693                    if *resolved {
 6694                        return Ok(());
 6695                    }
 6696                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6697                }
 6698                CompletionSource::Custom
 6699                | CompletionSource::Dap { .. }
 6700                | CompletionSource::BufferWord { .. } => {
 6701                    return Ok(());
 6702                }
 6703            }
 6704        };
 6705        let request = proto::ResolveCompletionDocumentation {
 6706            project_id,
 6707            language_server_id: server_id.0 as u64,
 6708            lsp_completion,
 6709            buffer_id: buffer_id.into(),
 6710        };
 6711
 6712        let response = client
 6713            .request(request)
 6714            .await
 6715            .context("completion documentation resolve proto request")?;
 6716        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6717
 6718        let documentation = if response.documentation.is_empty() {
 6719            CompletionDocumentation::Undocumented
 6720        } else if response.documentation_is_markdown {
 6721            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6722        } else if response.documentation.lines().count() <= 1 {
 6723            CompletionDocumentation::SingleLine(response.documentation.into())
 6724        } else {
 6725            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6726        };
 6727
 6728        let mut completions = completions.borrow_mut();
 6729        let completion = &mut completions[completion_index];
 6730        completion.documentation = Some(documentation);
 6731        if let CompletionSource::Lsp {
 6732            insert_range,
 6733            lsp_completion,
 6734            resolved,
 6735            server_id: completion_server_id,
 6736            lsp_defaults: _,
 6737        } = &mut completion.source
 6738        {
 6739            let completion_insert_range = response
 6740                .old_insert_start
 6741                .and_then(deserialize_anchor)
 6742                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6743            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6744
 6745            if *resolved {
 6746                return Ok(());
 6747            }
 6748            anyhow::ensure!(
 6749                server_id == *completion_server_id,
 6750                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6751            );
 6752            **lsp_completion = resolved_lsp_completion;
 6753            *resolved = true;
 6754        }
 6755
 6756        let replace_range = response
 6757            .old_replace_start
 6758            .and_then(deserialize_anchor)
 6759            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6760        if let Some((old_replace_start, old_replace_end)) = replace_range
 6761            && !response.new_text.is_empty()
 6762        {
 6763            completion.new_text = response.new_text;
 6764            completion.replace_range = old_replace_start..old_replace_end;
 6765        }
 6766
 6767        Ok(())
 6768    }
 6769
 6770    pub fn apply_additional_edits_for_completion(
 6771        &self,
 6772        buffer_handle: Entity<Buffer>,
 6773        completions: Rc<RefCell<Box<[Completion]>>>,
 6774        completion_index: usize,
 6775        push_to_history: bool,
 6776        all_commit_ranges: Vec<Range<language::Anchor>>,
 6777        cx: &mut Context<Self>,
 6778    ) -> Task<Result<Option<Transaction>>> {
 6779        if let Some((client, project_id)) = self.upstream_client() {
 6780            let buffer = buffer_handle.read(cx);
 6781            let buffer_id = buffer.remote_id();
 6782            cx.spawn(async move |_, cx| {
 6783                let request = {
 6784                    let completion = completions.borrow()[completion_index].clone();
 6785                    proto::ApplyCompletionAdditionalEdits {
 6786                        project_id,
 6787                        buffer_id: buffer_id.into(),
 6788                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6789                            replace_range: completion.replace_range,
 6790                            new_text: completion.new_text,
 6791                            source: completion.source,
 6792                        })),
 6793                        all_commit_ranges: all_commit_ranges
 6794                            .iter()
 6795                            .cloned()
 6796                            .map(language::proto::serialize_anchor_range)
 6797                            .collect(),
 6798                    }
 6799                };
 6800
 6801                let Some(transaction) = client.request(request).await?.transaction else {
 6802                    return Ok(None);
 6803                };
 6804
 6805                let transaction = language::proto::deserialize_transaction(transaction)?;
 6806                buffer_handle
 6807                    .update(cx, |buffer, _| {
 6808                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6809                    })
 6810                    .await?;
 6811                if push_to_history {
 6812                    buffer_handle.update(cx, |buffer, _| {
 6813                        buffer.push_transaction(transaction.clone(), Instant::now());
 6814                        buffer.finalize_last_transaction();
 6815                    });
 6816                }
 6817                Ok(Some(transaction))
 6818            })
 6819        } else {
 6820            let request_timeout = ProjectSettings::get_global(cx)
 6821                .global_lsp_settings
 6822                .get_request_timeout();
 6823
 6824            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6825                let completion = &completions.borrow()[completion_index];
 6826                let server_id = completion.source.server_id()?;
 6827                Some(
 6828                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6829                        .1
 6830                        .clone(),
 6831                )
 6832            }) else {
 6833                return Task::ready(Ok(None));
 6834            };
 6835
 6836            cx.spawn(async move |this, cx| {
 6837                Self::resolve_completion_local(
 6838                    server.clone(),
 6839                    completions.clone(),
 6840                    completion_index,
 6841                    request_timeout,
 6842                )
 6843                .await
 6844                .context("resolving completion")?;
 6845                let completion = completions.borrow()[completion_index].clone();
 6846                let additional_text_edits = completion
 6847                    .source
 6848                    .lsp_completion(true)
 6849                    .as_ref()
 6850                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6851                if let Some(edits) = additional_text_edits {
 6852                    let edits = this
 6853                        .update(cx, |this, cx| {
 6854                            this.as_local_mut().unwrap().edits_from_lsp(
 6855                                &buffer_handle,
 6856                                edits,
 6857                                server.server_id(),
 6858                                None,
 6859                                cx,
 6860                            )
 6861                        })?
 6862                        .await?;
 6863
 6864                    buffer_handle.update(cx, |buffer, cx| {
 6865                        buffer.finalize_last_transaction();
 6866                        buffer.start_transaction();
 6867
 6868                        for (range, text) in edits {
 6869                            let primary = &completion.replace_range;
 6870
 6871                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6872                            // and the primary completion is just an insertion (empty range), then this is likely
 6873                            // an auto-import scenario and should not be considered overlapping
 6874                            // https://github.com/zed-industries/zed/issues/26136
 6875                            let is_file_start_auto_import = {
 6876                                let snapshot = buffer.snapshot();
 6877                                let primary_start_point = primary.start.to_point(&snapshot);
 6878                                let range_start_point = range.start.to_point(&snapshot);
 6879
 6880                                let result = primary_start_point.row == 0
 6881                                    && primary_start_point.column == 0
 6882                                    && range_start_point.row == 0
 6883                                    && range_start_point.column == 0;
 6884
 6885                                result
 6886                            };
 6887
 6888                            let has_overlap = if is_file_start_auto_import {
 6889                                false
 6890                            } else {
 6891                                all_commit_ranges.iter().any(|commit_range| {
 6892                                    let start_within =
 6893                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6894                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6895                                    let end_within =
 6896                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6897                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6898                                    start_within || end_within
 6899                                })
 6900                            };
 6901
 6902                            //Skip additional edits which overlap with the primary completion edit
 6903                            //https://github.com/zed-industries/zed/pull/1871
 6904                            if !has_overlap {
 6905                                buffer.edit([(range, text)], None, cx);
 6906                            }
 6907                        }
 6908
 6909                        let transaction = if buffer.end_transaction(cx).is_some() {
 6910                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6911                            if !push_to_history {
 6912                                buffer.forget_transaction(transaction.id);
 6913                            }
 6914                            Some(transaction)
 6915                        } else {
 6916                            None
 6917                        };
 6918                        Ok(transaction)
 6919                    })
 6920                } else {
 6921                    Ok(None)
 6922                }
 6923            })
 6924        }
 6925    }
 6926
 6927    pub fn pull_diagnostics(
 6928        &mut self,
 6929        buffer: Entity<Buffer>,
 6930        cx: &mut Context<Self>,
 6931    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6932        let buffer_id = buffer.read(cx).remote_id();
 6933
 6934        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6935            let mut suitable_capabilities = None;
 6936            // Are we capable for proto request?
 6937            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6938                &buffer,
 6939                |capabilities| {
 6940                    if let Some(caps) = &capabilities.diagnostic_provider {
 6941                        suitable_capabilities = Some(caps.clone());
 6942                        true
 6943                    } else {
 6944                        false
 6945                    }
 6946                },
 6947                cx,
 6948            );
 6949            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6950            let Some(dynamic_caps) = suitable_capabilities else {
 6951                return Task::ready(Ok(None));
 6952            };
 6953            assert!(any_server_has_diagnostics_provider);
 6954
 6955            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6956            let request = GetDocumentDiagnostics {
 6957                previous_result_id: None,
 6958                identifier,
 6959                registration_id: None,
 6960            };
 6961            let request_timeout = ProjectSettings::get_global(cx)
 6962                .global_lsp_settings
 6963                .get_request_timeout();
 6964            let request_task = client.request_lsp(
 6965                upstream_project_id,
 6966                None,
 6967                request_timeout,
 6968                cx.background_executor().clone(),
 6969                request.to_proto(upstream_project_id, buffer.read(cx)),
 6970            );
 6971            cx.background_spawn(async move {
 6972                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6973                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6974                // Do not attempt to further process the dummy responses here.
 6975                let _response = request_task.await?;
 6976                Ok(None)
 6977            })
 6978        } else {
 6979            let servers = buffer.update(cx, |buffer, cx| {
 6980                self.running_language_servers_for_local_buffer(buffer, cx)
 6981                    .map(|(_, server)| server.clone())
 6982                    .collect::<Vec<_>>()
 6983            });
 6984
 6985            let pull_diagnostics = servers
 6986                .into_iter()
 6987                .flat_map(|server| {
 6988                    let result = maybe!({
 6989                        let local = self.as_local()?;
 6990                        let server_id = server.server_id();
 6991                        let providers_with_identifiers = local
 6992                            .language_server_dynamic_registrations
 6993                            .get(&server_id)
 6994                            .into_iter()
 6995                            .flat_map(|registrations| registrations.diagnostics.clone())
 6996                            .collect::<Vec<_>>();
 6997                        Some(
 6998                            providers_with_identifiers
 6999                                .into_iter()
 7000                                .map(|(registration_id, dynamic_caps)| {
 7001                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7002                                    let registration_id = registration_id.map(SharedString::from);
 7003                                    let result_id = self.result_id_for_buffer_pull(
 7004                                        server_id,
 7005                                        buffer_id,
 7006                                        &registration_id,
 7007                                        cx,
 7008                                    );
 7009                                    self.request_lsp(
 7010                                        buffer.clone(),
 7011                                        LanguageServerToQuery::Other(server_id),
 7012                                        GetDocumentDiagnostics {
 7013                                            previous_result_id: result_id,
 7014                                            registration_id,
 7015                                            identifier,
 7016                                        },
 7017                                        cx,
 7018                                    )
 7019                                })
 7020                                .collect::<Vec<_>>(),
 7021                        )
 7022                    });
 7023
 7024                    result.unwrap_or_default()
 7025                })
 7026                .collect::<Vec<_>>();
 7027
 7028            cx.background_spawn(async move {
 7029                let mut responses = Vec::new();
 7030                for diagnostics in join_all(pull_diagnostics).await {
 7031                    responses.extend(diagnostics?);
 7032                }
 7033                Ok(Some(responses))
 7034            })
 7035        }
 7036    }
 7037
 7038    pub fn applicable_inlay_chunks(
 7039        &mut self,
 7040        buffer: &Entity<Buffer>,
 7041        ranges: &[Range<text::Anchor>],
 7042        cx: &mut Context<Self>,
 7043    ) -> Vec<Range<BufferRow>> {
 7044        let buffer_snapshot = buffer.read(cx).snapshot();
 7045        let ranges = ranges
 7046            .iter()
 7047            .map(|range| range.to_point(&buffer_snapshot))
 7048            .collect::<Vec<_>>();
 7049
 7050        self.latest_lsp_data(buffer, cx)
 7051            .inlay_hints
 7052            .applicable_chunks(ranges.as_slice())
 7053            .map(|chunk| chunk.row_range())
 7054            .collect()
 7055    }
 7056
 7057    pub fn invalidate_inlay_hints<'a>(
 7058        &'a mut self,
 7059        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7060    ) {
 7061        for buffer_id in for_buffers {
 7062            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7063                lsp_data.inlay_hints.clear();
 7064            }
 7065        }
 7066    }
 7067
 7068    pub fn inlay_hints(
 7069        &mut self,
 7070        invalidate: InvalidationStrategy,
 7071        buffer: Entity<Buffer>,
 7072        ranges: Vec<Range<text::Anchor>>,
 7073        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7074        cx: &mut Context<Self>,
 7075    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7076        let next_hint_id = self.next_hint_id.clone();
 7077        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7078        let query_version = lsp_data.buffer_version.clone();
 7079        let mut lsp_refresh_requested = false;
 7080        let for_server = if let InvalidationStrategy::RefreshRequested {
 7081            server_id,
 7082            request_id,
 7083        } = invalidate
 7084        {
 7085            let invalidated = lsp_data
 7086                .inlay_hints
 7087                .invalidate_for_server_refresh(server_id, request_id);
 7088            lsp_refresh_requested = invalidated;
 7089            Some(server_id)
 7090        } else {
 7091            None
 7092        };
 7093        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7094        let known_chunks = known_chunks
 7095            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7096            .map(|(_, known_chunks)| known_chunks)
 7097            .unwrap_or_default();
 7098
 7099        let buffer_snapshot = buffer.read(cx).snapshot();
 7100        let ranges = ranges
 7101            .iter()
 7102            .map(|range| range.to_point(&buffer_snapshot))
 7103            .collect::<Vec<_>>();
 7104
 7105        let mut hint_fetch_tasks = Vec::new();
 7106        let mut cached_inlay_hints = None;
 7107        let mut ranges_to_query = None;
 7108        let applicable_chunks = existing_inlay_hints
 7109            .applicable_chunks(ranges.as_slice())
 7110            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7111            .collect::<Vec<_>>();
 7112        if applicable_chunks.is_empty() {
 7113            return HashMap::default();
 7114        }
 7115
 7116        for row_chunk in applicable_chunks {
 7117            match (
 7118                existing_inlay_hints
 7119                    .cached_hints(&row_chunk)
 7120                    .filter(|_| !lsp_refresh_requested)
 7121                    .cloned(),
 7122                existing_inlay_hints
 7123                    .fetched_hints(&row_chunk)
 7124                    .as_ref()
 7125                    .filter(|_| !lsp_refresh_requested)
 7126                    .cloned(),
 7127            ) {
 7128                (None, None) => {
 7129                    let chunk_range = row_chunk.anchor_range();
 7130                    ranges_to_query
 7131                        .get_or_insert_with(Vec::new)
 7132                        .push((row_chunk, chunk_range));
 7133                }
 7134                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7135                (Some(cached_hints), None) => {
 7136                    for (server_id, cached_hints) in cached_hints {
 7137                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7138                            cached_inlay_hints
 7139                                .get_or_insert_with(HashMap::default)
 7140                                .entry(row_chunk.row_range())
 7141                                .or_insert_with(HashMap::default)
 7142                                .entry(server_id)
 7143                                .or_insert_with(Vec::new)
 7144                                .extend(cached_hints);
 7145                        }
 7146                    }
 7147                }
 7148                (Some(cached_hints), Some(fetched_hints)) => {
 7149                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7150                    for (server_id, cached_hints) in cached_hints {
 7151                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7152                            cached_inlay_hints
 7153                                .get_or_insert_with(HashMap::default)
 7154                                .entry(row_chunk.row_range())
 7155                                .or_insert_with(HashMap::default)
 7156                                .entry(server_id)
 7157                                .or_insert_with(Vec::new)
 7158                                .extend(cached_hints);
 7159                        }
 7160                    }
 7161                }
 7162            }
 7163        }
 7164
 7165        if hint_fetch_tasks.is_empty()
 7166            && ranges_to_query
 7167                .as_ref()
 7168                .is_none_or(|ranges| ranges.is_empty())
 7169            && let Some(cached_inlay_hints) = cached_inlay_hints
 7170        {
 7171            cached_inlay_hints
 7172                .into_iter()
 7173                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7174                .collect()
 7175        } else {
 7176            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7177                // When a server refresh was requested, other servers' cached hints
 7178                // are unaffected by the refresh and must be included in the result.
 7179                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7180                // removes all visible hints but only adds back the requesting
 7181                // server's new hints, permanently losing other servers' hints.
 7182                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7183                    lsp_data
 7184                        .inlay_hints
 7185                        .cached_hints(&chunk)
 7186                        .cloned()
 7187                        .unwrap_or_default()
 7188                } else {
 7189                    HashMap::default()
 7190                };
 7191
 7192                let next_hint_id = next_hint_id.clone();
 7193                let buffer = buffer.clone();
 7194                let query_version = query_version.clone();
 7195                let new_inlay_hints = cx
 7196                    .spawn(async move |lsp_store, cx| {
 7197                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7198                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7199                        })?;
 7200                        new_fetch_task
 7201                            .await
 7202                            .and_then(|new_hints_by_server| {
 7203                                lsp_store.update(cx, |lsp_store, cx| {
 7204                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7205                                    let update_cache = lsp_data.buffer_version == query_version;
 7206                                    if new_hints_by_server.is_empty() {
 7207                                        if update_cache {
 7208                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7209                                        }
 7210                                        other_servers_cached
 7211                                    } else {
 7212                                        let mut result = other_servers_cached;
 7213                                        for (server_id, new_hints) in new_hints_by_server {
 7214                                            let new_hints = new_hints
 7215                                                .into_iter()
 7216                                                .map(|new_hint| {
 7217                                                    (
 7218                                                        InlayId::Hint(next_hint_id.fetch_add(
 7219                                                            1,
 7220                                                            atomic::Ordering::AcqRel,
 7221                                                        )),
 7222                                                        new_hint,
 7223                                                    )
 7224                                                })
 7225                                                .collect::<Vec<_>>();
 7226                                            if update_cache {
 7227                                                lsp_data.inlay_hints.insert_new_hints(
 7228                                                    chunk,
 7229                                                    server_id,
 7230                                                    new_hints.clone(),
 7231                                                );
 7232                                            }
 7233                                            result.insert(server_id, new_hints);
 7234                                        }
 7235                                        result
 7236                                    }
 7237                                })
 7238                            })
 7239                            .map_err(Arc::new)
 7240                    })
 7241                    .shared();
 7242
 7243                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7244                *fetch_task = Some(new_inlay_hints.clone());
 7245                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7246            }
 7247
 7248            cached_inlay_hints
 7249                .unwrap_or_default()
 7250                .into_iter()
 7251                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7252                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7253                    (
 7254                        chunk.row_range(),
 7255                        cx.spawn(async move |_, _| {
 7256                            hints_fetch.await.map_err(|e| {
 7257                                if e.error_code() != ErrorCode::Internal {
 7258                                    anyhow!(e.error_code())
 7259                                } else {
 7260                                    anyhow!("{e:#}")
 7261                                }
 7262                            })
 7263                        }),
 7264                    )
 7265                }))
 7266                .collect()
 7267        }
 7268    }
 7269
 7270    fn fetch_inlay_hints(
 7271        &mut self,
 7272        for_server: Option<LanguageServerId>,
 7273        buffer: &Entity<Buffer>,
 7274        range: Range<Anchor>,
 7275        cx: &mut Context<Self>,
 7276    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7277        let request = InlayHints {
 7278            range: range.clone(),
 7279        };
 7280        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7281            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7282                return Task::ready(Ok(HashMap::default()));
 7283            }
 7284            let request_timeout = ProjectSettings::get_global(cx)
 7285                .global_lsp_settings
 7286                .get_request_timeout();
 7287            let request_task = upstream_client.request_lsp(
 7288                project_id,
 7289                for_server.map(|id| id.to_proto()),
 7290                request_timeout,
 7291                cx.background_executor().clone(),
 7292                request.to_proto(project_id, buffer.read(cx)),
 7293            );
 7294            let buffer = buffer.clone();
 7295            cx.spawn(async move |weak_lsp_store, cx| {
 7296                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7297                    return Ok(HashMap::default());
 7298                };
 7299                let Some(responses) = request_task.await? else {
 7300                    return Ok(HashMap::default());
 7301                };
 7302
 7303                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7304                    let lsp_store = lsp_store.clone();
 7305                    let buffer = buffer.clone();
 7306                    let cx = cx.clone();
 7307                    let request = request.clone();
 7308                    async move {
 7309                        (
 7310                            LanguageServerId::from_proto(response.server_id),
 7311                            request
 7312                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7313                                .await,
 7314                        )
 7315                    }
 7316                }))
 7317                .await;
 7318
 7319                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7320                let mut has_errors = false;
 7321                let inlay_hints = inlay_hints
 7322                    .into_iter()
 7323                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7324                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7325                        Err(e) => {
 7326                            has_errors = true;
 7327                            log::error!("{e:#}");
 7328                            None
 7329                        }
 7330                    })
 7331                    .map(|(server_id, mut new_hints)| {
 7332                        new_hints.retain(|hint| {
 7333                            hint.position.is_valid(&buffer_snapshot)
 7334                                && range.start.is_valid(&buffer_snapshot)
 7335                                && range.end.is_valid(&buffer_snapshot)
 7336                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7337                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7338                        });
 7339                        (server_id, new_hints)
 7340                    })
 7341                    .collect::<HashMap<_, _>>();
 7342                anyhow::ensure!(
 7343                    !has_errors || !inlay_hints.is_empty(),
 7344                    "Failed to fetch inlay hints"
 7345                );
 7346                Ok(inlay_hints)
 7347            })
 7348        } else {
 7349            let inlay_hints_task = match for_server {
 7350                Some(server_id) => {
 7351                    let server_task = self.request_lsp(
 7352                        buffer.clone(),
 7353                        LanguageServerToQuery::Other(server_id),
 7354                        request,
 7355                        cx,
 7356                    );
 7357                    cx.background_spawn(async move {
 7358                        let mut responses = Vec::new();
 7359                        match server_task.await {
 7360                            Ok(response) => responses.push((server_id, response)),
 7361                            // rust-analyzer likes to error with this when its still loading up
 7362                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7363                            Err(e) => log::error!(
 7364                                "Error handling response for inlay hints request: {e:#}"
 7365                            ),
 7366                        }
 7367                        responses
 7368                    })
 7369                }
 7370                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7371            };
 7372            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7373            cx.background_spawn(async move {
 7374                Ok(inlay_hints_task
 7375                    .await
 7376                    .into_iter()
 7377                    .map(|(server_id, mut new_hints)| {
 7378                        new_hints.retain(|hint| {
 7379                            hint.position.is_valid(&buffer_snapshot)
 7380                                && range.start.is_valid(&buffer_snapshot)
 7381                                && range.end.is_valid(&buffer_snapshot)
 7382                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7383                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7384                        });
 7385                        (server_id, new_hints)
 7386                    })
 7387                    .collect())
 7388            })
 7389        }
 7390    }
 7391
 7392    fn diagnostic_registration_exists(
 7393        &self,
 7394        server_id: LanguageServerId,
 7395        registration_id: &Option<SharedString>,
 7396    ) -> bool {
 7397        let Some(local) = self.as_local() else {
 7398            return false;
 7399        };
 7400        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7401        else {
 7402            return false;
 7403        };
 7404        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7405        registrations.diagnostics.contains_key(&registration_key)
 7406    }
 7407
 7408    pub fn pull_diagnostics_for_buffer(
 7409        &mut self,
 7410        buffer: Entity<Buffer>,
 7411        cx: &mut Context<Self>,
 7412    ) -> Task<anyhow::Result<()>> {
 7413        let diagnostics = self.pull_diagnostics(buffer, cx);
 7414        cx.spawn(async move |lsp_store, cx| {
 7415            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7416                return Ok(());
 7417            };
 7418            lsp_store.update(cx, |lsp_store, cx| {
 7419                if lsp_store.as_local().is_none() {
 7420                    return;
 7421                }
 7422
 7423                let mut unchanged_buffers = HashMap::default();
 7424                let server_diagnostics_updates = diagnostics
 7425                    .into_iter()
 7426                    .filter_map(|diagnostics_set| match diagnostics_set {
 7427                        LspPullDiagnostics::Response {
 7428                            server_id,
 7429                            uri,
 7430                            diagnostics,
 7431                            registration_id,
 7432                        } => Some((server_id, uri, diagnostics, registration_id)),
 7433                        LspPullDiagnostics::Default => None,
 7434                    })
 7435                    .filter(|(server_id, _, _, registration_id)| {
 7436                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7437                    })
 7438                    .fold(
 7439                        HashMap::default(),
 7440                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7441                            let (result_id, diagnostics) = match diagnostics {
 7442                                PulledDiagnostics::Unchanged { result_id } => {
 7443                                    unchanged_buffers
 7444                                        .entry(new_registration_id.clone())
 7445                                        .or_insert_with(HashSet::default)
 7446                                        .insert(uri.clone());
 7447                                    (Some(result_id), Vec::new())
 7448                                }
 7449                                PulledDiagnostics::Changed {
 7450                                    result_id,
 7451                                    diagnostics,
 7452                                } => (result_id, diagnostics),
 7453                            };
 7454                            let disk_based_sources = Cow::Owned(
 7455                                lsp_store
 7456                                    .language_server_adapter_for_id(server_id)
 7457                                    .as_ref()
 7458                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7459                                    .unwrap_or(&[])
 7460                                    .to_vec(),
 7461                            );
 7462                            acc.entry(server_id)
 7463                                .or_insert_with(HashMap::default)
 7464                                .entry(new_registration_id.clone())
 7465                                .or_insert_with(Vec::new)
 7466                                .push(DocumentDiagnosticsUpdate {
 7467                                    server_id,
 7468                                    diagnostics: lsp::PublishDiagnosticsParams {
 7469                                        uri,
 7470                                        diagnostics,
 7471                                        version: None,
 7472                                    },
 7473                                    result_id: result_id.map(SharedString::new),
 7474                                    disk_based_sources,
 7475                                    registration_id: new_registration_id,
 7476                                });
 7477                            acc
 7478                        },
 7479                    );
 7480
 7481                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7482                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7483                        lsp_store
 7484                            .merge_lsp_diagnostics(
 7485                                DiagnosticSourceKind::Pulled,
 7486                                diagnostic_updates,
 7487                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7488                                    DiagnosticSourceKind::Pulled => {
 7489                                        old_diagnostic.registration_id != registration_id
 7490                                            || unchanged_buffers
 7491                                                .get(&old_diagnostic.registration_id)
 7492                                                .is_some_and(|unchanged_buffers| {
 7493                                                    unchanged_buffers.contains(&document_uri)
 7494                                                })
 7495                                    }
 7496                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7497                                        true
 7498                                    }
 7499                                },
 7500                                cx,
 7501                            )
 7502                            .log_err();
 7503                    }
 7504                }
 7505            })
 7506        })
 7507    }
 7508
 7509    pub fn signature_help<T: ToPointUtf16>(
 7510        &mut self,
 7511        buffer: &Entity<Buffer>,
 7512        position: T,
 7513        cx: &mut Context<Self>,
 7514    ) -> Task<Option<Vec<SignatureHelp>>> {
 7515        let position = position.to_point_utf16(buffer.read(cx));
 7516
 7517        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7518            let request = GetSignatureHelp { position };
 7519            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7520                return Task::ready(None);
 7521            }
 7522            let request_timeout = ProjectSettings::get_global(cx)
 7523                .global_lsp_settings
 7524                .get_request_timeout();
 7525            let request_task = client.request_lsp(
 7526                upstream_project_id,
 7527                None,
 7528                request_timeout,
 7529                cx.background_executor().clone(),
 7530                request.to_proto(upstream_project_id, buffer.read(cx)),
 7531            );
 7532            let buffer = buffer.clone();
 7533            cx.spawn(async move |weak_lsp_store, cx| {
 7534                let lsp_store = weak_lsp_store.upgrade()?;
 7535                let signatures = join_all(
 7536                    request_task
 7537                        .await
 7538                        .log_err()
 7539                        .flatten()
 7540                        .map(|response| response.payload)
 7541                        .unwrap_or_default()
 7542                        .into_iter()
 7543                        .map(|response| {
 7544                            let response = GetSignatureHelp { position }.response_from_proto(
 7545                                response.response,
 7546                                lsp_store.clone(),
 7547                                buffer.clone(),
 7548                                cx.clone(),
 7549                            );
 7550                            async move { response.await.log_err().flatten() }
 7551                        }),
 7552                )
 7553                .await
 7554                .into_iter()
 7555                .flatten()
 7556                .collect();
 7557                Some(signatures)
 7558            })
 7559        } else {
 7560            let all_actions_task = self.request_multiple_lsp_locally(
 7561                buffer,
 7562                Some(position),
 7563                GetSignatureHelp { position },
 7564                cx,
 7565            );
 7566            cx.background_spawn(async move {
 7567                Some(
 7568                    all_actions_task
 7569                        .await
 7570                        .into_iter()
 7571                        .flat_map(|(_, actions)| actions)
 7572                        .collect::<Vec<_>>(),
 7573                )
 7574            })
 7575        }
 7576    }
 7577
 7578    pub fn hover(
 7579        &mut self,
 7580        buffer: &Entity<Buffer>,
 7581        position: PointUtf16,
 7582        cx: &mut Context<Self>,
 7583    ) -> Task<Option<Vec<Hover>>> {
 7584        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7585            let request = GetHover { position };
 7586            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7587                return Task::ready(None);
 7588            }
 7589            let request_timeout = ProjectSettings::get_global(cx)
 7590                .global_lsp_settings
 7591                .get_request_timeout();
 7592            let request_task = client.request_lsp(
 7593                upstream_project_id,
 7594                None,
 7595                request_timeout,
 7596                cx.background_executor().clone(),
 7597                request.to_proto(upstream_project_id, buffer.read(cx)),
 7598            );
 7599            let buffer = buffer.clone();
 7600            cx.spawn(async move |weak_lsp_store, cx| {
 7601                let lsp_store = weak_lsp_store.upgrade()?;
 7602                let hovers = join_all(
 7603                    request_task
 7604                        .await
 7605                        .log_err()
 7606                        .flatten()
 7607                        .map(|response| response.payload)
 7608                        .unwrap_or_default()
 7609                        .into_iter()
 7610                        .map(|response| {
 7611                            let response = GetHover { position }.response_from_proto(
 7612                                response.response,
 7613                                lsp_store.clone(),
 7614                                buffer.clone(),
 7615                                cx.clone(),
 7616                            );
 7617                            async move {
 7618                                response
 7619                                    .await
 7620                                    .log_err()
 7621                                    .flatten()
 7622                                    .and_then(remove_empty_hover_blocks)
 7623                            }
 7624                        }),
 7625                )
 7626                .await
 7627                .into_iter()
 7628                .flatten()
 7629                .collect();
 7630                Some(hovers)
 7631            })
 7632        } else {
 7633            let all_actions_task = self.request_multiple_lsp_locally(
 7634                buffer,
 7635                Some(position),
 7636                GetHover { position },
 7637                cx,
 7638            );
 7639            cx.background_spawn(async move {
 7640                Some(
 7641                    all_actions_task
 7642                        .await
 7643                        .into_iter()
 7644                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7645                        .collect::<Vec<Hover>>(),
 7646                )
 7647            })
 7648        }
 7649    }
 7650
 7651    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7652        let language_registry = self.languages.clone();
 7653
 7654        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7655            let request = upstream_client.request(proto::GetProjectSymbols {
 7656                project_id: *project_id,
 7657                query: query.to_string(),
 7658            });
 7659            cx.foreground_executor().spawn(async move {
 7660                let response = request.await?;
 7661                let mut symbols = Vec::new();
 7662                let core_symbols = response
 7663                    .symbols
 7664                    .into_iter()
 7665                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7666                    .collect::<Vec<_>>();
 7667                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7668                    .await;
 7669                Ok(symbols)
 7670            })
 7671        } else if let Some(local) = self.as_local() {
 7672            struct WorkspaceSymbolsResult {
 7673                server_id: LanguageServerId,
 7674                lsp_adapter: Arc<CachedLspAdapter>,
 7675                worktree: WeakEntity<Worktree>,
 7676                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7677            }
 7678
 7679            let mut requests = Vec::new();
 7680            let mut requested_servers = BTreeSet::new();
 7681            let request_timeout = ProjectSettings::get_global(cx)
 7682                .global_lsp_settings
 7683                .get_request_timeout();
 7684
 7685            for (seed, state) in local.language_server_ids.iter() {
 7686                let Some(worktree_handle) = self
 7687                    .worktree_store
 7688                    .read(cx)
 7689                    .worktree_for_id(seed.worktree_id, cx)
 7690                else {
 7691                    continue;
 7692                };
 7693
 7694                let worktree = worktree_handle.read(cx);
 7695                if !worktree.is_visible() {
 7696                    continue;
 7697                }
 7698
 7699                if !requested_servers.insert(state.id) {
 7700                    continue;
 7701                }
 7702
 7703                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7704                    Some(LanguageServerState::Running {
 7705                        adapter, server, ..
 7706                    }) => (adapter.clone(), server),
 7707
 7708                    _ => continue,
 7709                };
 7710
 7711                let supports_workspace_symbol_request =
 7712                    match server.capabilities().workspace_symbol_provider {
 7713                        Some(OneOf::Left(supported)) => supported,
 7714                        Some(OneOf::Right(_)) => true,
 7715                        None => false,
 7716                    };
 7717
 7718                if !supports_workspace_symbol_request {
 7719                    continue;
 7720                }
 7721
 7722                let worktree_handle = worktree_handle.clone();
 7723                let server_id = server.server_id();
 7724                requests.push(
 7725                    server
 7726                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7727                            lsp::WorkspaceSymbolParams {
 7728                                query: query.to_string(),
 7729                                ..Default::default()
 7730                            },
 7731                            request_timeout,
 7732                        )
 7733                        .map(move |response| {
 7734                            let lsp_symbols = response
 7735                                .into_response()
 7736                                .context("workspace symbols request")
 7737                                .log_err()
 7738                                .flatten()
 7739                                .map(|symbol_response| match symbol_response {
 7740                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7741                                        flat_responses
 7742                                            .into_iter()
 7743                                            .map(|lsp_symbol| {
 7744                                                (
 7745                                                    lsp_symbol.name,
 7746                                                    lsp_symbol.kind,
 7747                                                    lsp_symbol.location,
 7748                                                    lsp_symbol.container_name,
 7749                                                )
 7750                                            })
 7751                                            .collect::<Vec<_>>()
 7752                                    }
 7753                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7754                                        nested_responses
 7755                                            .into_iter()
 7756                                            .filter_map(|lsp_symbol| {
 7757                                                let location = match lsp_symbol.location {
 7758                                                    OneOf::Left(location) => location,
 7759                                                    OneOf::Right(_) => {
 7760                                                        log::error!(
 7761                                                            "Unexpected: client capabilities \
 7762                                                            forbid symbol resolutions in \
 7763                                                            workspace.symbol.resolveSupport"
 7764                                                        );
 7765                                                        return None;
 7766                                                    }
 7767                                                };
 7768                                                Some((
 7769                                                    lsp_symbol.name,
 7770                                                    lsp_symbol.kind,
 7771                                                    location,
 7772                                                    lsp_symbol.container_name,
 7773                                                ))
 7774                                            })
 7775                                            .collect::<Vec<_>>()
 7776                                    }
 7777                                })
 7778                                .unwrap_or_default();
 7779
 7780                            WorkspaceSymbolsResult {
 7781                                server_id,
 7782                                lsp_adapter,
 7783                                worktree: worktree_handle.downgrade(),
 7784                                lsp_symbols,
 7785                            }
 7786                        }),
 7787                );
 7788            }
 7789
 7790            cx.spawn(async move |this, cx| {
 7791                let responses = futures::future::join_all(requests).await;
 7792                let this = match this.upgrade() {
 7793                    Some(this) => this,
 7794                    None => return Ok(Vec::new()),
 7795                };
 7796
 7797                let mut symbols = Vec::new();
 7798                for result in responses {
 7799                    let core_symbols = this.update(cx, |this, cx| {
 7800                        result
 7801                            .lsp_symbols
 7802                            .into_iter()
 7803                            .filter_map(
 7804                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7805                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7806                                    let source_worktree = result.worktree.upgrade()?;
 7807                                    let source_worktree_id = source_worktree.read(cx).id();
 7808
 7809                                    let path = if let Some((tree, rel_path)) =
 7810                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7811                                    {
 7812                                        let worktree_id = tree.read(cx).id();
 7813                                        SymbolLocation::InProject(ProjectPath {
 7814                                            worktree_id,
 7815                                            path: rel_path,
 7816                                        })
 7817                                    } else {
 7818                                        SymbolLocation::OutsideProject {
 7819                                            signature: this.symbol_signature(&abs_path),
 7820                                            abs_path: abs_path.into(),
 7821                                        }
 7822                                    };
 7823
 7824                                    Some(CoreSymbol {
 7825                                        source_language_server_id: result.server_id,
 7826                                        language_server_name: result.lsp_adapter.name.clone(),
 7827                                        source_worktree_id,
 7828                                        path,
 7829                                        kind: symbol_kind,
 7830                                        name: collapse_newlines(&symbol_name, ""),
 7831                                        range: range_from_lsp(symbol_location.range),
 7832                                        container_name: container_name
 7833                                            .map(|c| collapse_newlines(&c, "")),
 7834                                    })
 7835                                },
 7836                            )
 7837                            .collect::<Vec<_>>()
 7838                    });
 7839
 7840                    populate_labels_for_symbols(
 7841                        core_symbols,
 7842                        &language_registry,
 7843                        Some(result.lsp_adapter),
 7844                        &mut symbols,
 7845                    )
 7846                    .await;
 7847                }
 7848
 7849                Ok(symbols)
 7850            })
 7851        } else {
 7852            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7853        }
 7854    }
 7855
 7856    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7857        let mut summary = DiagnosticSummary::default();
 7858        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7859            summary.error_count += path_summary.error_count;
 7860            summary.warning_count += path_summary.warning_count;
 7861        }
 7862        summary
 7863    }
 7864
 7865    /// Returns the diagnostic summary for a specific project path.
 7866    pub fn diagnostic_summary_for_path(
 7867        &self,
 7868        project_path: &ProjectPath,
 7869        _: &App,
 7870    ) -> DiagnosticSummary {
 7871        if let Some(summaries) = self
 7872            .diagnostic_summaries
 7873            .get(&project_path.worktree_id)
 7874            .and_then(|map| map.get(&project_path.path))
 7875        {
 7876            let (error_count, warning_count) = summaries.iter().fold(
 7877                (0, 0),
 7878                |(error_count, warning_count), (_language_server_id, summary)| {
 7879                    (
 7880                        error_count + summary.error_count,
 7881                        warning_count + summary.warning_count,
 7882                    )
 7883                },
 7884            );
 7885
 7886            DiagnosticSummary {
 7887                error_count,
 7888                warning_count,
 7889            }
 7890        } else {
 7891            DiagnosticSummary::default()
 7892        }
 7893    }
 7894
 7895    pub fn diagnostic_summaries<'a>(
 7896        &'a self,
 7897        include_ignored: bool,
 7898        cx: &'a App,
 7899    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7900        self.worktree_store
 7901            .read(cx)
 7902            .visible_worktrees(cx)
 7903            .filter_map(|worktree| {
 7904                let worktree = worktree.read(cx);
 7905                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7906            })
 7907            .flat_map(move |(worktree, summaries)| {
 7908                let worktree_id = worktree.id();
 7909                summaries
 7910                    .iter()
 7911                    .filter(move |(path, _)| {
 7912                        include_ignored
 7913                            || worktree
 7914                                .entry_for_path(path.as_ref())
 7915                                .is_some_and(|entry| !entry.is_ignored)
 7916                    })
 7917                    .flat_map(move |(path, summaries)| {
 7918                        summaries.iter().map(move |(server_id, summary)| {
 7919                            (
 7920                                ProjectPath {
 7921                                    worktree_id,
 7922                                    path: path.clone(),
 7923                                },
 7924                                *server_id,
 7925                                *summary,
 7926                            )
 7927                        })
 7928                    })
 7929            })
 7930    }
 7931
 7932    pub fn on_buffer_edited(
 7933        &mut self,
 7934        buffer: Entity<Buffer>,
 7935        cx: &mut Context<Self>,
 7936    ) -> Option<()> {
 7937        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7938            Some(
 7939                self.as_local()?
 7940                    .language_servers_for_buffer(buffer, cx)
 7941                    .map(|i| i.1.clone())
 7942                    .collect(),
 7943            )
 7944        })?;
 7945
 7946        let buffer = buffer.read(cx);
 7947        let file = File::from_dyn(buffer.file())?;
 7948        let abs_path = file.as_local()?.abs_path(cx);
 7949        let uri = lsp::Uri::from_file_path(&abs_path)
 7950            .ok()
 7951            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7952            .log_err()?;
 7953        let next_snapshot = buffer.text_snapshot();
 7954        for language_server in language_servers {
 7955            let language_server = language_server.clone();
 7956
 7957            let buffer_snapshots = self
 7958                .as_local_mut()?
 7959                .buffer_snapshots
 7960                .get_mut(&buffer.remote_id())
 7961                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7962            let previous_snapshot = buffer_snapshots.last()?;
 7963
 7964            let build_incremental_change = || {
 7965                buffer
 7966                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7967                        previous_snapshot.snapshot.version(),
 7968                    )
 7969                    .map(|edit| {
 7970                        let edit_start = edit.new.start.0;
 7971                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7972                        let new_text = next_snapshot
 7973                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7974                            .collect();
 7975                        lsp::TextDocumentContentChangeEvent {
 7976                            range: Some(lsp::Range::new(
 7977                                point_to_lsp(edit_start),
 7978                                point_to_lsp(edit_end),
 7979                            )),
 7980                            range_length: None,
 7981                            text: new_text,
 7982                        }
 7983                    })
 7984                    .collect()
 7985            };
 7986
 7987            let document_sync_kind = language_server
 7988                .capabilities()
 7989                .text_document_sync
 7990                .as_ref()
 7991                .and_then(|sync| match sync {
 7992                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7993                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7994                });
 7995
 7996            let content_changes: Vec<_> = match document_sync_kind {
 7997                Some(lsp::TextDocumentSyncKind::FULL) => {
 7998                    vec![lsp::TextDocumentContentChangeEvent {
 7999                        range: None,
 8000                        range_length: None,
 8001                        text: next_snapshot.text(),
 8002                    }]
 8003                }
 8004                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8005                _ => {
 8006                    #[cfg(any(test, feature = "test-support"))]
 8007                    {
 8008                        build_incremental_change()
 8009                    }
 8010
 8011                    #[cfg(not(any(test, feature = "test-support")))]
 8012                    {
 8013                        continue;
 8014                    }
 8015                }
 8016            };
 8017
 8018            let next_version = previous_snapshot.version + 1;
 8019            buffer_snapshots.push(LspBufferSnapshot {
 8020                version: next_version,
 8021                snapshot: next_snapshot.clone(),
 8022            });
 8023
 8024            language_server
 8025                .notify::<lsp::notification::DidChangeTextDocument>(
 8026                    lsp::DidChangeTextDocumentParams {
 8027                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8028                            uri.clone(),
 8029                            next_version,
 8030                        ),
 8031                        content_changes,
 8032                    },
 8033                )
 8034                .ok();
 8035            self.pull_workspace_diagnostics(language_server.server_id());
 8036        }
 8037
 8038        None
 8039    }
 8040
 8041    pub fn on_buffer_saved(
 8042        &mut self,
 8043        buffer: Entity<Buffer>,
 8044        cx: &mut Context<Self>,
 8045    ) -> Option<()> {
 8046        let file = File::from_dyn(buffer.read(cx).file())?;
 8047        let worktree_id = file.worktree_id(cx);
 8048        let abs_path = file.as_local()?.abs_path(cx);
 8049        let text_document = lsp::TextDocumentIdentifier {
 8050            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8051        };
 8052        let local = self.as_local()?;
 8053
 8054        for server in local.language_servers_for_worktree(worktree_id) {
 8055            if let Some(include_text) = include_text(server.as_ref()) {
 8056                let text = if include_text {
 8057                    Some(buffer.read(cx).text())
 8058                } else {
 8059                    None
 8060                };
 8061                server
 8062                    .notify::<lsp::notification::DidSaveTextDocument>(
 8063                        lsp::DidSaveTextDocumentParams {
 8064                            text_document: text_document.clone(),
 8065                            text,
 8066                        },
 8067                    )
 8068                    .ok();
 8069            }
 8070        }
 8071
 8072        let language_servers = buffer.update(cx, |buffer, cx| {
 8073            local.language_server_ids_for_buffer(buffer, cx)
 8074        });
 8075        for language_server_id in language_servers {
 8076            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8077        }
 8078
 8079        None
 8080    }
 8081
 8082    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8083        maybe!(async move {
 8084            let mut refreshed_servers = HashSet::default();
 8085            let servers = lsp_store
 8086                .update(cx, |lsp_store, cx| {
 8087                    let local = lsp_store.as_local()?;
 8088
 8089                    let servers = local
 8090                        .language_server_ids
 8091                        .iter()
 8092                        .filter_map(|(seed, state)| {
 8093                            let worktree = lsp_store
 8094                                .worktree_store
 8095                                .read(cx)
 8096                                .worktree_for_id(seed.worktree_id, cx);
 8097                            let delegate: Arc<dyn LspAdapterDelegate> =
 8098                                worktree.map(|worktree| {
 8099                                    LocalLspAdapterDelegate::new(
 8100                                        local.languages.clone(),
 8101                                        &local.environment,
 8102                                        cx.weak_entity(),
 8103                                        &worktree,
 8104                                        local.http_client.clone(),
 8105                                        local.fs.clone(),
 8106                                        cx,
 8107                                    )
 8108                                })?;
 8109                            let server_id = state.id;
 8110
 8111                            let states = local.language_servers.get(&server_id)?;
 8112
 8113                            match states {
 8114                                LanguageServerState::Starting { .. } => None,
 8115                                LanguageServerState::Running {
 8116                                    adapter, server, ..
 8117                                } => {
 8118                                    let adapter = adapter.clone();
 8119                                    let server = server.clone();
 8120                                    refreshed_servers.insert(server.name());
 8121                                    let toolchain = seed.toolchain.clone();
 8122                                    Some(cx.spawn(async move |_, cx| {
 8123                                        let settings =
 8124                                            LocalLspStore::workspace_configuration_for_adapter(
 8125                                                adapter.adapter.clone(),
 8126                                                &delegate,
 8127                                                toolchain,
 8128                                                None,
 8129                                                cx,
 8130                                            )
 8131                                            .await
 8132                                            .ok()?;
 8133                                        server
 8134                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8135                                                lsp::DidChangeConfigurationParams { settings },
 8136                                            )
 8137                                            .ok()?;
 8138                                        Some(())
 8139                                    }))
 8140                                }
 8141                            }
 8142                        })
 8143                        .collect::<Vec<_>>();
 8144
 8145                    Some(servers)
 8146                })
 8147                .ok()
 8148                .flatten()?;
 8149
 8150            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8151            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8152            // to stop and unregister its language server wrapper.
 8153            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8154            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8155            let _: Vec<Option<()>> = join_all(servers).await;
 8156
 8157            Some(())
 8158        })
 8159        .await;
 8160    }
 8161
 8162    fn maintain_workspace_config(
 8163        external_refresh_requests: watch::Receiver<()>,
 8164        cx: &mut Context<Self>,
 8165    ) -> Task<Result<()>> {
 8166        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8167        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8168
 8169        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8170            *settings_changed_tx.borrow_mut() = ();
 8171        });
 8172
 8173        let mut joint_future =
 8174            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8175        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8176        // - 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).
 8177        // - 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.
 8178        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8179        // - 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,
 8180        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8181        cx.spawn(async move |this, cx| {
 8182            while let Some(()) = joint_future.next().await {
 8183                this.update(cx, |this, cx| {
 8184                    this.refresh_server_tree(cx);
 8185                })
 8186                .ok();
 8187
 8188                Self::refresh_workspace_configurations(&this, cx).await;
 8189            }
 8190
 8191            drop(settings_observation);
 8192            anyhow::Ok(())
 8193        })
 8194    }
 8195
 8196    pub fn running_language_servers_for_local_buffer<'a>(
 8197        &'a self,
 8198        buffer: &Buffer,
 8199        cx: &mut App,
 8200    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8201        let local = self.as_local();
 8202        let language_server_ids = local
 8203            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8204            .unwrap_or_default();
 8205
 8206        language_server_ids
 8207            .into_iter()
 8208            .filter_map(
 8209                move |server_id| match local?.language_servers.get(&server_id)? {
 8210                    LanguageServerState::Running {
 8211                        adapter, server, ..
 8212                    } => Some((adapter, server)),
 8213                    _ => None,
 8214                },
 8215            )
 8216    }
 8217
 8218    pub fn language_servers_for_local_buffer(
 8219        &self,
 8220        buffer: &Buffer,
 8221        cx: &mut App,
 8222    ) -> Vec<LanguageServerId> {
 8223        let local = self.as_local();
 8224        local
 8225            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8226            .unwrap_or_default()
 8227    }
 8228
 8229    pub fn language_server_for_local_buffer<'a>(
 8230        &'a self,
 8231        buffer: &'a Buffer,
 8232        server_id: LanguageServerId,
 8233        cx: &'a mut App,
 8234    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8235        self.as_local()?
 8236            .language_servers_for_buffer(buffer, cx)
 8237            .find(|(_, s)| s.server_id() == server_id)
 8238    }
 8239
 8240    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8241        self.diagnostic_summaries.remove(&id_to_remove);
 8242        if let Some(local) = self.as_local_mut() {
 8243            let to_remove = local.remove_worktree(id_to_remove, cx);
 8244            for server in to_remove {
 8245                self.language_server_statuses.remove(&server);
 8246            }
 8247        }
 8248    }
 8249
 8250    fn invalidate_diagnostic_summaries_for_removed_entries(
 8251        &mut self,
 8252        worktree_id: WorktreeId,
 8253        changes: &UpdatedEntriesSet,
 8254        cx: &mut Context<Self>,
 8255    ) {
 8256        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8257            return;
 8258        };
 8259
 8260        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8261        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8262        let downstream = self.downstream_client.clone();
 8263
 8264        for (path, _, _) in changes
 8265            .iter()
 8266            .filter(|(_, _, change)| *change == PathChange::Removed)
 8267        {
 8268            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8269                for (server_id, _) in &summaries_by_server_id {
 8270                    cleared_server_ids.insert(*server_id);
 8271                    if let Some((client, project_id)) = &downstream {
 8272                        client
 8273                            .send(proto::UpdateDiagnosticSummary {
 8274                                project_id: *project_id,
 8275                                worktree_id: worktree_id.to_proto(),
 8276                                summary: Some(proto::DiagnosticSummary {
 8277                                    path: path.as_ref().to_proto(),
 8278                                    language_server_id: server_id.0 as u64,
 8279                                    error_count: 0,
 8280                                    warning_count: 0,
 8281                                }),
 8282                                more_summaries: Vec::new(),
 8283                            })
 8284                            .ok();
 8285                    }
 8286                }
 8287                cleared_paths.push(ProjectPath {
 8288                    worktree_id,
 8289                    path: path.clone(),
 8290                });
 8291            }
 8292        }
 8293
 8294        if !cleared_paths.is_empty() {
 8295            for server_id in cleared_server_ids {
 8296                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8297                    server_id,
 8298                    paths: cleared_paths.clone(),
 8299                });
 8300            }
 8301        }
 8302    }
 8303
 8304    pub fn shared(
 8305        &mut self,
 8306        project_id: u64,
 8307        downstream_client: AnyProtoClient,
 8308        _: &mut Context<Self>,
 8309    ) {
 8310        self.downstream_client = Some((downstream_client.clone(), project_id));
 8311
 8312        for (server_id, status) in &self.language_server_statuses {
 8313            if let Some(server) = self.language_server_for_id(*server_id) {
 8314                downstream_client
 8315                    .send(proto::StartLanguageServer {
 8316                        project_id,
 8317                        server: Some(proto::LanguageServer {
 8318                            id: server_id.to_proto(),
 8319                            name: status.name.to_string(),
 8320                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8321                        }),
 8322                        capabilities: serde_json::to_string(&server.capabilities())
 8323                            .expect("serializing server LSP capabilities"),
 8324                    })
 8325                    .log_err();
 8326            }
 8327        }
 8328    }
 8329
 8330    pub fn disconnected_from_host(&mut self) {
 8331        self.downstream_client.take();
 8332    }
 8333
 8334    pub fn disconnected_from_ssh_remote(&mut self) {
 8335        if let LspStoreMode::Remote(RemoteLspStore {
 8336            upstream_client, ..
 8337        }) = &mut self.mode
 8338        {
 8339            upstream_client.take();
 8340        }
 8341    }
 8342
 8343    pub(crate) fn set_language_server_statuses_from_proto(
 8344        &mut self,
 8345        project: WeakEntity<Project>,
 8346        language_servers: Vec<proto::LanguageServer>,
 8347        server_capabilities: Vec<String>,
 8348        cx: &mut Context<Self>,
 8349    ) {
 8350        let lsp_logs = cx
 8351            .try_global::<GlobalLogStore>()
 8352            .map(|lsp_store| lsp_store.0.clone());
 8353
 8354        self.language_server_statuses = language_servers
 8355            .into_iter()
 8356            .zip(server_capabilities)
 8357            .map(|(server, server_capabilities)| {
 8358                let server_id = LanguageServerId(server.id as usize);
 8359                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8360                    self.lsp_server_capabilities
 8361                        .insert(server_id, server_capabilities);
 8362                }
 8363
 8364                let name = LanguageServerName::from_proto(server.name);
 8365                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8366
 8367                if let Some(lsp_logs) = &lsp_logs {
 8368                    lsp_logs.update(cx, |lsp_logs, cx| {
 8369                        lsp_logs.add_language_server(
 8370                            // Only remote clients get their language servers set from proto
 8371                            LanguageServerKind::Remote {
 8372                                project: project.clone(),
 8373                            },
 8374                            server_id,
 8375                            Some(name.clone()),
 8376                            worktree,
 8377                            None,
 8378                            cx,
 8379                        );
 8380                    });
 8381                }
 8382
 8383                (
 8384                    server_id,
 8385                    LanguageServerStatus {
 8386                        name,
 8387                        server_version: None,
 8388                        server_readable_version: None,
 8389                        pending_work: Default::default(),
 8390                        has_pending_diagnostic_updates: false,
 8391                        progress_tokens: Default::default(),
 8392                        worktree,
 8393                        binary: None,
 8394                        configuration: None,
 8395                        workspace_folders: BTreeSet::new(),
 8396                        process_id: None,
 8397                    },
 8398                )
 8399            })
 8400            .collect();
 8401    }
 8402
 8403    #[cfg(feature = "test-support")]
 8404    pub fn update_diagnostic_entries(
 8405        &mut self,
 8406        server_id: LanguageServerId,
 8407        abs_path: PathBuf,
 8408        result_id: Option<SharedString>,
 8409        version: Option<i32>,
 8410        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8411        cx: &mut Context<Self>,
 8412    ) -> anyhow::Result<()> {
 8413        self.merge_diagnostic_entries(
 8414            vec![DocumentDiagnosticsUpdate {
 8415                diagnostics: DocumentDiagnostics {
 8416                    diagnostics,
 8417                    document_abs_path: abs_path,
 8418                    version,
 8419                },
 8420                result_id,
 8421                server_id,
 8422                disk_based_sources: Cow::Borrowed(&[]),
 8423                registration_id: None,
 8424            }],
 8425            |_, _, _| false,
 8426            cx,
 8427        )?;
 8428        Ok(())
 8429    }
 8430
 8431    pub fn merge_diagnostic_entries<'a>(
 8432        &mut self,
 8433        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8434        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8435        cx: &mut Context<Self>,
 8436    ) -> anyhow::Result<()> {
 8437        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8438        let mut updated_diagnostics_paths = HashMap::default();
 8439        for mut update in diagnostic_updates {
 8440            let abs_path = &update.diagnostics.document_abs_path;
 8441            let server_id = update.server_id;
 8442            let Some((worktree, relative_path)) =
 8443                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8444            else {
 8445                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8446                return Ok(());
 8447            };
 8448
 8449            let worktree_id = worktree.read(cx).id();
 8450            let project_path = ProjectPath {
 8451                worktree_id,
 8452                path: relative_path,
 8453            };
 8454
 8455            let document_uri = lsp::Uri::from_file_path(abs_path)
 8456                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8457            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8458                let snapshot = buffer_handle.read(cx).snapshot();
 8459                let buffer = buffer_handle.read(cx);
 8460                let reused_diagnostics = buffer
 8461                    .buffer_diagnostics(Some(server_id))
 8462                    .iter()
 8463                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8464                    .map(|v| {
 8465                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8466                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8467                        DiagnosticEntry {
 8468                            range: start..end,
 8469                            diagnostic: v.diagnostic.clone(),
 8470                        }
 8471                    })
 8472                    .collect::<Vec<_>>();
 8473
 8474                self.as_local_mut()
 8475                    .context("cannot merge diagnostics on a remote LspStore")?
 8476                    .update_buffer_diagnostics(
 8477                        &buffer_handle,
 8478                        server_id,
 8479                        Some(update.registration_id),
 8480                        update.result_id,
 8481                        update.diagnostics.version,
 8482                        update.diagnostics.diagnostics.clone(),
 8483                        reused_diagnostics.clone(),
 8484                        cx,
 8485                    )?;
 8486
 8487                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8488            } else if let Some(local) = self.as_local() {
 8489                let reused_diagnostics = local
 8490                    .diagnostics
 8491                    .get(&worktree_id)
 8492                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8493                    .and_then(|diagnostics_by_server_id| {
 8494                        diagnostics_by_server_id
 8495                            .binary_search_by_key(&server_id, |e| e.0)
 8496                            .ok()
 8497                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8498                    })
 8499                    .into_iter()
 8500                    .flatten()
 8501                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8502
 8503                update
 8504                    .diagnostics
 8505                    .diagnostics
 8506                    .extend(reused_diagnostics.cloned());
 8507            }
 8508
 8509            let updated = worktree.update(cx, |worktree, cx| {
 8510                self.update_worktree_diagnostics(
 8511                    worktree.id(),
 8512                    server_id,
 8513                    project_path.path.clone(),
 8514                    update.diagnostics.diagnostics,
 8515                    cx,
 8516                )
 8517            })?;
 8518            match updated {
 8519                ControlFlow::Continue(new_summary) => {
 8520                    if let Some((project_id, new_summary)) = new_summary {
 8521                        match &mut diagnostics_summary {
 8522                            Some(diagnostics_summary) => {
 8523                                diagnostics_summary
 8524                                    .more_summaries
 8525                                    .push(proto::DiagnosticSummary {
 8526                                        path: project_path.path.as_ref().to_proto(),
 8527                                        language_server_id: server_id.0 as u64,
 8528                                        error_count: new_summary.error_count,
 8529                                        warning_count: new_summary.warning_count,
 8530                                    })
 8531                            }
 8532                            None => {
 8533                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8534                                    project_id,
 8535                                    worktree_id: worktree_id.to_proto(),
 8536                                    summary: Some(proto::DiagnosticSummary {
 8537                                        path: project_path.path.as_ref().to_proto(),
 8538                                        language_server_id: server_id.0 as u64,
 8539                                        error_count: new_summary.error_count,
 8540                                        warning_count: new_summary.warning_count,
 8541                                    }),
 8542                                    more_summaries: Vec::new(),
 8543                                })
 8544                            }
 8545                        }
 8546                    }
 8547                    updated_diagnostics_paths
 8548                        .entry(server_id)
 8549                        .or_insert_with(Vec::new)
 8550                        .push(project_path);
 8551                }
 8552                ControlFlow::Break(()) => {}
 8553            }
 8554        }
 8555
 8556        if let Some((diagnostics_summary, (downstream_client, _))) =
 8557            diagnostics_summary.zip(self.downstream_client.as_ref())
 8558        {
 8559            downstream_client.send(diagnostics_summary).log_err();
 8560        }
 8561        for (server_id, paths) in updated_diagnostics_paths {
 8562            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8563        }
 8564        Ok(())
 8565    }
 8566
 8567    fn update_worktree_diagnostics(
 8568        &mut self,
 8569        worktree_id: WorktreeId,
 8570        server_id: LanguageServerId,
 8571        path_in_worktree: Arc<RelPath>,
 8572        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8573        _: &mut Context<Worktree>,
 8574    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8575        let local = match &mut self.mode {
 8576            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8577            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8578        };
 8579
 8580        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8581        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8582        let summaries_by_server_id = summaries_for_tree
 8583            .entry(path_in_worktree.clone())
 8584            .or_default();
 8585
 8586        let old_summary = summaries_by_server_id
 8587            .remove(&server_id)
 8588            .unwrap_or_default();
 8589
 8590        let new_summary = DiagnosticSummary::new(&diagnostics);
 8591        if diagnostics.is_empty() {
 8592            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8593            {
 8594                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8595                    diagnostics_by_server_id.remove(ix);
 8596                }
 8597                if diagnostics_by_server_id.is_empty() {
 8598                    diagnostics_for_tree.remove(&path_in_worktree);
 8599                }
 8600            }
 8601        } else {
 8602            summaries_by_server_id.insert(server_id, new_summary);
 8603            let diagnostics_by_server_id = diagnostics_for_tree
 8604                .entry(path_in_worktree.clone())
 8605                .or_default();
 8606            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8607                Ok(ix) => {
 8608                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8609                }
 8610                Err(ix) => {
 8611                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8612                }
 8613            }
 8614        }
 8615
 8616        if !old_summary.is_empty() || !new_summary.is_empty() {
 8617            if let Some((_, project_id)) = &self.downstream_client {
 8618                Ok(ControlFlow::Continue(Some((
 8619                    *project_id,
 8620                    proto::DiagnosticSummary {
 8621                        path: path_in_worktree.to_proto(),
 8622                        language_server_id: server_id.0 as u64,
 8623                        error_count: new_summary.error_count as u32,
 8624                        warning_count: new_summary.warning_count as u32,
 8625                    },
 8626                ))))
 8627            } else {
 8628                Ok(ControlFlow::Continue(None))
 8629            }
 8630        } else {
 8631            Ok(ControlFlow::Break(()))
 8632        }
 8633    }
 8634
 8635    pub fn open_buffer_for_symbol(
 8636        &mut self,
 8637        symbol: &Symbol,
 8638        cx: &mut Context<Self>,
 8639    ) -> Task<Result<Entity<Buffer>>> {
 8640        if let Some((client, project_id)) = self.upstream_client() {
 8641            let request = client.request(proto::OpenBufferForSymbol {
 8642                project_id,
 8643                symbol: Some(Self::serialize_symbol(symbol)),
 8644            });
 8645            cx.spawn(async move |this, cx| {
 8646                let response = request.await?;
 8647                let buffer_id = BufferId::new(response.buffer_id)?;
 8648                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8649                    .await
 8650            })
 8651        } else if let Some(local) = self.as_local() {
 8652            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8653                seed.worktree_id == symbol.source_worktree_id
 8654                    && state.id == symbol.source_language_server_id
 8655                    && symbol.language_server_name == seed.name
 8656            });
 8657            if !is_valid {
 8658                return Task::ready(Err(anyhow!(
 8659                    "language server for worktree and language not found"
 8660                )));
 8661            };
 8662
 8663            let symbol_abs_path = match &symbol.path {
 8664                SymbolLocation::InProject(project_path) => self
 8665                    .worktree_store
 8666                    .read(cx)
 8667                    .absolutize(&project_path, cx)
 8668                    .context("no such worktree"),
 8669                SymbolLocation::OutsideProject {
 8670                    abs_path,
 8671                    signature: _,
 8672                } => Ok(abs_path.to_path_buf()),
 8673            };
 8674            let symbol_abs_path = match symbol_abs_path {
 8675                Ok(abs_path) => abs_path,
 8676                Err(err) => return Task::ready(Err(err)),
 8677            };
 8678            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8679                uri
 8680            } else {
 8681                return Task::ready(Err(anyhow!("invalid symbol path")));
 8682            };
 8683
 8684            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8685        } else {
 8686            Task::ready(Err(anyhow!("no upstream client or local store")))
 8687        }
 8688    }
 8689
 8690    pub(crate) fn open_local_buffer_via_lsp(
 8691        &mut self,
 8692        abs_path: lsp::Uri,
 8693        language_server_id: LanguageServerId,
 8694        cx: &mut Context<Self>,
 8695    ) -> Task<Result<Entity<Buffer>>> {
 8696        let path_style = self.worktree_store.read(cx).path_style();
 8697        cx.spawn(async move |lsp_store, cx| {
 8698            // Escape percent-encoded string.
 8699            let current_scheme = abs_path.scheme().to_owned();
 8700            // Uri is immutable, so we can't modify the scheme
 8701
 8702            let abs_path = abs_path
 8703                .to_file_path_ext(path_style)
 8704                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8705            let p = abs_path.clone();
 8706            let yarn_worktree = lsp_store
 8707                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8708                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8709                        cx.spawn(async move |this, cx| {
 8710                            let t = this
 8711                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8712                                .ok()?;
 8713                            t.await
 8714                        })
 8715                    }),
 8716                    None => Task::ready(None),
 8717                })?
 8718                .await;
 8719            let (worktree_root_target, known_relative_path) =
 8720                if let Some((zip_root, relative_path)) = yarn_worktree {
 8721                    (zip_root, Some(relative_path))
 8722                } else {
 8723                    (Arc::<Path>::from(abs_path.as_path()), None)
 8724                };
 8725            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8726                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8727                    worktree_store.find_worktree(&worktree_root_target, cx)
 8728                })
 8729            })?;
 8730            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8731                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8732                (result.0, relative_path, None)
 8733            } else {
 8734                let worktree = lsp_store
 8735                    .update(cx, |lsp_store, cx| {
 8736                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8737                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8738                        })
 8739                    })?
 8740                    .await?;
 8741                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8742                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8743                    lsp_store
 8744                        .update(cx, |lsp_store, cx| {
 8745                            if let Some(local) = lsp_store.as_local_mut() {
 8746                                local.register_language_server_for_invisible_worktree(
 8747                                    &worktree,
 8748                                    language_server_id,
 8749                                    cx,
 8750                                )
 8751                            }
 8752                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8753                                Some(status) => status.worktree,
 8754                                None => None,
 8755                            }
 8756                        })
 8757                        .ok()
 8758                        .flatten()
 8759                        .zip(Some(worktree_root.clone()))
 8760                } else {
 8761                    None
 8762                };
 8763                let relative_path = if let Some(known_path) = known_relative_path {
 8764                    known_path
 8765                } else {
 8766                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8767                        .into_arc()
 8768                };
 8769                (worktree, relative_path, source_ws)
 8770            };
 8771            let project_path = ProjectPath {
 8772                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8773                path: relative_path,
 8774            };
 8775            let buffer = lsp_store
 8776                .update(cx, |lsp_store, cx| {
 8777                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8778                        buffer_store.open_buffer(project_path, cx)
 8779                    })
 8780                })?
 8781                .await?;
 8782            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8783            if let Some((source_ws, worktree_root)) = source_ws {
 8784                buffer.update(cx, |buffer, cx| {
 8785                    let settings = WorktreeSettings::get(
 8786                        Some(
 8787                            (&ProjectPath {
 8788                                worktree_id: source_ws,
 8789                                path: Arc::from(RelPath::empty()),
 8790                            })
 8791                                .into(),
 8792                        ),
 8793                        cx,
 8794                    );
 8795                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8796                    if is_read_only {
 8797                        buffer.set_capability(Capability::ReadOnly, cx);
 8798                    }
 8799                });
 8800            }
 8801            Ok(buffer)
 8802        })
 8803    }
 8804
 8805    fn local_lsp_servers_for_buffer(
 8806        &self,
 8807        buffer: &Entity<Buffer>,
 8808        cx: &mut Context<Self>,
 8809    ) -> Vec<LanguageServerId> {
 8810        let Some(local) = self.as_local() else {
 8811            return Vec::new();
 8812        };
 8813
 8814        let snapshot = buffer.read(cx).snapshot();
 8815
 8816        buffer.update(cx, |buffer, cx| {
 8817            local
 8818                .language_servers_for_buffer(buffer, cx)
 8819                .map(|(_, server)| server.server_id())
 8820                .filter(|server_id| {
 8821                    self.as_local().is_none_or(|local| {
 8822                        local
 8823                            .buffers_opened_in_servers
 8824                            .get(&snapshot.remote_id())
 8825                            .is_some_and(|servers| servers.contains(server_id))
 8826                    })
 8827                })
 8828                .collect()
 8829        })
 8830    }
 8831
 8832    fn request_multiple_lsp_locally<P, R>(
 8833        &mut self,
 8834        buffer: &Entity<Buffer>,
 8835        position: Option<P>,
 8836        request: R,
 8837        cx: &mut Context<Self>,
 8838    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8839    where
 8840        P: ToOffset,
 8841        R: LspCommand + Clone,
 8842        <R::LspRequest as lsp::request::Request>::Result: Send,
 8843        <R::LspRequest as lsp::request::Request>::Params: Send,
 8844    {
 8845        let Some(local) = self.as_local() else {
 8846            return Task::ready(Vec::new());
 8847        };
 8848
 8849        let snapshot = buffer.read(cx).snapshot();
 8850        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8851
 8852        let server_ids = buffer.update(cx, |buffer, cx| {
 8853            local
 8854                .language_servers_for_buffer(buffer, cx)
 8855                .filter(|(adapter, _)| {
 8856                    scope
 8857                        .as_ref()
 8858                        .map(|scope| scope.language_allowed(&adapter.name))
 8859                        .unwrap_or(true)
 8860                })
 8861                .map(|(_, server)| server.server_id())
 8862                .filter(|server_id| {
 8863                    self.as_local().is_none_or(|local| {
 8864                        local
 8865                            .buffers_opened_in_servers
 8866                            .get(&snapshot.remote_id())
 8867                            .is_some_and(|servers| servers.contains(server_id))
 8868                    })
 8869                })
 8870                .collect::<Vec<_>>()
 8871        });
 8872
 8873        let mut response_results = server_ids
 8874            .into_iter()
 8875            .map(|server_id| {
 8876                let task = self.request_lsp(
 8877                    buffer.clone(),
 8878                    LanguageServerToQuery::Other(server_id),
 8879                    request.clone(),
 8880                    cx,
 8881                );
 8882                async move { (server_id, task.await) }
 8883            })
 8884            .collect::<FuturesUnordered<_>>();
 8885
 8886        cx.background_spawn(async move {
 8887            let mut responses = Vec::with_capacity(response_results.len());
 8888            while let Some((server_id, response_result)) = response_results.next().await {
 8889                match response_result {
 8890                    Ok(response) => responses.push((server_id, response)),
 8891                    // rust-analyzer likes to error with this when its still loading up
 8892                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8893                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8894                }
 8895            }
 8896            responses
 8897        })
 8898    }
 8899
 8900    async fn handle_lsp_get_completions(
 8901        this: Entity<Self>,
 8902        envelope: TypedEnvelope<proto::GetCompletions>,
 8903        mut cx: AsyncApp,
 8904    ) -> Result<proto::GetCompletionsResponse> {
 8905        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8906
 8907        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8908        let buffer_handle = this.update(&mut cx, |this, cx| {
 8909            this.buffer_store.read(cx).get_existing(buffer_id)
 8910        })?;
 8911        let request = GetCompletions::from_proto(
 8912            envelope.payload,
 8913            this.clone(),
 8914            buffer_handle.clone(),
 8915            cx.clone(),
 8916        )
 8917        .await?;
 8918
 8919        let server_to_query = match request.server_id {
 8920            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8921            None => LanguageServerToQuery::FirstCapable,
 8922        };
 8923
 8924        let response = this
 8925            .update(&mut cx, |this, cx| {
 8926                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8927            })
 8928            .await?;
 8929        this.update(&mut cx, |this, cx| {
 8930            Ok(GetCompletions::response_to_proto(
 8931                response,
 8932                this,
 8933                sender_id,
 8934                &buffer_handle.read(cx).version(),
 8935                cx,
 8936            ))
 8937        })
 8938    }
 8939
 8940    async fn handle_lsp_command<T: LspCommand>(
 8941        this: Entity<Self>,
 8942        envelope: TypedEnvelope<T::ProtoRequest>,
 8943        mut cx: AsyncApp,
 8944    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8945    where
 8946        <T::LspRequest as lsp::request::Request>::Params: Send,
 8947        <T::LspRequest as lsp::request::Request>::Result: Send,
 8948    {
 8949        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8950        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8951        let buffer_handle = this.update(&mut cx, |this, cx| {
 8952            this.buffer_store.read(cx).get_existing(buffer_id)
 8953        })?;
 8954        let request = T::from_proto(
 8955            envelope.payload,
 8956            this.clone(),
 8957            buffer_handle.clone(),
 8958            cx.clone(),
 8959        )
 8960        .await?;
 8961        let response = this
 8962            .update(&mut cx, |this, cx| {
 8963                this.request_lsp(
 8964                    buffer_handle.clone(),
 8965                    LanguageServerToQuery::FirstCapable,
 8966                    request,
 8967                    cx,
 8968                )
 8969            })
 8970            .await?;
 8971        this.update(&mut cx, |this, cx| {
 8972            Ok(T::response_to_proto(
 8973                response,
 8974                this,
 8975                sender_id,
 8976                &buffer_handle.read(cx).version(),
 8977                cx,
 8978            ))
 8979        })
 8980    }
 8981
 8982    async fn handle_lsp_query(
 8983        lsp_store: Entity<Self>,
 8984        envelope: TypedEnvelope<proto::LspQuery>,
 8985        mut cx: AsyncApp,
 8986    ) -> Result<proto::Ack> {
 8987        use proto::lsp_query::Request;
 8988        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8989        let lsp_query = envelope.payload;
 8990        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8991        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8992        match lsp_query.request.context("invalid LSP query request")? {
 8993            Request::GetReferences(get_references) => {
 8994                let position = get_references.position.clone().and_then(deserialize_anchor);
 8995                Self::query_lsp_locally::<GetReferences>(
 8996                    lsp_store,
 8997                    server_id,
 8998                    sender_id,
 8999                    lsp_request_id,
 9000                    get_references,
 9001                    position,
 9002                    &mut cx,
 9003                )
 9004                .await?;
 9005            }
 9006            Request::GetDocumentColor(get_document_color) => {
 9007                Self::query_lsp_locally::<GetDocumentColor>(
 9008                    lsp_store,
 9009                    server_id,
 9010                    sender_id,
 9011                    lsp_request_id,
 9012                    get_document_color,
 9013                    None,
 9014                    &mut cx,
 9015                )
 9016                .await?;
 9017            }
 9018            Request::GetFoldingRanges(get_folding_ranges) => {
 9019                Self::query_lsp_locally::<GetFoldingRanges>(
 9020                    lsp_store,
 9021                    server_id,
 9022                    sender_id,
 9023                    lsp_request_id,
 9024                    get_folding_ranges,
 9025                    None,
 9026                    &mut cx,
 9027                )
 9028                .await?;
 9029            }
 9030            Request::GetDocumentSymbols(get_document_symbols) => {
 9031                Self::query_lsp_locally::<GetDocumentSymbols>(
 9032                    lsp_store,
 9033                    server_id,
 9034                    sender_id,
 9035                    lsp_request_id,
 9036                    get_document_symbols,
 9037                    None,
 9038                    &mut cx,
 9039                )
 9040                .await?;
 9041            }
 9042            Request::GetHover(get_hover) => {
 9043                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9044                Self::query_lsp_locally::<GetHover>(
 9045                    lsp_store,
 9046                    server_id,
 9047                    sender_id,
 9048                    lsp_request_id,
 9049                    get_hover,
 9050                    position,
 9051                    &mut cx,
 9052                )
 9053                .await?;
 9054            }
 9055            Request::GetCodeActions(get_code_actions) => {
 9056                Self::query_lsp_locally::<GetCodeActions>(
 9057                    lsp_store,
 9058                    server_id,
 9059                    sender_id,
 9060                    lsp_request_id,
 9061                    get_code_actions,
 9062                    None,
 9063                    &mut cx,
 9064                )
 9065                .await?;
 9066            }
 9067            Request::GetSignatureHelp(get_signature_help) => {
 9068                let position = get_signature_help
 9069                    .position
 9070                    .clone()
 9071                    .and_then(deserialize_anchor);
 9072                Self::query_lsp_locally::<GetSignatureHelp>(
 9073                    lsp_store,
 9074                    server_id,
 9075                    sender_id,
 9076                    lsp_request_id,
 9077                    get_signature_help,
 9078                    position,
 9079                    &mut cx,
 9080                )
 9081                .await?;
 9082            }
 9083            Request::GetCodeLens(get_code_lens) => {
 9084                Self::query_lsp_locally::<GetCodeLens>(
 9085                    lsp_store,
 9086                    server_id,
 9087                    sender_id,
 9088                    lsp_request_id,
 9089                    get_code_lens,
 9090                    None,
 9091                    &mut cx,
 9092                )
 9093                .await?;
 9094            }
 9095            Request::GetDefinition(get_definition) => {
 9096                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9097                Self::query_lsp_locally::<GetDefinitions>(
 9098                    lsp_store,
 9099                    server_id,
 9100                    sender_id,
 9101                    lsp_request_id,
 9102                    get_definition,
 9103                    position,
 9104                    &mut cx,
 9105                )
 9106                .await?;
 9107            }
 9108            Request::GetDeclaration(get_declaration) => {
 9109                let position = get_declaration
 9110                    .position
 9111                    .clone()
 9112                    .and_then(deserialize_anchor);
 9113                Self::query_lsp_locally::<GetDeclarations>(
 9114                    lsp_store,
 9115                    server_id,
 9116                    sender_id,
 9117                    lsp_request_id,
 9118                    get_declaration,
 9119                    position,
 9120                    &mut cx,
 9121                )
 9122                .await?;
 9123            }
 9124            Request::GetTypeDefinition(get_type_definition) => {
 9125                let position = get_type_definition
 9126                    .position
 9127                    .clone()
 9128                    .and_then(deserialize_anchor);
 9129                Self::query_lsp_locally::<GetTypeDefinitions>(
 9130                    lsp_store,
 9131                    server_id,
 9132                    sender_id,
 9133                    lsp_request_id,
 9134                    get_type_definition,
 9135                    position,
 9136                    &mut cx,
 9137                )
 9138                .await?;
 9139            }
 9140            Request::GetImplementation(get_implementation) => {
 9141                let position = get_implementation
 9142                    .position
 9143                    .clone()
 9144                    .and_then(deserialize_anchor);
 9145                Self::query_lsp_locally::<GetImplementations>(
 9146                    lsp_store,
 9147                    server_id,
 9148                    sender_id,
 9149                    lsp_request_id,
 9150                    get_implementation,
 9151                    position,
 9152                    &mut cx,
 9153                )
 9154                .await?;
 9155            }
 9156            Request::InlayHints(inlay_hints) => {
 9157                let query_start = inlay_hints
 9158                    .start
 9159                    .clone()
 9160                    .and_then(deserialize_anchor)
 9161                    .context("invalid inlay hints range start")?;
 9162                let query_end = inlay_hints
 9163                    .end
 9164                    .clone()
 9165                    .and_then(deserialize_anchor)
 9166                    .context("invalid inlay hints range end")?;
 9167                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9168                    &lsp_store,
 9169                    server_id,
 9170                    lsp_request_id,
 9171                    &inlay_hints,
 9172                    query_start..query_end,
 9173                    &mut cx,
 9174                )
 9175                .await
 9176                .context("preparing inlay hints request")?;
 9177                Self::query_lsp_locally::<InlayHints>(
 9178                    lsp_store,
 9179                    server_id,
 9180                    sender_id,
 9181                    lsp_request_id,
 9182                    inlay_hints,
 9183                    None,
 9184                    &mut cx,
 9185                )
 9186                .await
 9187                .context("querying for inlay hints")?
 9188            }
 9189            //////////////////////////////
 9190            // Below are LSP queries that need to fetch more data,
 9191            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9192            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9193                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9194                    &lsp_store,
 9195                    &get_document_diagnostics,
 9196                    &mut cx,
 9197                )
 9198                .await?;
 9199                lsp_store.update(&mut cx, |lsp_store, cx| {
 9200                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9201                    let key = LspKey {
 9202                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9203                        server_queried: server_id,
 9204                    };
 9205                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9206                    ) {
 9207                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9208                            lsp_requests.clear();
 9209                        };
 9210                    }
 9211
 9212                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9213                        lsp_request_id,
 9214                        cx.spawn(async move |lsp_store, cx| {
 9215                            let diagnostics_pull = lsp_store
 9216                                .update(cx, |lsp_store, cx| {
 9217                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9218                                })
 9219                                .ok();
 9220                            if let Some(diagnostics_pull) = diagnostics_pull {
 9221                                match diagnostics_pull.await {
 9222                                    Ok(()) => {}
 9223                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9224                                };
 9225                            }
 9226                        }),
 9227                    );
 9228                });
 9229            }
 9230            Request::SemanticTokens(semantic_tokens) => {
 9231                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9232                    &lsp_store,
 9233                    &semantic_tokens,
 9234                    &mut cx,
 9235                )
 9236                .await?;
 9237                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9238                lsp_store.update(&mut cx, |lsp_store, cx| {
 9239                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9240                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9241                        let key = LspKey {
 9242                            request_type: TypeId::of::<SemanticTokensFull>(),
 9243                            server_queried: server_id,
 9244                        };
 9245                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9246                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9247                                lsp_requests.clear();
 9248                            };
 9249                        }
 9250
 9251                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9252                            lsp_request_id,
 9253                            cx.spawn(async move |lsp_store, cx| {
 9254                                let tokens_fetch = lsp_store
 9255                                    .update(cx, |lsp_store, cx| {
 9256                                        lsp_store
 9257                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9258                                    })
 9259                                    .ok();
 9260                                if let Some(tokens_fetch) = tokens_fetch {
 9261                                    let new_tokens = tokens_fetch.await;
 9262                                    if let Some(new_tokens) = new_tokens {
 9263                                        lsp_store
 9264                                            .update(cx, |lsp_store, cx| {
 9265                                                let response = new_tokens
 9266                                                    .into_iter()
 9267                                                    .map(|(server_id, response)| {
 9268                                                        (
 9269                                                            server_id.to_proto(),
 9270                                                            SemanticTokensFull::response_to_proto(
 9271                                                                response,
 9272                                                                lsp_store,
 9273                                                                sender_id,
 9274                                                                &buffer_version,
 9275                                                                cx,
 9276                                                            ),
 9277                                                        )
 9278                                                    })
 9279                                                    .collect::<HashMap<_, _>>();
 9280                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9281                                                    project_id,
 9282                                                    lsp_request_id,
 9283                                                    response,
 9284                                                ) {
 9285                                                    Ok(()) => {}
 9286                                                    Err(e) => {
 9287                                                        log::error!(
 9288                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9289                                                        )
 9290                                                    }
 9291                                                }
 9292                                            })
 9293                                            .ok();
 9294                                    }
 9295                                }
 9296                            }),
 9297                        );
 9298                    }
 9299                });
 9300            }
 9301        }
 9302        Ok(proto::Ack {})
 9303    }
 9304
 9305    async fn handle_lsp_query_response(
 9306        lsp_store: Entity<Self>,
 9307        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9308        cx: AsyncApp,
 9309    ) -> Result<()> {
 9310        lsp_store.read_with(&cx, |lsp_store, _| {
 9311            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9312                upstream_client.handle_lsp_response(envelope.clone());
 9313            }
 9314        });
 9315        Ok(())
 9316    }
 9317
 9318    async fn handle_apply_code_action(
 9319        this: Entity<Self>,
 9320        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9321        mut cx: AsyncApp,
 9322    ) -> Result<proto::ApplyCodeActionResponse> {
 9323        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9324        let action =
 9325            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9326        let apply_code_action = this.update(&mut cx, |this, cx| {
 9327            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9328            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9329            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9330        })?;
 9331
 9332        let project_transaction = apply_code_action.await?;
 9333        let project_transaction = this.update(&mut cx, |this, cx| {
 9334            this.buffer_store.update(cx, |buffer_store, cx| {
 9335                buffer_store.serialize_project_transaction_for_peer(
 9336                    project_transaction,
 9337                    sender_id,
 9338                    cx,
 9339                )
 9340            })
 9341        });
 9342        Ok(proto::ApplyCodeActionResponse {
 9343            transaction: Some(project_transaction),
 9344        })
 9345    }
 9346
 9347    async fn handle_register_buffer_with_language_servers(
 9348        this: Entity<Self>,
 9349        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9350        mut cx: AsyncApp,
 9351    ) -> Result<proto::Ack> {
 9352        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9353        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9354        this.update(&mut cx, |this, cx| {
 9355            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9356                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9357                    project_id: upstream_project_id,
 9358                    buffer_id: buffer_id.to_proto(),
 9359                    only_servers: envelope.payload.only_servers,
 9360                });
 9361            }
 9362
 9363            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9364                anyhow::bail!("buffer is not open");
 9365            };
 9366
 9367            let handle = this.register_buffer_with_language_servers(
 9368                &buffer,
 9369                envelope
 9370                    .payload
 9371                    .only_servers
 9372                    .into_iter()
 9373                    .filter_map(|selector| {
 9374                        Some(match selector.selector? {
 9375                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9376                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9377                            }
 9378                            proto::language_server_selector::Selector::Name(name) => {
 9379                                LanguageServerSelector::Name(LanguageServerName(
 9380                                    SharedString::from(name),
 9381                                ))
 9382                            }
 9383                        })
 9384                    })
 9385                    .collect(),
 9386                false,
 9387                cx,
 9388            );
 9389            // Pull diagnostics for the buffer even if it was already registered.
 9390            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9391            // but it's unclear if we need it.
 9392            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9393                .detach();
 9394            this.buffer_store().update(cx, |buffer_store, _| {
 9395                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9396            });
 9397
 9398            Ok(())
 9399        })?;
 9400        Ok(proto::Ack {})
 9401    }
 9402
 9403    async fn handle_rename_project_entry(
 9404        this: Entity<Self>,
 9405        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9406        mut cx: AsyncApp,
 9407    ) -> Result<proto::ProjectEntryResponse> {
 9408        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9409        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9410        let new_path =
 9411            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9412
 9413        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9414            .update(&mut cx, |this, cx| {
 9415                let (worktree, entry) = this
 9416                    .worktree_store
 9417                    .read(cx)
 9418                    .worktree_and_entry_for_id(entry_id, cx)?;
 9419                let new_worktree = this
 9420                    .worktree_store
 9421                    .read(cx)
 9422                    .worktree_for_id(new_worktree_id, cx)?;
 9423                Some((
 9424                    this.worktree_store.clone(),
 9425                    worktree,
 9426                    new_worktree,
 9427                    entry.clone(),
 9428                ))
 9429            })
 9430            .context("worktree not found")?;
 9431        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9432            (worktree.absolutize(&old_entry.path), worktree.id())
 9433        });
 9434        let new_abs_path =
 9435            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9436
 9437        let _transaction = Self::will_rename_entry(
 9438            this.downgrade(),
 9439            old_worktree_id,
 9440            &old_abs_path,
 9441            &new_abs_path,
 9442            old_entry.is_dir(),
 9443            cx.clone(),
 9444        )
 9445        .await;
 9446        let response = WorktreeStore::handle_rename_project_entry(
 9447            worktree_store,
 9448            envelope.payload,
 9449            cx.clone(),
 9450        )
 9451        .await;
 9452        this.read_with(&cx, |this, _| {
 9453            this.did_rename_entry(
 9454                old_worktree_id,
 9455                &old_abs_path,
 9456                &new_abs_path,
 9457                old_entry.is_dir(),
 9458            );
 9459        });
 9460        response
 9461    }
 9462
 9463    async fn handle_update_diagnostic_summary(
 9464        this: Entity<Self>,
 9465        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9466        mut cx: AsyncApp,
 9467    ) -> Result<()> {
 9468        this.update(&mut cx, |lsp_store, cx| {
 9469            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9470            let mut updated_diagnostics_paths = HashMap::default();
 9471            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9472            for message_summary in envelope
 9473                .payload
 9474                .summary
 9475                .into_iter()
 9476                .chain(envelope.payload.more_summaries)
 9477            {
 9478                let project_path = ProjectPath {
 9479                    worktree_id,
 9480                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9481                };
 9482                let path = project_path.path.clone();
 9483                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9484                let summary = DiagnosticSummary {
 9485                    error_count: message_summary.error_count as usize,
 9486                    warning_count: message_summary.warning_count as usize,
 9487                };
 9488
 9489                if summary.is_empty() {
 9490                    if let Some(worktree_summaries) =
 9491                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9492                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9493                    {
 9494                        summaries.remove(&server_id);
 9495                        if summaries.is_empty() {
 9496                            worktree_summaries.remove(&path);
 9497                        }
 9498                    }
 9499                } else {
 9500                    lsp_store
 9501                        .diagnostic_summaries
 9502                        .entry(worktree_id)
 9503                        .or_default()
 9504                        .entry(path)
 9505                        .or_default()
 9506                        .insert(server_id, summary);
 9507                }
 9508
 9509                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9510                    match &mut diagnostics_summary {
 9511                        Some(diagnostics_summary) => {
 9512                            diagnostics_summary
 9513                                .more_summaries
 9514                                .push(proto::DiagnosticSummary {
 9515                                    path: project_path.path.as_ref().to_proto(),
 9516                                    language_server_id: server_id.0 as u64,
 9517                                    error_count: summary.error_count as u32,
 9518                                    warning_count: summary.warning_count as u32,
 9519                                })
 9520                        }
 9521                        None => {
 9522                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9523                                project_id: *project_id,
 9524                                worktree_id: worktree_id.to_proto(),
 9525                                summary: Some(proto::DiagnosticSummary {
 9526                                    path: project_path.path.as_ref().to_proto(),
 9527                                    language_server_id: server_id.0 as u64,
 9528                                    error_count: summary.error_count as u32,
 9529                                    warning_count: summary.warning_count as u32,
 9530                                }),
 9531                                more_summaries: Vec::new(),
 9532                            })
 9533                        }
 9534                    }
 9535                }
 9536                updated_diagnostics_paths
 9537                    .entry(server_id)
 9538                    .or_insert_with(Vec::new)
 9539                    .push(project_path);
 9540            }
 9541
 9542            if let Some((diagnostics_summary, (downstream_client, _))) =
 9543                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9544            {
 9545                downstream_client.send(diagnostics_summary).log_err();
 9546            }
 9547            for (server_id, paths) in updated_diagnostics_paths {
 9548                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9549            }
 9550            Ok(())
 9551        })
 9552    }
 9553
 9554    async fn handle_start_language_server(
 9555        lsp_store: Entity<Self>,
 9556        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9557        mut cx: AsyncApp,
 9558    ) -> Result<()> {
 9559        let server = envelope.payload.server.context("invalid server")?;
 9560        let server_capabilities =
 9561            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9562                .with_context(|| {
 9563                    format!(
 9564                        "incorrect server capabilities {}",
 9565                        envelope.payload.capabilities
 9566                    )
 9567                })?;
 9568        lsp_store.update(&mut cx, |lsp_store, cx| {
 9569            let server_id = LanguageServerId(server.id as usize);
 9570            let server_name = LanguageServerName::from_proto(server.name.clone());
 9571            lsp_store
 9572                .lsp_server_capabilities
 9573                .insert(server_id, server_capabilities);
 9574            lsp_store.language_server_statuses.insert(
 9575                server_id,
 9576                LanguageServerStatus {
 9577                    name: server_name.clone(),
 9578                    server_version: None,
 9579                    server_readable_version: None,
 9580                    pending_work: Default::default(),
 9581                    has_pending_diagnostic_updates: false,
 9582                    progress_tokens: Default::default(),
 9583                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9584                    binary: None,
 9585                    configuration: None,
 9586                    workspace_folders: BTreeSet::new(),
 9587                    process_id: None,
 9588                },
 9589            );
 9590            cx.emit(LspStoreEvent::LanguageServerAdded(
 9591                server_id,
 9592                server_name,
 9593                server.worktree_id.map(WorktreeId::from_proto),
 9594            ));
 9595            cx.notify();
 9596        });
 9597        Ok(())
 9598    }
 9599
 9600    async fn handle_update_language_server(
 9601        lsp_store: Entity<Self>,
 9602        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9603        mut cx: AsyncApp,
 9604    ) -> Result<()> {
 9605        lsp_store.update(&mut cx, |lsp_store, cx| {
 9606            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9607
 9608            match envelope.payload.variant.context("invalid variant")? {
 9609                proto::update_language_server::Variant::WorkStart(payload) => {
 9610                    lsp_store.on_lsp_work_start(
 9611                        language_server_id,
 9612                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9613                            .context("invalid progress token value")?,
 9614                        LanguageServerProgress {
 9615                            title: payload.title,
 9616                            is_disk_based_diagnostics_progress: false,
 9617                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9618                            message: payload.message,
 9619                            percentage: payload.percentage.map(|p| p as usize),
 9620                            last_update_at: cx.background_executor().now(),
 9621                        },
 9622                        cx,
 9623                    );
 9624                }
 9625                proto::update_language_server::Variant::WorkProgress(payload) => {
 9626                    lsp_store.on_lsp_work_progress(
 9627                        language_server_id,
 9628                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9629                            .context("invalid progress token value")?,
 9630                        LanguageServerProgress {
 9631                            title: None,
 9632                            is_disk_based_diagnostics_progress: false,
 9633                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9634                            message: payload.message,
 9635                            percentage: payload.percentage.map(|p| p as usize),
 9636                            last_update_at: cx.background_executor().now(),
 9637                        },
 9638                        cx,
 9639                    );
 9640                }
 9641
 9642                proto::update_language_server::Variant::WorkEnd(payload) => {
 9643                    lsp_store.on_lsp_work_end(
 9644                        language_server_id,
 9645                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9646                            .context("invalid progress token value")?,
 9647                        cx,
 9648                    );
 9649                }
 9650
 9651                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9652                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9653                }
 9654
 9655                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9656                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9657                }
 9658
 9659                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9660                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9661                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9662                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9663                        language_server_id,
 9664                        name: envelope
 9665                            .payload
 9666                            .server_name
 9667                            .map(SharedString::new)
 9668                            .map(LanguageServerName),
 9669                        message: non_lsp,
 9670                    });
 9671                }
 9672            }
 9673
 9674            Ok(())
 9675        })
 9676    }
 9677
 9678    async fn handle_language_server_log(
 9679        this: Entity<Self>,
 9680        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9681        mut cx: AsyncApp,
 9682    ) -> Result<()> {
 9683        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9684        let log_type = envelope
 9685            .payload
 9686            .log_type
 9687            .map(LanguageServerLogType::from_proto)
 9688            .context("invalid language server log type")?;
 9689
 9690        let message = envelope.payload.message;
 9691
 9692        this.update(&mut cx, |_, cx| {
 9693            cx.emit(LspStoreEvent::LanguageServerLog(
 9694                language_server_id,
 9695                log_type,
 9696                message,
 9697            ));
 9698        });
 9699        Ok(())
 9700    }
 9701
 9702    async fn handle_lsp_ext_cancel_flycheck(
 9703        lsp_store: Entity<Self>,
 9704        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9705        cx: AsyncApp,
 9706    ) -> Result<proto::Ack> {
 9707        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9708        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9709            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9710                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9711            } else {
 9712                None
 9713            }
 9714        });
 9715        if let Some(task) = task {
 9716            task.context("handling lsp ext cancel flycheck")?;
 9717        }
 9718
 9719        Ok(proto::Ack {})
 9720    }
 9721
 9722    async fn handle_lsp_ext_run_flycheck(
 9723        lsp_store: Entity<Self>,
 9724        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9725        mut cx: AsyncApp,
 9726    ) -> Result<proto::Ack> {
 9727        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9728        lsp_store.update(&mut cx, |lsp_store, cx| {
 9729            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9730                let text_document = if envelope.payload.current_file_only {
 9731                    let buffer_id = envelope
 9732                        .payload
 9733                        .buffer_id
 9734                        .map(|id| BufferId::new(id))
 9735                        .transpose()?;
 9736                    buffer_id
 9737                        .and_then(|buffer_id| {
 9738                            lsp_store
 9739                                .buffer_store()
 9740                                .read(cx)
 9741                                .get(buffer_id)
 9742                                .and_then(|buffer| {
 9743                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9744                                })
 9745                                .map(|path| make_text_document_identifier(&path))
 9746                        })
 9747                        .transpose()?
 9748                } else {
 9749                    None
 9750                };
 9751                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9752                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9753                )?;
 9754            }
 9755            anyhow::Ok(())
 9756        })?;
 9757
 9758        Ok(proto::Ack {})
 9759    }
 9760
 9761    async fn handle_lsp_ext_clear_flycheck(
 9762        lsp_store: Entity<Self>,
 9763        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9764        cx: AsyncApp,
 9765    ) -> Result<proto::Ack> {
 9766        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9767        lsp_store.read_with(&cx, |lsp_store, _| {
 9768            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9769                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9770            } else {
 9771                None
 9772            }
 9773        });
 9774
 9775        Ok(proto::Ack {})
 9776    }
 9777
 9778    pub fn disk_based_diagnostics_started(
 9779        &mut self,
 9780        language_server_id: LanguageServerId,
 9781        cx: &mut Context<Self>,
 9782    ) {
 9783        if let Some(language_server_status) =
 9784            self.language_server_statuses.get_mut(&language_server_id)
 9785        {
 9786            language_server_status.has_pending_diagnostic_updates = true;
 9787        }
 9788
 9789        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9790        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9791            language_server_id,
 9792            name: self
 9793                .language_server_adapter_for_id(language_server_id)
 9794                .map(|adapter| adapter.name()),
 9795            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9796                Default::default(),
 9797            ),
 9798        })
 9799    }
 9800
 9801    pub fn disk_based_diagnostics_finished(
 9802        &mut self,
 9803        language_server_id: LanguageServerId,
 9804        cx: &mut Context<Self>,
 9805    ) {
 9806        if let Some(language_server_status) =
 9807            self.language_server_statuses.get_mut(&language_server_id)
 9808        {
 9809            language_server_status.has_pending_diagnostic_updates = false;
 9810        }
 9811
 9812        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9813        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9814            language_server_id,
 9815            name: self
 9816                .language_server_adapter_for_id(language_server_id)
 9817                .map(|adapter| adapter.name()),
 9818            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9819                Default::default(),
 9820            ),
 9821        })
 9822    }
 9823
 9824    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9825    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9826    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9827    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9828    // the language server might take some time to publish diagnostics.
 9829    fn simulate_disk_based_diagnostics_events_if_needed(
 9830        &mut self,
 9831        language_server_id: LanguageServerId,
 9832        cx: &mut Context<Self>,
 9833    ) {
 9834        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9835
 9836        let Some(LanguageServerState::Running {
 9837            simulate_disk_based_diagnostics_completion,
 9838            adapter,
 9839            ..
 9840        }) = self
 9841            .as_local_mut()
 9842            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9843        else {
 9844            return;
 9845        };
 9846
 9847        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9848            return;
 9849        }
 9850
 9851        let prev_task =
 9852            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9853                cx.background_executor()
 9854                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9855                    .await;
 9856
 9857                this.update(cx, |this, cx| {
 9858                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9859
 9860                    if let Some(LanguageServerState::Running {
 9861                        simulate_disk_based_diagnostics_completion,
 9862                        ..
 9863                    }) = this.as_local_mut().and_then(|local_store| {
 9864                        local_store.language_servers.get_mut(&language_server_id)
 9865                    }) {
 9866                        *simulate_disk_based_diagnostics_completion = None;
 9867                    }
 9868                })
 9869                .ok();
 9870            }));
 9871
 9872        if prev_task.is_none() {
 9873            self.disk_based_diagnostics_started(language_server_id, cx);
 9874        }
 9875    }
 9876
 9877    pub fn language_server_statuses(
 9878        &self,
 9879    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9880        self.language_server_statuses
 9881            .iter()
 9882            .map(|(key, value)| (*key, value))
 9883    }
 9884
 9885    pub(super) fn did_rename_entry(
 9886        &self,
 9887        worktree_id: WorktreeId,
 9888        old_path: &Path,
 9889        new_path: &Path,
 9890        is_dir: bool,
 9891    ) {
 9892        maybe!({
 9893            let local_store = self.as_local()?;
 9894
 9895            let old_uri = lsp::Uri::from_file_path(old_path)
 9896                .ok()
 9897                .map(|uri| uri.to_string())?;
 9898            let new_uri = lsp::Uri::from_file_path(new_path)
 9899                .ok()
 9900                .map(|uri| uri.to_string())?;
 9901
 9902            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9903                let Some(filter) = local_store
 9904                    .language_server_paths_watched_for_rename
 9905                    .get(&language_server.server_id())
 9906                else {
 9907                    continue;
 9908                };
 9909
 9910                if filter.should_send_did_rename(&old_uri, is_dir) {
 9911                    language_server
 9912                        .notify::<DidRenameFiles>(RenameFilesParams {
 9913                            files: vec![FileRename {
 9914                                old_uri: old_uri.clone(),
 9915                                new_uri: new_uri.clone(),
 9916                            }],
 9917                        })
 9918                        .ok();
 9919                }
 9920            }
 9921            Some(())
 9922        });
 9923    }
 9924
 9925    pub(super) fn will_rename_entry(
 9926        this: WeakEntity<Self>,
 9927        worktree_id: WorktreeId,
 9928        old_path: &Path,
 9929        new_path: &Path,
 9930        is_dir: bool,
 9931        cx: AsyncApp,
 9932    ) -> Task<ProjectTransaction> {
 9933        let old_uri = lsp::Uri::from_file_path(old_path)
 9934            .ok()
 9935            .map(|uri| uri.to_string());
 9936        let new_uri = lsp::Uri::from_file_path(new_path)
 9937            .ok()
 9938            .map(|uri| uri.to_string());
 9939        cx.spawn(async move |cx| {
 9940            let mut tasks = vec![];
 9941            this.update(cx, |this, cx| {
 9942                let local_store = this.as_local()?;
 9943                let old_uri = old_uri?;
 9944                let new_uri = new_uri?;
 9945                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9946                    let Some(filter) = local_store
 9947                        .language_server_paths_watched_for_rename
 9948                        .get(&language_server.server_id())
 9949                    else {
 9950                        continue;
 9951                    };
 9952
 9953                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9954                        continue;
 9955                    }
 9956                    let request_timeout = ProjectSettings::get_global(cx)
 9957                        .global_lsp_settings
 9958                        .get_request_timeout();
 9959
 9960                    let apply_edit = cx.spawn({
 9961                        let old_uri = old_uri.clone();
 9962                        let new_uri = new_uri.clone();
 9963                        let language_server = language_server.clone();
 9964                        async move |this, cx| {
 9965                            let edit = language_server
 9966                                .request::<WillRenameFiles>(
 9967                                    RenameFilesParams {
 9968                                        files: vec![FileRename { old_uri, new_uri }],
 9969                                    },
 9970                                    request_timeout,
 9971                                )
 9972                                .await
 9973                                .into_response()
 9974                                .context("will rename files")
 9975                                .log_err()
 9976                                .flatten()?;
 9977
 9978                            LocalLspStore::deserialize_workspace_edit(
 9979                                this.upgrade()?,
 9980                                edit,
 9981                                false,
 9982                                language_server.clone(),
 9983                                cx,
 9984                            )
 9985                            .await
 9986                            .ok()
 9987                        }
 9988                    });
 9989                    tasks.push(apply_edit);
 9990                }
 9991                Some(())
 9992            })
 9993            .ok()
 9994            .flatten();
 9995            let mut merged_transaction = ProjectTransaction::default();
 9996            for task in tasks {
 9997                // Await on tasks sequentially so that the order of application of edits is deterministic
 9998                // (at least with regards to the order of registration of language servers)
 9999                if let Some(transaction) = task.await {
10000                    for (buffer, buffer_transaction) in transaction.0 {
10001                        merged_transaction.0.insert(buffer, buffer_transaction);
10002                    }
10003                }
10004            }
10005            merged_transaction
10006        })
10007    }
10008
10009    fn lsp_notify_abs_paths_changed(
10010        &mut self,
10011        server_id: LanguageServerId,
10012        changes: Vec<PathEvent>,
10013    ) {
10014        maybe!({
10015            let server = self.language_server_for_id(server_id)?;
10016            let changes = changes
10017                .into_iter()
10018                .filter_map(|event| {
10019                    let typ = match event.kind? {
10020                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10021                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10022                        PathEventKind::Changed | PathEventKind::Rescan => {
10023                            lsp::FileChangeType::CHANGED
10024                        }
10025                    };
10026                    Some(lsp::FileEvent {
10027                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10028                        typ,
10029                    })
10030                })
10031                .collect::<Vec<_>>();
10032            if !changes.is_empty() {
10033                server
10034                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10035                        lsp::DidChangeWatchedFilesParams { changes },
10036                    )
10037                    .ok();
10038            }
10039            Some(())
10040        });
10041    }
10042
10043    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10044        self.as_local()?.language_server_for_id(id)
10045    }
10046
10047    fn on_lsp_progress(
10048        &mut self,
10049        progress_params: lsp::ProgressParams,
10050        language_server_id: LanguageServerId,
10051        disk_based_diagnostics_progress_token: Option<String>,
10052        cx: &mut Context<Self>,
10053    ) {
10054        match progress_params.value {
10055            lsp::ProgressParamsValue::WorkDone(progress) => {
10056                self.handle_work_done_progress(
10057                    progress,
10058                    language_server_id,
10059                    disk_based_diagnostics_progress_token,
10060                    ProgressToken::from_lsp(progress_params.token),
10061                    cx,
10062                );
10063            }
10064            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10065                let registration_id = match progress_params.token {
10066                    lsp::NumberOrString::Number(_) => None,
10067                    lsp::NumberOrString::String(token) => token
10068                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10069                        .map(|(_, id)| id.to_owned()),
10070                };
10071                if let Some(LanguageServerState::Running {
10072                    workspace_diagnostics_refresh_tasks,
10073                    ..
10074                }) = self
10075                    .as_local_mut()
10076                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10077                    && let Some(workspace_diagnostics) =
10078                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10079                {
10080                    workspace_diagnostics.progress_tx.try_send(()).ok();
10081                    self.apply_workspace_diagnostic_report(
10082                        language_server_id,
10083                        report,
10084                        registration_id.map(SharedString::from),
10085                        cx,
10086                    )
10087                }
10088            }
10089        }
10090    }
10091
10092    fn handle_work_done_progress(
10093        &mut self,
10094        progress: lsp::WorkDoneProgress,
10095        language_server_id: LanguageServerId,
10096        disk_based_diagnostics_progress_token: Option<String>,
10097        token: ProgressToken,
10098        cx: &mut Context<Self>,
10099    ) {
10100        let language_server_status =
10101            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10102                status
10103            } else {
10104                return;
10105            };
10106
10107        if !language_server_status.progress_tokens.contains(&token) {
10108            return;
10109        }
10110
10111        let is_disk_based_diagnostics_progress =
10112            if let (Some(disk_based_token), ProgressToken::String(token)) =
10113                (&disk_based_diagnostics_progress_token, &token)
10114            {
10115                token.starts_with(disk_based_token)
10116            } else {
10117                false
10118            };
10119
10120        match progress {
10121            lsp::WorkDoneProgress::Begin(report) => {
10122                if is_disk_based_diagnostics_progress {
10123                    self.disk_based_diagnostics_started(language_server_id, cx);
10124                }
10125                self.on_lsp_work_start(
10126                    language_server_id,
10127                    token.clone(),
10128                    LanguageServerProgress {
10129                        title: Some(report.title),
10130                        is_disk_based_diagnostics_progress,
10131                        is_cancellable: report.cancellable.unwrap_or(false),
10132                        message: report.message.clone(),
10133                        percentage: report.percentage.map(|p| p as usize),
10134                        last_update_at: cx.background_executor().now(),
10135                    },
10136                    cx,
10137                );
10138            }
10139            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10140                language_server_id,
10141                token,
10142                LanguageServerProgress {
10143                    title: None,
10144                    is_disk_based_diagnostics_progress,
10145                    is_cancellable: report.cancellable.unwrap_or(false),
10146                    message: report.message,
10147                    percentage: report.percentage.map(|p| p as usize),
10148                    last_update_at: cx.background_executor().now(),
10149                },
10150                cx,
10151            ),
10152            lsp::WorkDoneProgress::End(_) => {
10153                language_server_status.progress_tokens.remove(&token);
10154                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10155                if is_disk_based_diagnostics_progress {
10156                    self.disk_based_diagnostics_finished(language_server_id, cx);
10157                }
10158            }
10159        }
10160    }
10161
10162    fn on_lsp_work_start(
10163        &mut self,
10164        language_server_id: LanguageServerId,
10165        token: ProgressToken,
10166        progress: LanguageServerProgress,
10167        cx: &mut Context<Self>,
10168    ) {
10169        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10170            status.pending_work.insert(token.clone(), progress.clone());
10171            cx.notify();
10172        }
10173        cx.emit(LspStoreEvent::LanguageServerUpdate {
10174            language_server_id,
10175            name: self
10176                .language_server_adapter_for_id(language_server_id)
10177                .map(|adapter| adapter.name()),
10178            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10179                token: Some(token.to_proto()),
10180                title: progress.title,
10181                message: progress.message,
10182                percentage: progress.percentage.map(|p| p as u32),
10183                is_cancellable: Some(progress.is_cancellable),
10184            }),
10185        })
10186    }
10187
10188    fn on_lsp_work_progress(
10189        &mut self,
10190        language_server_id: LanguageServerId,
10191        token: ProgressToken,
10192        progress: LanguageServerProgress,
10193        cx: &mut Context<Self>,
10194    ) {
10195        let mut did_update = false;
10196        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10197            match status.pending_work.entry(token.clone()) {
10198                btree_map::Entry::Vacant(entry) => {
10199                    entry.insert(progress.clone());
10200                    did_update = true;
10201                }
10202                btree_map::Entry::Occupied(mut entry) => {
10203                    let entry = entry.get_mut();
10204                    if (progress.last_update_at - entry.last_update_at)
10205                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10206                    {
10207                        entry.last_update_at = progress.last_update_at;
10208                        if progress.message.is_some() {
10209                            entry.message = progress.message.clone();
10210                        }
10211                        if progress.percentage.is_some() {
10212                            entry.percentage = progress.percentage;
10213                        }
10214                        if progress.is_cancellable != entry.is_cancellable {
10215                            entry.is_cancellable = progress.is_cancellable;
10216                        }
10217                        did_update = true;
10218                    }
10219                }
10220            }
10221        }
10222
10223        if did_update {
10224            cx.emit(LspStoreEvent::LanguageServerUpdate {
10225                language_server_id,
10226                name: self
10227                    .language_server_adapter_for_id(language_server_id)
10228                    .map(|adapter| adapter.name()),
10229                message: proto::update_language_server::Variant::WorkProgress(
10230                    proto::LspWorkProgress {
10231                        token: Some(token.to_proto()),
10232                        message: progress.message,
10233                        percentage: progress.percentage.map(|p| p as u32),
10234                        is_cancellable: Some(progress.is_cancellable),
10235                    },
10236                ),
10237            })
10238        }
10239    }
10240
10241    fn on_lsp_work_end(
10242        &mut self,
10243        language_server_id: LanguageServerId,
10244        token: ProgressToken,
10245        cx: &mut Context<Self>,
10246    ) {
10247        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10248            if let Some(work) = status.pending_work.remove(&token)
10249                && !work.is_disk_based_diagnostics_progress
10250            {
10251                cx.emit(LspStoreEvent::RefreshInlayHints {
10252                    server_id: language_server_id,
10253                    request_id: None,
10254                });
10255            }
10256            cx.notify();
10257        }
10258
10259        cx.emit(LspStoreEvent::LanguageServerUpdate {
10260            language_server_id,
10261            name: self
10262                .language_server_adapter_for_id(language_server_id)
10263                .map(|adapter| adapter.name()),
10264            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10265                token: Some(token.to_proto()),
10266            }),
10267        })
10268    }
10269
10270    pub async fn handle_resolve_completion_documentation(
10271        this: Entity<Self>,
10272        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10273        mut cx: AsyncApp,
10274    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10275        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10276
10277        let completion = this
10278            .read_with(&cx, |this, cx| {
10279                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10280                let server = this
10281                    .language_server_for_id(id)
10282                    .with_context(|| format!("No language server {id}"))?;
10283
10284                let request_timeout = ProjectSettings::get_global(cx)
10285                    .global_lsp_settings
10286                    .get_request_timeout();
10287
10288                anyhow::Ok(cx.background_spawn(async move {
10289                    let can_resolve = server
10290                        .capabilities()
10291                        .completion_provider
10292                        .as_ref()
10293                        .and_then(|options| options.resolve_provider)
10294                        .unwrap_or(false);
10295                    if can_resolve {
10296                        server
10297                            .request::<lsp::request::ResolveCompletionItem>(
10298                                lsp_completion,
10299                                request_timeout,
10300                            )
10301                            .await
10302                            .into_response()
10303                            .context("resolve completion item")
10304                    } else {
10305                        anyhow::Ok(lsp_completion)
10306                    }
10307                }))
10308            })?
10309            .await?;
10310
10311        let mut documentation_is_markdown = false;
10312        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10313        let documentation = match completion.documentation {
10314            Some(lsp::Documentation::String(text)) => text,
10315
10316            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10317                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10318                value
10319            }
10320
10321            _ => String::new(),
10322        };
10323
10324        // If we have a new buffer_id, that means we're talking to a new client
10325        // and want to check for new text_edits in the completion too.
10326        let mut old_replace_start = None;
10327        let mut old_replace_end = None;
10328        let mut old_insert_start = None;
10329        let mut old_insert_end = None;
10330        let mut new_text = String::default();
10331        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10332            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10333                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10334                anyhow::Ok(buffer.read(cx).snapshot())
10335            })?;
10336
10337            if let Some(text_edit) = completion.text_edit.as_ref() {
10338                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10339
10340                if let Some(mut edit) = edit {
10341                    LineEnding::normalize(&mut edit.new_text);
10342
10343                    new_text = edit.new_text;
10344                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10345                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10346                    if let Some(insert_range) = edit.insert_range {
10347                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10348                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10349                    }
10350                }
10351            }
10352        }
10353
10354        Ok(proto::ResolveCompletionDocumentationResponse {
10355            documentation,
10356            documentation_is_markdown,
10357            old_replace_start,
10358            old_replace_end,
10359            new_text,
10360            lsp_completion,
10361            old_insert_start,
10362            old_insert_end,
10363        })
10364    }
10365
10366    async fn handle_on_type_formatting(
10367        this: Entity<Self>,
10368        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10369        mut cx: AsyncApp,
10370    ) -> Result<proto::OnTypeFormattingResponse> {
10371        let on_type_formatting = this.update(&mut cx, |this, cx| {
10372            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10373            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10374            let position = envelope
10375                .payload
10376                .position
10377                .and_then(deserialize_anchor)
10378                .context("invalid position")?;
10379            anyhow::Ok(this.apply_on_type_formatting(
10380                buffer,
10381                position,
10382                envelope.payload.trigger.clone(),
10383                cx,
10384            ))
10385        })?;
10386
10387        let transaction = on_type_formatting
10388            .await?
10389            .as_ref()
10390            .map(language::proto::serialize_transaction);
10391        Ok(proto::OnTypeFormattingResponse { transaction })
10392    }
10393
10394    async fn handle_pull_workspace_diagnostics(
10395        lsp_store: Entity<Self>,
10396        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10397        mut cx: AsyncApp,
10398    ) -> Result<proto::Ack> {
10399        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10400        lsp_store.update(&mut cx, |lsp_store, _| {
10401            lsp_store.pull_workspace_diagnostics(server_id);
10402        });
10403        Ok(proto::Ack {})
10404    }
10405
10406    async fn handle_open_buffer_for_symbol(
10407        this: Entity<Self>,
10408        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10409        mut cx: AsyncApp,
10410    ) -> Result<proto::OpenBufferForSymbolResponse> {
10411        let peer_id = envelope.original_sender_id().unwrap_or_default();
10412        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10413        let symbol = Self::deserialize_symbol(symbol)?;
10414        this.read_with(&cx, |this, _| {
10415            if let SymbolLocation::OutsideProject {
10416                abs_path,
10417                signature,
10418            } = &symbol.path
10419            {
10420                let new_signature = this.symbol_signature(&abs_path);
10421                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10422            }
10423            Ok(())
10424        })?;
10425        let buffer = this
10426            .update(&mut cx, |this, cx| {
10427                this.open_buffer_for_symbol(
10428                    &Symbol {
10429                        language_server_name: symbol.language_server_name,
10430                        source_worktree_id: symbol.source_worktree_id,
10431                        source_language_server_id: symbol.source_language_server_id,
10432                        path: symbol.path,
10433                        name: symbol.name,
10434                        kind: symbol.kind,
10435                        range: symbol.range,
10436                        label: CodeLabel::default(),
10437                        container_name: symbol.container_name,
10438                    },
10439                    cx,
10440                )
10441            })
10442            .await?;
10443
10444        this.update(&mut cx, |this, cx| {
10445            let is_private = buffer
10446                .read(cx)
10447                .file()
10448                .map(|f| f.is_private())
10449                .unwrap_or_default();
10450            if is_private {
10451                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10452            } else {
10453                this.buffer_store
10454                    .update(cx, |buffer_store, cx| {
10455                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10456                    })
10457                    .detach_and_log_err(cx);
10458                let buffer_id = buffer.read(cx).remote_id().to_proto();
10459                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10460            }
10461        })
10462    }
10463
10464    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10465        let mut hasher = Sha256::new();
10466        hasher.update(abs_path.to_string_lossy().as_bytes());
10467        hasher.update(self.nonce.to_be_bytes());
10468        hasher.finalize().as_slice().try_into().unwrap()
10469    }
10470
10471    pub async fn handle_get_project_symbols(
10472        this: Entity<Self>,
10473        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10474        mut cx: AsyncApp,
10475    ) -> Result<proto::GetProjectSymbolsResponse> {
10476        let symbols = this
10477            .update(&mut cx, |this, cx| {
10478                this.symbols(&envelope.payload.query, cx)
10479            })
10480            .await?;
10481
10482        Ok(proto::GetProjectSymbolsResponse {
10483            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10484        })
10485    }
10486
10487    pub async fn handle_restart_language_servers(
10488        this: Entity<Self>,
10489        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10490        mut cx: AsyncApp,
10491    ) -> Result<proto::Ack> {
10492        this.update(&mut cx, |lsp_store, cx| {
10493            let buffers =
10494                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10495            lsp_store.restart_language_servers_for_buffers(
10496                buffers,
10497                envelope
10498                    .payload
10499                    .only_servers
10500                    .into_iter()
10501                    .filter_map(|selector| {
10502                        Some(match selector.selector? {
10503                            proto::language_server_selector::Selector::ServerId(server_id) => {
10504                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10505                            }
10506                            proto::language_server_selector::Selector::Name(name) => {
10507                                LanguageServerSelector::Name(LanguageServerName(
10508                                    SharedString::from(name),
10509                                ))
10510                            }
10511                        })
10512                    })
10513                    .collect(),
10514                cx,
10515            );
10516        });
10517
10518        Ok(proto::Ack {})
10519    }
10520
10521    pub async fn handle_stop_language_servers(
10522        lsp_store: Entity<Self>,
10523        envelope: TypedEnvelope<proto::StopLanguageServers>,
10524        mut cx: AsyncApp,
10525    ) -> Result<proto::Ack> {
10526        lsp_store.update(&mut cx, |lsp_store, cx| {
10527            if envelope.payload.all
10528                && envelope.payload.also_servers.is_empty()
10529                && envelope.payload.buffer_ids.is_empty()
10530            {
10531                lsp_store.stop_all_language_servers(cx);
10532            } else {
10533                let buffers =
10534                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10535                lsp_store
10536                    .stop_language_servers_for_buffers(
10537                        buffers,
10538                        envelope
10539                            .payload
10540                            .also_servers
10541                            .into_iter()
10542                            .filter_map(|selector| {
10543                                Some(match selector.selector? {
10544                                    proto::language_server_selector::Selector::ServerId(
10545                                        server_id,
10546                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10547                                        server_id,
10548                                    )),
10549                                    proto::language_server_selector::Selector::Name(name) => {
10550                                        LanguageServerSelector::Name(LanguageServerName(
10551                                            SharedString::from(name),
10552                                        ))
10553                                    }
10554                                })
10555                            })
10556                            .collect(),
10557                        cx,
10558                    )
10559                    .detach_and_log_err(cx);
10560            }
10561        });
10562
10563        Ok(proto::Ack {})
10564    }
10565
10566    pub async fn handle_cancel_language_server_work(
10567        lsp_store: Entity<Self>,
10568        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10569        mut cx: AsyncApp,
10570    ) -> Result<proto::Ack> {
10571        lsp_store.update(&mut cx, |lsp_store, cx| {
10572            if let Some(work) = envelope.payload.work {
10573                match work {
10574                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10575                        let buffers =
10576                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10577                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10578                    }
10579                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10580                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10581                        let token = work
10582                            .token
10583                            .map(|token| {
10584                                ProgressToken::from_proto(token)
10585                                    .context("invalid work progress token")
10586                            })
10587                            .transpose()?;
10588                        lsp_store.cancel_language_server_work(server_id, token, cx);
10589                    }
10590                }
10591            }
10592            anyhow::Ok(())
10593        })?;
10594
10595        Ok(proto::Ack {})
10596    }
10597
10598    fn buffer_ids_to_buffers(
10599        &mut self,
10600        buffer_ids: impl Iterator<Item = u64>,
10601        cx: &mut Context<Self>,
10602    ) -> Vec<Entity<Buffer>> {
10603        buffer_ids
10604            .into_iter()
10605            .flat_map(|buffer_id| {
10606                self.buffer_store
10607                    .read(cx)
10608                    .get(BufferId::new(buffer_id).log_err()?)
10609            })
10610            .collect::<Vec<_>>()
10611    }
10612
10613    async fn handle_apply_additional_edits_for_completion(
10614        this: Entity<Self>,
10615        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10616        mut cx: AsyncApp,
10617    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10618        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10619            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10620            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10621            let completion = Self::deserialize_completion(
10622                envelope.payload.completion.context("invalid completion")?,
10623            )?;
10624            let all_commit_ranges = envelope
10625                .payload
10626                .all_commit_ranges
10627                .into_iter()
10628                .map(language::proto::deserialize_anchor_range)
10629                .collect::<Result<Vec<_>, _>>()?;
10630            anyhow::Ok((buffer, completion, all_commit_ranges))
10631        })?;
10632
10633        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10634            this.apply_additional_edits_for_completion(
10635                buffer,
10636                Rc::new(RefCell::new(Box::new([Completion {
10637                    replace_range: completion.replace_range,
10638                    new_text: completion.new_text,
10639                    source: completion.source,
10640                    documentation: None,
10641                    label: CodeLabel::default(),
10642                    match_start: None,
10643                    snippet_deduplication_key: None,
10644                    insert_text_mode: None,
10645                    icon_path: None,
10646                    confirm: None,
10647                }]))),
10648                0,
10649                false,
10650                all_commit_ranges,
10651                cx,
10652            )
10653        });
10654
10655        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10656            transaction: apply_additional_edits
10657                .await?
10658                .as_ref()
10659                .map(language::proto::serialize_transaction),
10660        })
10661    }
10662
10663    pub fn last_formatting_failure(&self) -> Option<&str> {
10664        self.last_formatting_failure.as_deref()
10665    }
10666
10667    pub fn reset_last_formatting_failure(&mut self) {
10668        self.last_formatting_failure = None;
10669    }
10670
10671    pub fn environment_for_buffer(
10672        &self,
10673        buffer: &Entity<Buffer>,
10674        cx: &mut Context<Self>,
10675    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10676        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10677            environment.update(cx, |env, cx| {
10678                env.buffer_environment(buffer, &self.worktree_store, cx)
10679            })
10680        } else {
10681            Task::ready(None).shared()
10682        }
10683    }
10684
10685    pub fn format(
10686        &mut self,
10687        buffers: HashSet<Entity<Buffer>>,
10688        target: LspFormatTarget,
10689        push_to_history: bool,
10690        trigger: FormatTrigger,
10691        cx: &mut Context<Self>,
10692    ) -> Task<anyhow::Result<ProjectTransaction>> {
10693        let logger = zlog::scoped!("format");
10694        if self.as_local().is_some() {
10695            zlog::trace!(logger => "Formatting locally");
10696            let logger = zlog::scoped!(logger => "local");
10697            let buffers = buffers
10698                .into_iter()
10699                .map(|buffer_handle| {
10700                    let buffer = buffer_handle.read(cx);
10701                    let buffer_abs_path = File::from_dyn(buffer.file())
10702                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10703
10704                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10705                })
10706                .collect::<Vec<_>>();
10707
10708            cx.spawn(async move |lsp_store, cx| {
10709                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10710
10711                for (handle, abs_path, id) in buffers {
10712                    let env = lsp_store
10713                        .update(cx, |lsp_store, cx| {
10714                            lsp_store.environment_for_buffer(&handle, cx)
10715                        })?
10716                        .await;
10717
10718                    let ranges = match &target {
10719                        LspFormatTarget::Buffers => None,
10720                        LspFormatTarget::Ranges(ranges) => {
10721                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10722                        }
10723                    };
10724
10725                    formattable_buffers.push(FormattableBuffer {
10726                        handle,
10727                        abs_path,
10728                        env,
10729                        ranges,
10730                    });
10731                }
10732                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10733
10734                let format_timer = zlog::time!(logger => "Formatting buffers");
10735                let result = LocalLspStore::format_locally(
10736                    lsp_store.clone(),
10737                    formattable_buffers,
10738                    push_to_history,
10739                    trigger,
10740                    logger,
10741                    cx,
10742                )
10743                .await;
10744                format_timer.end();
10745
10746                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10747
10748                lsp_store.update(cx, |lsp_store, _| {
10749                    lsp_store.update_last_formatting_failure(&result);
10750                })?;
10751
10752                result
10753            })
10754        } else if let Some((client, project_id)) = self.upstream_client() {
10755            zlog::trace!(logger => "Formatting remotely");
10756            let logger = zlog::scoped!(logger => "remote");
10757
10758            let buffer_ranges = match &target {
10759                LspFormatTarget::Buffers => Vec::new(),
10760                LspFormatTarget::Ranges(ranges) => ranges
10761                    .iter()
10762                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10763                        buffer_id: buffer_id.to_proto(),
10764                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10765                    })
10766                    .collect(),
10767            };
10768
10769            let buffer_store = self.buffer_store();
10770            cx.spawn(async move |lsp_store, cx| {
10771                zlog::trace!(logger => "Sending remote format request");
10772                let request_timer = zlog::time!(logger => "remote format request");
10773                let result = client
10774                    .request(proto::FormatBuffers {
10775                        project_id,
10776                        trigger: trigger as i32,
10777                        buffer_ids: buffers
10778                            .iter()
10779                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10780                            .collect(),
10781                        buffer_ranges,
10782                    })
10783                    .await
10784                    .and_then(|result| result.transaction.context("missing transaction"));
10785                request_timer.end();
10786
10787                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10788
10789                lsp_store.update(cx, |lsp_store, _| {
10790                    lsp_store.update_last_formatting_failure(&result);
10791                })?;
10792
10793                let transaction_response = result?;
10794                let _timer = zlog::time!(logger => "deserializing project transaction");
10795                buffer_store
10796                    .update(cx, |buffer_store, cx| {
10797                        buffer_store.deserialize_project_transaction(
10798                            transaction_response,
10799                            push_to_history,
10800                            cx,
10801                        )
10802                    })
10803                    .await
10804            })
10805        } else {
10806            zlog::trace!(logger => "Not formatting");
10807            Task::ready(Ok(ProjectTransaction::default()))
10808        }
10809    }
10810
10811    async fn handle_format_buffers(
10812        this: Entity<Self>,
10813        envelope: TypedEnvelope<proto::FormatBuffers>,
10814        mut cx: AsyncApp,
10815    ) -> Result<proto::FormatBuffersResponse> {
10816        let sender_id = envelope.original_sender_id().unwrap_or_default();
10817        let format = this.update(&mut cx, |this, cx| {
10818            let mut buffers = HashSet::default();
10819            for buffer_id in &envelope.payload.buffer_ids {
10820                let buffer_id = BufferId::new(*buffer_id)?;
10821                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10822            }
10823
10824            let target = if envelope.payload.buffer_ranges.is_empty() {
10825                LspFormatTarget::Buffers
10826            } else {
10827                let mut ranges_map = BTreeMap::new();
10828                for buffer_range in &envelope.payload.buffer_ranges {
10829                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10830                    let ranges: Result<Vec<_>> = buffer_range
10831                        .ranges
10832                        .iter()
10833                        .map(|range| {
10834                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10835                        })
10836                        .collect();
10837                    ranges_map.insert(buffer_id, ranges?);
10838                }
10839                LspFormatTarget::Ranges(ranges_map)
10840            };
10841
10842            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10843            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10844        })?;
10845
10846        let project_transaction = format.await?;
10847        let project_transaction = this.update(&mut cx, |this, cx| {
10848            this.buffer_store.update(cx, |buffer_store, cx| {
10849                buffer_store.serialize_project_transaction_for_peer(
10850                    project_transaction,
10851                    sender_id,
10852                    cx,
10853                )
10854            })
10855        });
10856        Ok(proto::FormatBuffersResponse {
10857            transaction: Some(project_transaction),
10858        })
10859    }
10860
10861    async fn handle_apply_code_action_kind(
10862        this: Entity<Self>,
10863        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10864        mut cx: AsyncApp,
10865    ) -> Result<proto::ApplyCodeActionKindResponse> {
10866        let sender_id = envelope.original_sender_id().unwrap_or_default();
10867        let format = this.update(&mut cx, |this, cx| {
10868            let mut buffers = HashSet::default();
10869            for buffer_id in &envelope.payload.buffer_ids {
10870                let buffer_id = BufferId::new(*buffer_id)?;
10871                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10872            }
10873            let kind = match envelope.payload.kind.as_str() {
10874                "" => CodeActionKind::EMPTY,
10875                "quickfix" => CodeActionKind::QUICKFIX,
10876                "refactor" => CodeActionKind::REFACTOR,
10877                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10878                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10879                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10880                "source" => CodeActionKind::SOURCE,
10881                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10882                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10883                _ => anyhow::bail!(
10884                    "Invalid code action kind {}",
10885                    envelope.payload.kind.as_str()
10886                ),
10887            };
10888            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10889        })?;
10890
10891        let project_transaction = format.await?;
10892        let project_transaction = this.update(&mut cx, |this, cx| {
10893            this.buffer_store.update(cx, |buffer_store, cx| {
10894                buffer_store.serialize_project_transaction_for_peer(
10895                    project_transaction,
10896                    sender_id,
10897                    cx,
10898                )
10899            })
10900        });
10901        Ok(proto::ApplyCodeActionKindResponse {
10902            transaction: Some(project_transaction),
10903        })
10904    }
10905
10906    async fn shutdown_language_server(
10907        server_state: Option<LanguageServerState>,
10908        name: LanguageServerName,
10909        cx: &mut AsyncApp,
10910    ) {
10911        let server = match server_state {
10912            Some(LanguageServerState::Starting { startup, .. }) => {
10913                let mut timer = cx
10914                    .background_executor()
10915                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10916                    .fuse();
10917
10918                select! {
10919                    server = startup.fuse() => server,
10920                    () = timer => {
10921                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10922                        None
10923                    },
10924                }
10925            }
10926
10927            Some(LanguageServerState::Running { server, .. }) => Some(server),
10928
10929            None => None,
10930        };
10931
10932        let Some(server) = server else { return };
10933        if let Some(shutdown) = server.shutdown() {
10934            shutdown.await;
10935        }
10936    }
10937
10938    // Returns a list of all of the worktrees which no longer have a language server and the root path
10939    // for the stopped server
10940    fn stop_local_language_server(
10941        &mut self,
10942        server_id: LanguageServerId,
10943        cx: &mut Context<Self>,
10944    ) -> Task<()> {
10945        let local = match &mut self.mode {
10946            LspStoreMode::Local(local) => local,
10947            _ => {
10948                return Task::ready(());
10949            }
10950        };
10951
10952        // Remove this server ID from all entries in the given worktree.
10953        local
10954            .language_server_ids
10955            .retain(|_, state| state.id != server_id);
10956        self.buffer_store.update(cx, |buffer_store, cx| {
10957            for buffer in buffer_store.buffers() {
10958                buffer.update(cx, |buffer, cx| {
10959                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10960                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10961                });
10962            }
10963        });
10964
10965        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10966        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10967            summaries.retain(|path, summaries_by_server_id| {
10968                if summaries_by_server_id.remove(&server_id).is_some() {
10969                    if let Some((client, project_id)) = self.downstream_client.clone() {
10970                        client
10971                            .send(proto::UpdateDiagnosticSummary {
10972                                project_id,
10973                                worktree_id: worktree_id.to_proto(),
10974                                summary: Some(proto::DiagnosticSummary {
10975                                    path: path.as_ref().to_proto(),
10976                                    language_server_id: server_id.0 as u64,
10977                                    error_count: 0,
10978                                    warning_count: 0,
10979                                }),
10980                                more_summaries: Vec::new(),
10981                            })
10982                            .log_err();
10983                    }
10984                    cleared_paths.push(ProjectPath {
10985                        worktree_id: *worktree_id,
10986                        path: path.clone(),
10987                    });
10988                    !summaries_by_server_id.is_empty()
10989                } else {
10990                    true
10991                }
10992            });
10993        }
10994        if !cleared_paths.is_empty() {
10995            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10996                server_id,
10997                paths: cleared_paths,
10998            });
10999        }
11000
11001        let local = self.as_local_mut().unwrap();
11002        for diagnostics in local.diagnostics.values_mut() {
11003            diagnostics.retain(|_, diagnostics_by_server_id| {
11004                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11005                    diagnostics_by_server_id.remove(ix);
11006                    !diagnostics_by_server_id.is_empty()
11007                } else {
11008                    true
11009                }
11010            });
11011        }
11012        local.language_server_watched_paths.remove(&server_id);
11013
11014        let server_state = local.language_servers.remove(&server_id);
11015        self.cleanup_lsp_data(server_id);
11016        let name = self
11017            .language_server_statuses
11018            .remove(&server_id)
11019            .map(|status| status.name)
11020            .or_else(|| {
11021                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11022                    Some(adapter.name())
11023                } else {
11024                    None
11025                }
11026            });
11027
11028        if let Some(name) = name {
11029            log::info!("stopping language server {name}");
11030            self.languages
11031                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11032            cx.notify();
11033
11034            return cx.spawn(async move |lsp_store, cx| {
11035                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11036                lsp_store
11037                    .update(cx, |lsp_store, cx| {
11038                        lsp_store
11039                            .languages
11040                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11041                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11042                        cx.notify();
11043                    })
11044                    .ok();
11045            });
11046        }
11047
11048        if server_state.is_some() {
11049            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11050        }
11051        Task::ready(())
11052    }
11053
11054    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11055        self.shutdown_all_language_servers(cx).detach();
11056    }
11057
11058    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11059        if let Some((client, project_id)) = self.upstream_client() {
11060            let request = client.request(proto::StopLanguageServers {
11061                project_id,
11062                buffer_ids: Vec::new(),
11063                also_servers: Vec::new(),
11064                all: true,
11065            });
11066            cx.background_spawn(async move {
11067                request.await.ok();
11068            })
11069        } else {
11070            let Some(local) = self.as_local_mut() else {
11071                return Task::ready(());
11072            };
11073            let language_servers_to_stop = local
11074                .language_server_ids
11075                .values()
11076                .map(|state| state.id)
11077                .collect();
11078            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11079            let tasks = language_servers_to_stop
11080                .into_iter()
11081                .map(|server| self.stop_local_language_server(server, cx))
11082                .collect::<Vec<_>>();
11083            cx.background_spawn(async move {
11084                futures::future::join_all(tasks).await;
11085            })
11086        }
11087    }
11088
11089    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11090        let buffers = self.buffer_store.read(cx).buffers().collect();
11091        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11092    }
11093
11094    pub fn restart_language_servers_for_buffers(
11095        &mut self,
11096        buffers: Vec<Entity<Buffer>>,
11097        only_restart_servers: HashSet<LanguageServerSelector>,
11098        cx: &mut Context<Self>,
11099    ) {
11100        if let Some((client, project_id)) = self.upstream_client() {
11101            let request = client.request(proto::RestartLanguageServers {
11102                project_id,
11103                buffer_ids: buffers
11104                    .into_iter()
11105                    .map(|b| b.read(cx).remote_id().to_proto())
11106                    .collect(),
11107                only_servers: only_restart_servers
11108                    .into_iter()
11109                    .map(|selector| {
11110                        let selector = match selector {
11111                            LanguageServerSelector::Id(language_server_id) => {
11112                                proto::language_server_selector::Selector::ServerId(
11113                                    language_server_id.to_proto(),
11114                                )
11115                            }
11116                            LanguageServerSelector::Name(language_server_name) => {
11117                                proto::language_server_selector::Selector::Name(
11118                                    language_server_name.to_string(),
11119                                )
11120                            }
11121                        };
11122                        proto::LanguageServerSelector {
11123                            selector: Some(selector),
11124                        }
11125                    })
11126                    .collect(),
11127                all: false,
11128            });
11129            cx.background_spawn(request).detach_and_log_err(cx);
11130        } else {
11131            let stop_task = if only_restart_servers.is_empty() {
11132                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11133            } else {
11134                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11135            };
11136            cx.spawn(async move |lsp_store, cx| {
11137                stop_task.await;
11138                lsp_store.update(cx, |lsp_store, cx| {
11139                    for buffer in buffers {
11140                        lsp_store.register_buffer_with_language_servers(
11141                            &buffer,
11142                            only_restart_servers.clone(),
11143                            true,
11144                            cx,
11145                        );
11146                    }
11147                })
11148            })
11149            .detach();
11150        }
11151    }
11152
11153    pub fn stop_language_servers_for_buffers(
11154        &mut self,
11155        buffers: Vec<Entity<Buffer>>,
11156        also_stop_servers: HashSet<LanguageServerSelector>,
11157        cx: &mut Context<Self>,
11158    ) -> Task<Result<()>> {
11159        if let Some((client, project_id)) = self.upstream_client() {
11160            let request = client.request(proto::StopLanguageServers {
11161                project_id,
11162                buffer_ids: buffers
11163                    .into_iter()
11164                    .map(|b| b.read(cx).remote_id().to_proto())
11165                    .collect(),
11166                also_servers: also_stop_servers
11167                    .into_iter()
11168                    .map(|selector| {
11169                        let selector = match selector {
11170                            LanguageServerSelector::Id(language_server_id) => {
11171                                proto::language_server_selector::Selector::ServerId(
11172                                    language_server_id.to_proto(),
11173                                )
11174                            }
11175                            LanguageServerSelector::Name(language_server_name) => {
11176                                proto::language_server_selector::Selector::Name(
11177                                    language_server_name.to_string(),
11178                                )
11179                            }
11180                        };
11181                        proto::LanguageServerSelector {
11182                            selector: Some(selector),
11183                        }
11184                    })
11185                    .collect(),
11186                all: false,
11187            });
11188            cx.background_spawn(async move {
11189                let _ = request.await?;
11190                Ok(())
11191            })
11192        } else {
11193            let task =
11194                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11195            cx.background_spawn(async move {
11196                task.await;
11197                Ok(())
11198            })
11199        }
11200    }
11201
11202    fn stop_local_language_servers_for_buffers(
11203        &mut self,
11204        buffers: &[Entity<Buffer>],
11205        also_stop_servers: HashSet<LanguageServerSelector>,
11206        cx: &mut Context<Self>,
11207    ) -> Task<()> {
11208        let Some(local) = self.as_local_mut() else {
11209            return Task::ready(());
11210        };
11211        let mut language_server_names_to_stop = BTreeSet::default();
11212        let mut language_servers_to_stop = also_stop_servers
11213            .into_iter()
11214            .flat_map(|selector| match selector {
11215                LanguageServerSelector::Id(id) => Some(id),
11216                LanguageServerSelector::Name(name) => {
11217                    language_server_names_to_stop.insert(name);
11218                    None
11219                }
11220            })
11221            .collect::<BTreeSet<_>>();
11222
11223        let mut covered_worktrees = HashSet::default();
11224        for buffer in buffers {
11225            buffer.update(cx, |buffer, cx| {
11226                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11227                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11228                    && covered_worktrees.insert(worktree_id)
11229                {
11230                    language_server_names_to_stop.retain(|name| {
11231                        let old_ids_count = language_servers_to_stop.len();
11232                        let all_language_servers_with_this_name = local
11233                            .language_server_ids
11234                            .iter()
11235                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11236                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11237                        old_ids_count == language_servers_to_stop.len()
11238                    });
11239                }
11240            });
11241        }
11242        for name in language_server_names_to_stop {
11243            language_servers_to_stop.extend(
11244                local
11245                    .language_server_ids
11246                    .iter()
11247                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11248            );
11249        }
11250
11251        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11252        let tasks = language_servers_to_stop
11253            .into_iter()
11254            .map(|server| self.stop_local_language_server(server, cx))
11255            .collect::<Vec<_>>();
11256
11257        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11258    }
11259
11260    #[cfg(any(test, feature = "test-support"))]
11261    pub fn update_diagnostics(
11262        &mut self,
11263        server_id: LanguageServerId,
11264        diagnostics: lsp::PublishDiagnosticsParams,
11265        result_id: Option<SharedString>,
11266        source_kind: DiagnosticSourceKind,
11267        disk_based_sources: &[String],
11268        cx: &mut Context<Self>,
11269    ) -> Result<()> {
11270        self.merge_lsp_diagnostics(
11271            source_kind,
11272            vec![DocumentDiagnosticsUpdate {
11273                diagnostics,
11274                result_id,
11275                server_id,
11276                disk_based_sources: Cow::Borrowed(disk_based_sources),
11277                registration_id: None,
11278            }],
11279            |_, _, _| false,
11280            cx,
11281        )
11282    }
11283
11284    pub fn merge_lsp_diagnostics(
11285        &mut self,
11286        source_kind: DiagnosticSourceKind,
11287        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11288        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11289        cx: &mut Context<Self>,
11290    ) -> Result<()> {
11291        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11292        let updates = lsp_diagnostics
11293            .into_iter()
11294            .filter_map(|update| {
11295                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11296                Some(DocumentDiagnosticsUpdate {
11297                    diagnostics: self.lsp_to_document_diagnostics(
11298                        abs_path,
11299                        source_kind,
11300                        update.server_id,
11301                        update.diagnostics,
11302                        &update.disk_based_sources,
11303                        update.registration_id.clone(),
11304                    ),
11305                    result_id: update.result_id,
11306                    server_id: update.server_id,
11307                    disk_based_sources: update.disk_based_sources,
11308                    registration_id: update.registration_id,
11309                })
11310            })
11311            .collect();
11312        self.merge_diagnostic_entries(updates, merge, cx)?;
11313        Ok(())
11314    }
11315
11316    fn lsp_to_document_diagnostics(
11317        &mut self,
11318        document_abs_path: PathBuf,
11319        source_kind: DiagnosticSourceKind,
11320        server_id: LanguageServerId,
11321        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11322        disk_based_sources: &[String],
11323        registration_id: Option<SharedString>,
11324    ) -> DocumentDiagnostics {
11325        let mut diagnostics = Vec::default();
11326        let mut primary_diagnostic_group_ids = HashMap::default();
11327        let mut sources_by_group_id = HashMap::default();
11328        let mut supporting_diagnostics = HashMap::default();
11329
11330        let adapter = self.language_server_adapter_for_id(server_id);
11331
11332        // Ensure that primary diagnostics are always the most severe
11333        lsp_diagnostics
11334            .diagnostics
11335            .sort_by_key(|item| item.severity);
11336
11337        for diagnostic in &lsp_diagnostics.diagnostics {
11338            let source = diagnostic.source.as_ref();
11339            let range = range_from_lsp(diagnostic.range);
11340            let is_supporting = diagnostic
11341                .related_information
11342                .as_ref()
11343                .is_some_and(|infos| {
11344                    infos.iter().any(|info| {
11345                        primary_diagnostic_group_ids.contains_key(&(
11346                            source,
11347                            diagnostic.code.clone(),
11348                            range_from_lsp(info.location.range),
11349                        ))
11350                    })
11351                });
11352
11353            let is_unnecessary = diagnostic
11354                .tags
11355                .as_ref()
11356                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11357
11358            let underline = self
11359                .language_server_adapter_for_id(server_id)
11360                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11361
11362            if is_supporting {
11363                supporting_diagnostics.insert(
11364                    (source, diagnostic.code.clone(), range),
11365                    (diagnostic.severity, is_unnecessary),
11366                );
11367            } else {
11368                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11369                let is_disk_based =
11370                    source.is_some_and(|source| disk_based_sources.contains(source));
11371
11372                sources_by_group_id.insert(group_id, source);
11373                primary_diagnostic_group_ids
11374                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11375
11376                diagnostics.push(DiagnosticEntry {
11377                    range,
11378                    diagnostic: Diagnostic {
11379                        source: diagnostic.source.clone(),
11380                        source_kind,
11381                        code: diagnostic.code.clone(),
11382                        code_description: diagnostic
11383                            .code_description
11384                            .as_ref()
11385                            .and_then(|d| d.href.clone()),
11386                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11387                        markdown: adapter.as_ref().and_then(|adapter| {
11388                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11389                        }),
11390                        message: diagnostic.message.trim().to_string(),
11391                        group_id,
11392                        is_primary: true,
11393                        is_disk_based,
11394                        is_unnecessary,
11395                        underline,
11396                        data: diagnostic.data.clone(),
11397                        registration_id: registration_id.clone(),
11398                    },
11399                });
11400                if let Some(infos) = &diagnostic.related_information {
11401                    for info in infos {
11402                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11403                            let range = range_from_lsp(info.location.range);
11404                            diagnostics.push(DiagnosticEntry {
11405                                range,
11406                                diagnostic: Diagnostic {
11407                                    source: diagnostic.source.clone(),
11408                                    source_kind,
11409                                    code: diagnostic.code.clone(),
11410                                    code_description: diagnostic
11411                                        .code_description
11412                                        .as_ref()
11413                                        .and_then(|d| d.href.clone()),
11414                                    severity: DiagnosticSeverity::INFORMATION,
11415                                    markdown: adapter.as_ref().and_then(|adapter| {
11416                                        adapter.diagnostic_message_to_markdown(&info.message)
11417                                    }),
11418                                    message: info.message.trim().to_string(),
11419                                    group_id,
11420                                    is_primary: false,
11421                                    is_disk_based,
11422                                    is_unnecessary: false,
11423                                    underline,
11424                                    data: diagnostic.data.clone(),
11425                                    registration_id: registration_id.clone(),
11426                                },
11427                            });
11428                        }
11429                    }
11430                }
11431            }
11432        }
11433
11434        for entry in &mut diagnostics {
11435            let diagnostic = &mut entry.diagnostic;
11436            if !diagnostic.is_primary {
11437                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11438                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11439                    source,
11440                    diagnostic.code.clone(),
11441                    entry.range.clone(),
11442                )) {
11443                    if let Some(severity) = severity {
11444                        diagnostic.severity = severity;
11445                    }
11446                    diagnostic.is_unnecessary = is_unnecessary;
11447                }
11448            }
11449        }
11450
11451        DocumentDiagnostics {
11452            diagnostics,
11453            document_abs_path,
11454            version: lsp_diagnostics.version,
11455        }
11456    }
11457
11458    fn insert_newly_running_language_server(
11459        &mut self,
11460        adapter: Arc<CachedLspAdapter>,
11461        language_server: Arc<LanguageServer>,
11462        server_id: LanguageServerId,
11463        key: LanguageServerSeed,
11464        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11465        cx: &mut Context<Self>,
11466    ) {
11467        let Some(local) = self.as_local_mut() else {
11468            return;
11469        };
11470        // If the language server for this key doesn't match the server id, don't store the
11471        // server. Which will cause it to be dropped, killing the process
11472        if local
11473            .language_server_ids
11474            .get(&key)
11475            .map(|state| state.id != server_id)
11476            .unwrap_or(false)
11477        {
11478            return;
11479        }
11480
11481        // Update language_servers collection with Running variant of LanguageServerState
11482        // indicating that the server is up and running and ready
11483        let workspace_folders = workspace_folders.lock().clone();
11484        language_server.set_workspace_folders(workspace_folders);
11485
11486        let workspace_diagnostics_refresh_tasks = language_server
11487            .capabilities()
11488            .diagnostic_provider
11489            .and_then(|provider| {
11490                local
11491                    .language_server_dynamic_registrations
11492                    .entry(server_id)
11493                    .or_default()
11494                    .diagnostics
11495                    .entry(None)
11496                    .or_insert(provider.clone());
11497                let workspace_refresher =
11498                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11499
11500                Some((None, workspace_refresher))
11501            })
11502            .into_iter()
11503            .collect();
11504        local.language_servers.insert(
11505            server_id,
11506            LanguageServerState::Running {
11507                workspace_diagnostics_refresh_tasks,
11508                adapter: adapter.clone(),
11509                server: language_server.clone(),
11510                simulate_disk_based_diagnostics_completion: None,
11511            },
11512        );
11513        local
11514            .languages
11515            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11516        if let Some(file_ops_caps) = language_server
11517            .capabilities()
11518            .workspace
11519            .as_ref()
11520            .and_then(|ws| ws.file_operations.as_ref())
11521        {
11522            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11523            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11524            if did_rename_caps.or(will_rename_caps).is_some() {
11525                let watcher = RenamePathsWatchedForServer::default()
11526                    .with_did_rename_patterns(did_rename_caps)
11527                    .with_will_rename_patterns(will_rename_caps);
11528                local
11529                    .language_server_paths_watched_for_rename
11530                    .insert(server_id, watcher);
11531            }
11532        }
11533
11534        self.language_server_statuses.insert(
11535            server_id,
11536            LanguageServerStatus {
11537                name: language_server.name(),
11538                server_version: language_server.version(),
11539                server_readable_version: language_server.readable_version(),
11540                pending_work: Default::default(),
11541                has_pending_diagnostic_updates: false,
11542                progress_tokens: Default::default(),
11543                worktree: Some(key.worktree_id),
11544                binary: Some(language_server.binary().clone()),
11545                configuration: Some(language_server.configuration().clone()),
11546                workspace_folders: language_server.workspace_folders(),
11547                process_id: language_server.process_id(),
11548            },
11549        );
11550
11551        cx.emit(LspStoreEvent::LanguageServerAdded(
11552            server_id,
11553            language_server.name(),
11554            Some(key.worktree_id),
11555        ));
11556
11557        let server_capabilities = language_server.capabilities();
11558        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11559            downstream_client
11560                .send(proto::StartLanguageServer {
11561                    project_id: *project_id,
11562                    server: Some(proto::LanguageServer {
11563                        id: server_id.to_proto(),
11564                        name: language_server.name().to_string(),
11565                        worktree_id: Some(key.worktree_id.to_proto()),
11566                    }),
11567                    capabilities: serde_json::to_string(&server_capabilities)
11568                        .expect("serializing server LSP capabilities"),
11569                })
11570                .log_err();
11571        }
11572        self.lsp_server_capabilities
11573            .insert(server_id, server_capabilities);
11574
11575        // Tell the language server about every open buffer in the worktree that matches the language.
11576        // Also check for buffers in worktrees that reused this server
11577        let mut worktrees_using_server = vec![key.worktree_id];
11578        if let Some(local) = self.as_local() {
11579            // Find all worktrees that have this server in their language server tree
11580            for (worktree_id, servers) in &local.lsp_tree.instances {
11581                if *worktree_id != key.worktree_id {
11582                    for server_map in servers.roots.values() {
11583                        if server_map
11584                            .values()
11585                            .any(|(node, _)| node.id() == Some(server_id))
11586                        {
11587                            worktrees_using_server.push(*worktree_id);
11588                        }
11589                    }
11590                }
11591            }
11592        }
11593
11594        let mut buffer_paths_registered = Vec::new();
11595        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11596            let mut lsp_adapters = HashMap::default();
11597            for buffer_handle in buffer_store.buffers() {
11598                let buffer = buffer_handle.read(cx);
11599                let file = match File::from_dyn(buffer.file()) {
11600                    Some(file) => file,
11601                    None => continue,
11602                };
11603                let language = match buffer.language() {
11604                    Some(language) => language,
11605                    None => continue,
11606                };
11607
11608                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11609                    || !lsp_adapters
11610                        .entry(language.name())
11611                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11612                        .iter()
11613                        .any(|a| a.name == key.name)
11614                {
11615                    continue;
11616                }
11617                // didOpen
11618                let file = match file.as_local() {
11619                    Some(file) => file,
11620                    None => continue,
11621                };
11622
11623                let local = self.as_local_mut().unwrap();
11624
11625                let buffer_id = buffer.remote_id();
11626                if local.registered_buffers.contains_key(&buffer_id) {
11627                    let abs_path = file.abs_path(cx);
11628                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11629                        Ok(uri) => uri,
11630                        Err(()) => {
11631                            log::error!("failed to convert path to URI: {:?}", abs_path);
11632                            continue;
11633                        }
11634                    };
11635
11636                    let versions = local
11637                        .buffer_snapshots
11638                        .entry(buffer_id)
11639                        .or_default()
11640                        .entry(server_id)
11641                        .and_modify(|_| {
11642                            assert!(
11643                            false,
11644                            "There should not be an existing snapshot for a newly inserted buffer"
11645                        )
11646                        })
11647                        .or_insert_with(|| {
11648                            vec![LspBufferSnapshot {
11649                                version: 0,
11650                                snapshot: buffer.text_snapshot(),
11651                            }]
11652                        });
11653
11654                    let snapshot = versions.last().unwrap();
11655                    let version = snapshot.version;
11656                    let initial_snapshot = &snapshot.snapshot;
11657                    language_server.register_buffer(
11658                        uri,
11659                        adapter.language_id(&language.name()),
11660                        version,
11661                        initial_snapshot.text(),
11662                    );
11663                    buffer_paths_registered.push((buffer_id, abs_path));
11664                    local
11665                        .buffers_opened_in_servers
11666                        .entry(buffer_id)
11667                        .or_default()
11668                        .insert(server_id);
11669                }
11670                buffer_handle.update(cx, |buffer, cx| {
11671                    buffer.set_completion_triggers(
11672                        server_id,
11673                        language_server
11674                            .capabilities()
11675                            .completion_provider
11676                            .as_ref()
11677                            .and_then(|provider| {
11678                                provider
11679                                    .trigger_characters
11680                                    .as_ref()
11681                                    .map(|characters| characters.iter().cloned().collect())
11682                            })
11683                            .unwrap_or_default(),
11684                        cx,
11685                    )
11686                });
11687            }
11688        });
11689
11690        for (buffer_id, abs_path) in buffer_paths_registered {
11691            cx.emit(LspStoreEvent::LanguageServerUpdate {
11692                language_server_id: server_id,
11693                name: Some(adapter.name()),
11694                message: proto::update_language_server::Variant::RegisteredForBuffer(
11695                    proto::RegisteredForBuffer {
11696                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11697                        buffer_id: buffer_id.to_proto(),
11698                    },
11699                ),
11700            });
11701        }
11702
11703        cx.notify();
11704    }
11705
11706    pub fn language_servers_running_disk_based_diagnostics(
11707        &self,
11708    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11709        self.language_server_statuses
11710            .iter()
11711            .filter_map(|(id, status)| {
11712                if status.has_pending_diagnostic_updates {
11713                    Some(*id)
11714                } else {
11715                    None
11716                }
11717            })
11718    }
11719
11720    pub(crate) fn cancel_language_server_work_for_buffers(
11721        &mut self,
11722        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11723        cx: &mut Context<Self>,
11724    ) {
11725        if let Some((client, project_id)) = self.upstream_client() {
11726            let request = client.request(proto::CancelLanguageServerWork {
11727                project_id,
11728                work: Some(proto::cancel_language_server_work::Work::Buffers(
11729                    proto::cancel_language_server_work::Buffers {
11730                        buffer_ids: buffers
11731                            .into_iter()
11732                            .map(|b| b.read(cx).remote_id().to_proto())
11733                            .collect(),
11734                    },
11735                )),
11736            });
11737            cx.background_spawn(request).detach_and_log_err(cx);
11738        } else if let Some(local) = self.as_local() {
11739            let servers = buffers
11740                .into_iter()
11741                .flat_map(|buffer| {
11742                    buffer.update(cx, |buffer, cx| {
11743                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11744                    })
11745                })
11746                .collect::<HashSet<_>>();
11747            for server_id in servers {
11748                self.cancel_language_server_work(server_id, None, cx);
11749            }
11750        }
11751    }
11752
11753    pub(crate) fn cancel_language_server_work(
11754        &mut self,
11755        server_id: LanguageServerId,
11756        token_to_cancel: Option<ProgressToken>,
11757        cx: &mut Context<Self>,
11758    ) {
11759        if let Some(local) = self.as_local() {
11760            let status = self.language_server_statuses.get(&server_id);
11761            let server = local.language_servers.get(&server_id);
11762            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11763            {
11764                for (token, progress) in &status.pending_work {
11765                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11766                        && token != token_to_cancel
11767                    {
11768                        continue;
11769                    }
11770                    if progress.is_cancellable {
11771                        server
11772                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11773                                WorkDoneProgressCancelParams {
11774                                    token: token.to_lsp(),
11775                                },
11776                            )
11777                            .ok();
11778                    }
11779                }
11780            }
11781        } else if let Some((client, project_id)) = self.upstream_client() {
11782            let request = client.request(proto::CancelLanguageServerWork {
11783                project_id,
11784                work: Some(
11785                    proto::cancel_language_server_work::Work::LanguageServerWork(
11786                        proto::cancel_language_server_work::LanguageServerWork {
11787                            language_server_id: server_id.to_proto(),
11788                            token: token_to_cancel.map(|token| token.to_proto()),
11789                        },
11790                    ),
11791                ),
11792            });
11793            cx.background_spawn(request).detach_and_log_err(cx);
11794        }
11795    }
11796
11797    fn register_supplementary_language_server(
11798        &mut self,
11799        id: LanguageServerId,
11800        name: LanguageServerName,
11801        server: Arc<LanguageServer>,
11802        cx: &mut Context<Self>,
11803    ) {
11804        if let Some(local) = self.as_local_mut() {
11805            local
11806                .supplementary_language_servers
11807                .insert(id, (name.clone(), server));
11808            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11809        }
11810    }
11811
11812    fn unregister_supplementary_language_server(
11813        &mut self,
11814        id: LanguageServerId,
11815        cx: &mut Context<Self>,
11816    ) {
11817        if let Some(local) = self.as_local_mut() {
11818            local.supplementary_language_servers.remove(&id);
11819            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11820        }
11821    }
11822
11823    pub(crate) fn supplementary_language_servers(
11824        &self,
11825    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11826        self.as_local().into_iter().flat_map(|local| {
11827            local
11828                .supplementary_language_servers
11829                .iter()
11830                .map(|(id, (name, _))| (*id, name.clone()))
11831        })
11832    }
11833
11834    pub fn language_server_adapter_for_id(
11835        &self,
11836        id: LanguageServerId,
11837    ) -> Option<Arc<CachedLspAdapter>> {
11838        self.as_local()
11839            .and_then(|local| local.language_servers.get(&id))
11840            .and_then(|language_server_state| match language_server_state {
11841                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11842                _ => None,
11843            })
11844    }
11845
11846    pub(super) fn update_local_worktree_language_servers(
11847        &mut self,
11848        worktree_handle: &Entity<Worktree>,
11849        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11850        cx: &mut Context<Self>,
11851    ) {
11852        if changes.is_empty() {
11853            return;
11854        }
11855
11856        let Some(local) = self.as_local() else { return };
11857
11858        local.prettier_store.update(cx, |prettier_store, cx| {
11859            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11860        });
11861
11862        let worktree_id = worktree_handle.read(cx).id();
11863        let mut language_server_ids = local
11864            .language_server_ids
11865            .iter()
11866            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11867            .collect::<Vec<_>>();
11868        language_server_ids.sort();
11869        language_server_ids.dedup();
11870
11871        // let abs_path = worktree_handle.read(cx).abs_path();
11872        for server_id in &language_server_ids {
11873            if let Some(LanguageServerState::Running { server, .. }) =
11874                local.language_servers.get(server_id)
11875                && let Some(watched_paths) = local
11876                    .language_server_watched_paths
11877                    .get(server_id)
11878                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11879            {
11880                let params = lsp::DidChangeWatchedFilesParams {
11881                    changes: changes
11882                        .iter()
11883                        .filter_map(|(path, _, change)| {
11884                            if !watched_paths.is_match(path.as_std_path()) {
11885                                return None;
11886                            }
11887                            let typ = match change {
11888                                PathChange::Loaded => return None,
11889                                PathChange::Added => lsp::FileChangeType::CREATED,
11890                                PathChange::Removed => lsp::FileChangeType::DELETED,
11891                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11892                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11893                            };
11894                            let uri = lsp::Uri::from_file_path(
11895                                worktree_handle.read(cx).absolutize(&path),
11896                            )
11897                            .ok()?;
11898                            Some(lsp::FileEvent { uri, typ })
11899                        })
11900                        .collect(),
11901                };
11902                if !params.changes.is_empty() {
11903                    server
11904                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11905                        .ok();
11906                }
11907            }
11908        }
11909        for (path, _, _) in changes {
11910            if let Some(file_name) = path.file_name()
11911                && local.watched_manifest_filenames.contains(file_name)
11912            {
11913                self.request_workspace_config_refresh();
11914                break;
11915            }
11916        }
11917    }
11918
11919    pub fn wait_for_remote_buffer(
11920        &mut self,
11921        id: BufferId,
11922        cx: &mut Context<Self>,
11923    ) -> Task<Result<Entity<Buffer>>> {
11924        self.buffer_store.update(cx, |buffer_store, cx| {
11925            buffer_store.wait_for_remote_buffer(id, cx)
11926        })
11927    }
11928
11929    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11930        let mut result = proto::Symbol {
11931            language_server_name: symbol.language_server_name.0.to_string(),
11932            source_worktree_id: symbol.source_worktree_id.to_proto(),
11933            language_server_id: symbol.source_language_server_id.to_proto(),
11934            name: symbol.name.clone(),
11935            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11936            start: Some(proto::PointUtf16 {
11937                row: symbol.range.start.0.row,
11938                column: symbol.range.start.0.column,
11939            }),
11940            end: Some(proto::PointUtf16 {
11941                row: symbol.range.end.0.row,
11942                column: symbol.range.end.0.column,
11943            }),
11944            worktree_id: Default::default(),
11945            path: Default::default(),
11946            signature: Default::default(),
11947            container_name: symbol.container_name.clone(),
11948        };
11949        match &symbol.path {
11950            SymbolLocation::InProject(path) => {
11951                result.worktree_id = path.worktree_id.to_proto();
11952                result.path = path.path.to_proto();
11953            }
11954            SymbolLocation::OutsideProject {
11955                abs_path,
11956                signature,
11957            } => {
11958                result.path = abs_path.to_string_lossy().into_owned();
11959                result.signature = signature.to_vec();
11960            }
11961        }
11962        result
11963    }
11964
11965    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11966        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11967        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11968        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11969
11970        let path = if serialized_symbol.signature.is_empty() {
11971            SymbolLocation::InProject(ProjectPath {
11972                worktree_id,
11973                path: RelPath::from_proto(&serialized_symbol.path)
11974                    .context("invalid symbol path")?,
11975            })
11976        } else {
11977            SymbolLocation::OutsideProject {
11978                abs_path: Path::new(&serialized_symbol.path).into(),
11979                signature: serialized_symbol
11980                    .signature
11981                    .try_into()
11982                    .map_err(|_| anyhow!("invalid signature"))?,
11983            }
11984        };
11985
11986        let start = serialized_symbol.start.context("invalid start")?;
11987        let end = serialized_symbol.end.context("invalid end")?;
11988        Ok(CoreSymbol {
11989            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11990            source_worktree_id,
11991            source_language_server_id: LanguageServerId::from_proto(
11992                serialized_symbol.language_server_id,
11993            ),
11994            path,
11995            name: serialized_symbol.name,
11996            range: Unclipped(PointUtf16::new(start.row, start.column))
11997                ..Unclipped(PointUtf16::new(end.row, end.column)),
11998            kind,
11999            container_name: serialized_symbol.container_name,
12000        })
12001    }
12002
12003    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12004        let mut serialized_completion = proto::Completion {
12005            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12006            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12007            new_text: completion.new_text.clone(),
12008            ..proto::Completion::default()
12009        };
12010        match &completion.source {
12011            CompletionSource::Lsp {
12012                insert_range,
12013                server_id,
12014                lsp_completion,
12015                lsp_defaults,
12016                resolved,
12017            } => {
12018                let (old_insert_start, old_insert_end) = insert_range
12019                    .as_ref()
12020                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12021                    .unzip();
12022
12023                serialized_completion.old_insert_start = old_insert_start;
12024                serialized_completion.old_insert_end = old_insert_end;
12025                serialized_completion.source = proto::completion::Source::Lsp as i32;
12026                serialized_completion.server_id = server_id.0 as u64;
12027                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12028                serialized_completion.lsp_defaults = lsp_defaults
12029                    .as_deref()
12030                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12031                serialized_completion.resolved = *resolved;
12032            }
12033            CompletionSource::BufferWord {
12034                word_range,
12035                resolved,
12036            } => {
12037                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12038                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12039                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12040                serialized_completion.resolved = *resolved;
12041            }
12042            CompletionSource::Custom => {
12043                serialized_completion.source = proto::completion::Source::Custom as i32;
12044                serialized_completion.resolved = true;
12045            }
12046            CompletionSource::Dap { sort_text } => {
12047                serialized_completion.source = proto::completion::Source::Dap as i32;
12048                serialized_completion.sort_text = Some(sort_text.clone());
12049            }
12050        }
12051
12052        serialized_completion
12053    }
12054
12055    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12056        let old_replace_start = completion
12057            .old_replace_start
12058            .and_then(deserialize_anchor)
12059            .context("invalid old start")?;
12060        let old_replace_end = completion
12061            .old_replace_end
12062            .and_then(deserialize_anchor)
12063            .context("invalid old end")?;
12064        let insert_range = {
12065            match completion.old_insert_start.zip(completion.old_insert_end) {
12066                Some((start, end)) => {
12067                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12068                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12069                    Some(start..end)
12070                }
12071                None => None,
12072            }
12073        };
12074        Ok(CoreCompletion {
12075            replace_range: old_replace_start..old_replace_end,
12076            new_text: completion.new_text,
12077            source: match proto::completion::Source::from_i32(completion.source) {
12078                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12079                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12080                    insert_range,
12081                    server_id: LanguageServerId::from_proto(completion.server_id),
12082                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12083                    lsp_defaults: completion
12084                        .lsp_defaults
12085                        .as_deref()
12086                        .map(serde_json::from_slice)
12087                        .transpose()?,
12088                    resolved: completion.resolved,
12089                },
12090                Some(proto::completion::Source::BufferWord) => {
12091                    let word_range = completion
12092                        .buffer_word_start
12093                        .and_then(deserialize_anchor)
12094                        .context("invalid buffer word start")?
12095                        ..completion
12096                            .buffer_word_end
12097                            .and_then(deserialize_anchor)
12098                            .context("invalid buffer word end")?;
12099                    CompletionSource::BufferWord {
12100                        word_range,
12101                        resolved: completion.resolved,
12102                    }
12103                }
12104                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12105                    sort_text: completion
12106                        .sort_text
12107                        .context("expected sort text to exist")?,
12108                },
12109                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12110            },
12111        })
12112    }
12113
12114    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12115        let (kind, lsp_action) = match &action.lsp_action {
12116            LspAction::Action(code_action) => (
12117                proto::code_action::Kind::Action as i32,
12118                serde_json::to_vec(code_action).unwrap(),
12119            ),
12120            LspAction::Command(command) => (
12121                proto::code_action::Kind::Command as i32,
12122                serde_json::to_vec(command).unwrap(),
12123            ),
12124            LspAction::CodeLens(code_lens) => (
12125                proto::code_action::Kind::CodeLens as i32,
12126                serde_json::to_vec(code_lens).unwrap(),
12127            ),
12128        };
12129
12130        proto::CodeAction {
12131            server_id: action.server_id.0 as u64,
12132            start: Some(serialize_anchor(&action.range.start)),
12133            end: Some(serialize_anchor(&action.range.end)),
12134            lsp_action,
12135            kind,
12136            resolved: action.resolved,
12137        }
12138    }
12139
12140    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12141        let start = action
12142            .start
12143            .and_then(deserialize_anchor)
12144            .context("invalid start")?;
12145        let end = action
12146            .end
12147            .and_then(deserialize_anchor)
12148            .context("invalid end")?;
12149        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12150            Some(proto::code_action::Kind::Action) => {
12151                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12152            }
12153            Some(proto::code_action::Kind::Command) => {
12154                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12155            }
12156            Some(proto::code_action::Kind::CodeLens) => {
12157                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12158            }
12159            None => anyhow::bail!("Unknown action kind {}", action.kind),
12160        };
12161        Ok(CodeAction {
12162            server_id: LanguageServerId(action.server_id as usize),
12163            range: start..end,
12164            resolved: action.resolved,
12165            lsp_action,
12166        })
12167    }
12168
12169    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12170        match &formatting_result {
12171            Ok(_) => self.last_formatting_failure = None,
12172            Err(error) => {
12173                let error_string = format!("{error:#}");
12174                log::error!("Formatting failed: {error_string}");
12175                self.last_formatting_failure
12176                    .replace(error_string.lines().join(" "));
12177            }
12178        }
12179    }
12180
12181    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12182        self.lsp_server_capabilities.remove(&for_server);
12183        self.semantic_token_config.remove_server_data(for_server);
12184        for lsp_data in self.lsp_data.values_mut() {
12185            lsp_data.remove_server_data(for_server);
12186        }
12187        if let Some(local) = self.as_local_mut() {
12188            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12189            local
12190                .workspace_pull_diagnostics_result_ids
12191                .remove(&for_server);
12192            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12193                buffer_servers.remove(&for_server);
12194            }
12195        }
12196    }
12197
12198    pub fn result_id_for_buffer_pull(
12199        &self,
12200        server_id: LanguageServerId,
12201        buffer_id: BufferId,
12202        registration_id: &Option<SharedString>,
12203        cx: &App,
12204    ) -> Option<SharedString> {
12205        let abs_path = self
12206            .buffer_store
12207            .read(cx)
12208            .get(buffer_id)
12209            .and_then(|b| File::from_dyn(b.read(cx).file()))
12210            .map(|f| f.abs_path(cx))?;
12211        self.as_local()?
12212            .buffer_pull_diagnostics_result_ids
12213            .get(&server_id)?
12214            .get(registration_id)?
12215            .get(&abs_path)?
12216            .clone()
12217    }
12218
12219    /// Gets all result_ids for a workspace diagnostics pull request.
12220    /// 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.
12221    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12222    pub fn result_ids_for_workspace_refresh(
12223        &self,
12224        server_id: LanguageServerId,
12225        registration_id: &Option<SharedString>,
12226    ) -> HashMap<PathBuf, SharedString> {
12227        let Some(local) = self.as_local() else {
12228            return HashMap::default();
12229        };
12230        local
12231            .workspace_pull_diagnostics_result_ids
12232            .get(&server_id)
12233            .into_iter()
12234            .filter_map(|diagnostics| diagnostics.get(registration_id))
12235            .flatten()
12236            .filter_map(|(abs_path, result_id)| {
12237                let result_id = local
12238                    .buffer_pull_diagnostics_result_ids
12239                    .get(&server_id)
12240                    .and_then(|buffer_ids_result_ids| {
12241                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12242                    })
12243                    .cloned()
12244                    .flatten()
12245                    .or_else(|| result_id.clone())?;
12246                Some((abs_path.clone(), result_id))
12247            })
12248            .collect()
12249    }
12250
12251    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12252        if let Some(LanguageServerState::Running {
12253            workspace_diagnostics_refresh_tasks,
12254            ..
12255        }) = self
12256            .as_local_mut()
12257            .and_then(|local| local.language_servers.get_mut(&server_id))
12258        {
12259            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12260                diagnostics.refresh_tx.try_send(()).ok();
12261            }
12262        }
12263    }
12264
12265    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12266    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12267    /// which requires refreshing both workspace and document diagnostics.
12268    pub fn pull_document_diagnostics_for_server(
12269        &mut self,
12270        server_id: LanguageServerId,
12271        source_buffer_id: Option<BufferId>,
12272        cx: &mut Context<Self>,
12273    ) -> Shared<Task<()>> {
12274        let Some(local) = self.as_local_mut() else {
12275            return Task::ready(()).shared();
12276        };
12277        let mut buffers_to_refresh = HashSet::default();
12278        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12279            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12280                buffers_to_refresh.insert(*buffer_id);
12281            }
12282        }
12283
12284        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12285    }
12286
12287    pub fn pull_document_diagnostics_for_buffer_edit(
12288        &mut self,
12289        buffer_id: BufferId,
12290        cx: &mut Context<Self>,
12291    ) {
12292        let Some(local) = self.as_local_mut() else {
12293            return;
12294        };
12295        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12296        else {
12297            return;
12298        };
12299        for server_id in languages_servers {
12300            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12301        }
12302    }
12303
12304    fn apply_workspace_diagnostic_report(
12305        &mut self,
12306        server_id: LanguageServerId,
12307        report: lsp::WorkspaceDiagnosticReportResult,
12308        registration_id: Option<SharedString>,
12309        cx: &mut Context<Self>,
12310    ) {
12311        let mut workspace_diagnostics =
12312            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12313                report,
12314                server_id,
12315                registration_id,
12316            );
12317        workspace_diagnostics.retain(|d| match &d.diagnostics {
12318            LspPullDiagnostics::Response {
12319                server_id,
12320                registration_id,
12321                ..
12322            } => self.diagnostic_registration_exists(*server_id, registration_id),
12323            LspPullDiagnostics::Default => false,
12324        });
12325        let mut unchanged_buffers = HashMap::default();
12326        let workspace_diagnostics_updates = workspace_diagnostics
12327            .into_iter()
12328            .filter_map(
12329                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12330                    LspPullDiagnostics::Response {
12331                        server_id,
12332                        uri,
12333                        diagnostics,
12334                        registration_id,
12335                    } => Some((
12336                        server_id,
12337                        uri,
12338                        diagnostics,
12339                        workspace_diagnostics.version,
12340                        registration_id,
12341                    )),
12342                    LspPullDiagnostics::Default => None,
12343                },
12344            )
12345            .fold(
12346                HashMap::default(),
12347                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12348                    let (result_id, diagnostics) = match diagnostics {
12349                        PulledDiagnostics::Unchanged { result_id } => {
12350                            unchanged_buffers
12351                                .entry(new_registration_id.clone())
12352                                .or_insert_with(HashSet::default)
12353                                .insert(uri.clone());
12354                            (Some(result_id), Vec::new())
12355                        }
12356                        PulledDiagnostics::Changed {
12357                            result_id,
12358                            diagnostics,
12359                        } => (result_id, diagnostics),
12360                    };
12361                    let disk_based_sources = Cow::Owned(
12362                        self.language_server_adapter_for_id(server_id)
12363                            .as_ref()
12364                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12365                            .unwrap_or(&[])
12366                            .to_vec(),
12367                    );
12368
12369                    let Some(abs_path) = uri.to_file_path().ok() else {
12370                        return acc;
12371                    };
12372                    let Some((worktree, relative_path)) =
12373                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12374                    else {
12375                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12376                        return acc;
12377                    };
12378                    let worktree_id = worktree.read(cx).id();
12379                    let project_path = ProjectPath {
12380                        worktree_id,
12381                        path: relative_path,
12382                    };
12383                    if let Some(local_lsp_store) = self.as_local_mut() {
12384                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12385                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12386                    }
12387                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12388                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12389                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12390                        acc.entry(server_id)
12391                            .or_insert_with(HashMap::default)
12392                            .entry(new_registration_id.clone())
12393                            .or_insert_with(Vec::new)
12394                            .push(DocumentDiagnosticsUpdate {
12395                                server_id,
12396                                diagnostics: lsp::PublishDiagnosticsParams {
12397                                    uri,
12398                                    diagnostics,
12399                                    version,
12400                                },
12401                                result_id: result_id.map(SharedString::new),
12402                                disk_based_sources,
12403                                registration_id: new_registration_id,
12404                            });
12405                    }
12406                    acc
12407                },
12408            );
12409
12410        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12411            for (registration_id, diagnostic_updates) in diagnostic_updates {
12412                self.merge_lsp_diagnostics(
12413                    DiagnosticSourceKind::Pulled,
12414                    diagnostic_updates,
12415                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12416                        DiagnosticSourceKind::Pulled => {
12417                            old_diagnostic.registration_id != registration_id
12418                                || unchanged_buffers
12419                                    .get(&old_diagnostic.registration_id)
12420                                    .is_some_and(|unchanged_buffers| {
12421                                        unchanged_buffers.contains(&document_uri)
12422                                    })
12423                        }
12424                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12425                    },
12426                    cx,
12427                )
12428                .log_err();
12429            }
12430        }
12431    }
12432
12433    fn register_server_capabilities(
12434        &mut self,
12435        server_id: LanguageServerId,
12436        params: lsp::RegistrationParams,
12437        cx: &mut Context<Self>,
12438    ) -> anyhow::Result<()> {
12439        let server = self
12440            .language_server_for_id(server_id)
12441            .with_context(|| format!("no server {server_id} found"))?;
12442        for reg in params.registrations {
12443            match reg.method.as_str() {
12444                "workspace/didChangeWatchedFiles" => {
12445                    if let Some(options) = reg.register_options {
12446                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12447                            let caps = serde_json::from_value(options)?;
12448                            local_lsp_store
12449                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12450                            true
12451                        } else {
12452                            false
12453                        };
12454                        if notify {
12455                            notify_server_capabilities_updated(&server, cx);
12456                        }
12457                    }
12458                }
12459                "workspace/didChangeConfiguration" => {
12460                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12461                }
12462                "workspace/didChangeWorkspaceFolders" => {
12463                    // In this case register options is an empty object, we can ignore it
12464                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12465                        supported: Some(true),
12466                        change_notifications: Some(OneOf::Right(reg.id)),
12467                    };
12468                    server.update_capabilities(|capabilities| {
12469                        capabilities
12470                            .workspace
12471                            .get_or_insert_default()
12472                            .workspace_folders = Some(caps);
12473                    });
12474                    notify_server_capabilities_updated(&server, cx);
12475                }
12476                "workspace/symbol" => {
12477                    let options = parse_register_capabilities(reg)?;
12478                    server.update_capabilities(|capabilities| {
12479                        capabilities.workspace_symbol_provider = Some(options);
12480                    });
12481                    notify_server_capabilities_updated(&server, cx);
12482                }
12483                "workspace/fileOperations" => {
12484                    if let Some(options) = reg.register_options {
12485                        let caps = serde_json::from_value(options)?;
12486                        server.update_capabilities(|capabilities| {
12487                            capabilities
12488                                .workspace
12489                                .get_or_insert_default()
12490                                .file_operations = Some(caps);
12491                        });
12492                        notify_server_capabilities_updated(&server, cx);
12493                    }
12494                }
12495                "workspace/executeCommand" => {
12496                    if let Some(options) = reg.register_options {
12497                        let options = serde_json::from_value(options)?;
12498                        server.update_capabilities(|capabilities| {
12499                            capabilities.execute_command_provider = Some(options);
12500                        });
12501                        notify_server_capabilities_updated(&server, cx);
12502                    }
12503                }
12504                "textDocument/rangeFormatting" => {
12505                    let options = parse_register_capabilities(reg)?;
12506                    server.update_capabilities(|capabilities| {
12507                        capabilities.document_range_formatting_provider = Some(options);
12508                    });
12509                    notify_server_capabilities_updated(&server, cx);
12510                }
12511                "textDocument/onTypeFormatting" => {
12512                    if let Some(options) = reg
12513                        .register_options
12514                        .map(serde_json::from_value)
12515                        .transpose()?
12516                    {
12517                        server.update_capabilities(|capabilities| {
12518                            capabilities.document_on_type_formatting_provider = Some(options);
12519                        });
12520                        notify_server_capabilities_updated(&server, cx);
12521                    }
12522                }
12523                "textDocument/formatting" => {
12524                    let options = parse_register_capabilities(reg)?;
12525                    server.update_capabilities(|capabilities| {
12526                        capabilities.document_formatting_provider = Some(options);
12527                    });
12528                    notify_server_capabilities_updated(&server, cx);
12529                }
12530                "textDocument/rename" => {
12531                    let options = parse_register_capabilities(reg)?;
12532                    server.update_capabilities(|capabilities| {
12533                        capabilities.rename_provider = Some(options);
12534                    });
12535                    notify_server_capabilities_updated(&server, cx);
12536                }
12537                "textDocument/inlayHint" => {
12538                    let options = parse_register_capabilities(reg)?;
12539                    server.update_capabilities(|capabilities| {
12540                        capabilities.inlay_hint_provider = Some(options);
12541                    });
12542                    notify_server_capabilities_updated(&server, cx);
12543                }
12544                "textDocument/documentSymbol" => {
12545                    let options = parse_register_capabilities(reg)?;
12546                    server.update_capabilities(|capabilities| {
12547                        capabilities.document_symbol_provider = Some(options);
12548                    });
12549                    notify_server_capabilities_updated(&server, cx);
12550                }
12551                "textDocument/codeAction" => {
12552                    let options = parse_register_capabilities(reg)?;
12553                    let provider = match options {
12554                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12555                        OneOf::Right(caps) => caps,
12556                    };
12557                    server.update_capabilities(|capabilities| {
12558                        capabilities.code_action_provider = Some(provider);
12559                    });
12560                    notify_server_capabilities_updated(&server, cx);
12561                }
12562                "textDocument/definition" => {
12563                    let options = parse_register_capabilities(reg)?;
12564                    server.update_capabilities(|capabilities| {
12565                        capabilities.definition_provider = Some(options);
12566                    });
12567                    notify_server_capabilities_updated(&server, cx);
12568                }
12569                "textDocument/completion" => {
12570                    if let Some(caps) = reg
12571                        .register_options
12572                        .map(serde_json::from_value::<CompletionOptions>)
12573                        .transpose()?
12574                    {
12575                        server.update_capabilities(|capabilities| {
12576                            capabilities.completion_provider = Some(caps.clone());
12577                        });
12578
12579                        if let Some(local) = self.as_local() {
12580                            let mut buffers_with_language_server = Vec::new();
12581                            for handle in self.buffer_store.read(cx).buffers() {
12582                                let buffer_id = handle.read(cx).remote_id();
12583                                if local
12584                                    .buffers_opened_in_servers
12585                                    .get(&buffer_id)
12586                                    .filter(|s| s.contains(&server_id))
12587                                    .is_some()
12588                                {
12589                                    buffers_with_language_server.push(handle);
12590                                }
12591                            }
12592                            let triggers = caps
12593                                .trigger_characters
12594                                .unwrap_or_default()
12595                                .into_iter()
12596                                .collect::<BTreeSet<_>>();
12597                            for handle in buffers_with_language_server {
12598                                let triggers = triggers.clone();
12599                                let _ = handle.update(cx, move |buffer, cx| {
12600                                    buffer.set_completion_triggers(server_id, triggers, cx);
12601                                });
12602                            }
12603                        }
12604                        notify_server_capabilities_updated(&server, cx);
12605                    }
12606                }
12607                "textDocument/hover" => {
12608                    let options = parse_register_capabilities(reg)?;
12609                    let provider = match options {
12610                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12611                        OneOf::Right(caps) => caps,
12612                    };
12613                    server.update_capabilities(|capabilities| {
12614                        capabilities.hover_provider = Some(provider);
12615                    });
12616                    notify_server_capabilities_updated(&server, cx);
12617                }
12618                "textDocument/signatureHelp" => {
12619                    if let Some(caps) = reg
12620                        .register_options
12621                        .map(serde_json::from_value)
12622                        .transpose()?
12623                    {
12624                        server.update_capabilities(|capabilities| {
12625                            capabilities.signature_help_provider = Some(caps);
12626                        });
12627                        notify_server_capabilities_updated(&server, cx);
12628                    }
12629                }
12630                "textDocument/didChange" => {
12631                    if let Some(sync_kind) = reg
12632                        .register_options
12633                        .and_then(|opts| opts.get("syncKind").cloned())
12634                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12635                        .transpose()?
12636                    {
12637                        server.update_capabilities(|capabilities| {
12638                            let mut sync_options =
12639                                Self::take_text_document_sync_options(capabilities);
12640                            sync_options.change = Some(sync_kind);
12641                            capabilities.text_document_sync =
12642                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12643                        });
12644                        notify_server_capabilities_updated(&server, cx);
12645                    }
12646                }
12647                "textDocument/didSave" => {
12648                    if let Some(include_text) = reg
12649                        .register_options
12650                        .map(|opts| {
12651                            let transpose = opts
12652                                .get("includeText")
12653                                .cloned()
12654                                .map(serde_json::from_value::<Option<bool>>)
12655                                .transpose();
12656                            match transpose {
12657                                Ok(value) => Ok(value.flatten()),
12658                                Err(e) => Err(e),
12659                            }
12660                        })
12661                        .transpose()?
12662                    {
12663                        server.update_capabilities(|capabilities| {
12664                            let mut sync_options =
12665                                Self::take_text_document_sync_options(capabilities);
12666                            sync_options.save =
12667                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12668                                    include_text,
12669                                }));
12670                            capabilities.text_document_sync =
12671                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12672                        });
12673                        notify_server_capabilities_updated(&server, cx);
12674                    }
12675                }
12676                "textDocument/codeLens" => {
12677                    if let Some(caps) = reg
12678                        .register_options
12679                        .map(serde_json::from_value)
12680                        .transpose()?
12681                    {
12682                        server.update_capabilities(|capabilities| {
12683                            capabilities.code_lens_provider = Some(caps);
12684                        });
12685                        notify_server_capabilities_updated(&server, cx);
12686                    }
12687                }
12688                "textDocument/diagnostic" => {
12689                    if let Some(caps) = reg
12690                        .register_options
12691                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12692                        .transpose()?
12693                    {
12694                        let local = self
12695                            .as_local_mut()
12696                            .context("Expected LSP Store to be local")?;
12697                        let state = local
12698                            .language_servers
12699                            .get_mut(&server_id)
12700                            .context("Could not obtain Language Servers state")?;
12701                        local
12702                            .language_server_dynamic_registrations
12703                            .entry(server_id)
12704                            .or_default()
12705                            .diagnostics
12706                            .insert(Some(reg.id.clone()), caps.clone());
12707
12708                        let supports_workspace_diagnostics =
12709                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12710                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12711                                    diagnostic_options.workspace_diagnostics
12712                                }
12713                                DiagnosticServerCapabilities::RegistrationOptions(
12714                                    diagnostic_registration_options,
12715                                ) => {
12716                                    diagnostic_registration_options
12717                                        .diagnostic_options
12718                                        .workspace_diagnostics
12719                                }
12720                            };
12721
12722                        if supports_workspace_diagnostics(&caps) {
12723                            if let LanguageServerState::Running {
12724                                workspace_diagnostics_refresh_tasks,
12725                                ..
12726                            } = state
12727                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12728                                    Some(reg.id.clone()),
12729                                    caps.clone(),
12730                                    server.clone(),
12731                                    cx,
12732                                )
12733                            {
12734                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12735                            }
12736                        }
12737
12738                        server.update_capabilities(|capabilities| {
12739                            capabilities.diagnostic_provider = Some(caps);
12740                        });
12741
12742                        notify_server_capabilities_updated(&server, cx);
12743
12744                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12745                    }
12746                }
12747                "textDocument/documentColor" => {
12748                    let options = parse_register_capabilities(reg)?;
12749                    let provider = match options {
12750                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12751                        OneOf::Right(caps) => caps,
12752                    };
12753                    server.update_capabilities(|capabilities| {
12754                        capabilities.color_provider = Some(provider);
12755                    });
12756                    notify_server_capabilities_updated(&server, cx);
12757                }
12758                "textDocument/foldingRange" => {
12759                    let options = parse_register_capabilities(reg)?;
12760                    let provider = match options {
12761                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12762                        OneOf::Right(caps) => caps,
12763                    };
12764                    server.update_capabilities(|capabilities| {
12765                        capabilities.folding_range_provider = Some(provider);
12766                    });
12767                    notify_server_capabilities_updated(&server, cx);
12768                }
12769                _ => log::warn!("unhandled capability registration: {reg:?}"),
12770            }
12771        }
12772
12773        Ok(())
12774    }
12775
12776    fn unregister_server_capabilities(
12777        &mut self,
12778        server_id: LanguageServerId,
12779        params: lsp::UnregistrationParams,
12780        cx: &mut Context<Self>,
12781    ) -> anyhow::Result<()> {
12782        let server = self
12783            .language_server_for_id(server_id)
12784            .with_context(|| format!("no server {server_id} found"))?;
12785        for unreg in params.unregisterations.iter() {
12786            match unreg.method.as_str() {
12787                "workspace/didChangeWatchedFiles" => {
12788                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12789                        local_lsp_store
12790                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12791                        true
12792                    } else {
12793                        false
12794                    };
12795                    if notify {
12796                        notify_server_capabilities_updated(&server, cx);
12797                    }
12798                }
12799                "workspace/didChangeConfiguration" => {
12800                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12801                }
12802                "workspace/didChangeWorkspaceFolders" => {
12803                    server.update_capabilities(|capabilities| {
12804                        capabilities
12805                            .workspace
12806                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12807                                workspace_folders: None,
12808                                file_operations: None,
12809                            })
12810                            .workspace_folders = None;
12811                    });
12812                    notify_server_capabilities_updated(&server, cx);
12813                }
12814                "workspace/symbol" => {
12815                    server.update_capabilities(|capabilities| {
12816                        capabilities.workspace_symbol_provider = None
12817                    });
12818                    notify_server_capabilities_updated(&server, cx);
12819                }
12820                "workspace/fileOperations" => {
12821                    server.update_capabilities(|capabilities| {
12822                        capabilities
12823                            .workspace
12824                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12825                                workspace_folders: None,
12826                                file_operations: None,
12827                            })
12828                            .file_operations = None;
12829                    });
12830                    notify_server_capabilities_updated(&server, cx);
12831                }
12832                "workspace/executeCommand" => {
12833                    server.update_capabilities(|capabilities| {
12834                        capabilities.execute_command_provider = None;
12835                    });
12836                    notify_server_capabilities_updated(&server, cx);
12837                }
12838                "textDocument/rangeFormatting" => {
12839                    server.update_capabilities(|capabilities| {
12840                        capabilities.document_range_formatting_provider = None
12841                    });
12842                    notify_server_capabilities_updated(&server, cx);
12843                }
12844                "textDocument/onTypeFormatting" => {
12845                    server.update_capabilities(|capabilities| {
12846                        capabilities.document_on_type_formatting_provider = None;
12847                    });
12848                    notify_server_capabilities_updated(&server, cx);
12849                }
12850                "textDocument/formatting" => {
12851                    server.update_capabilities(|capabilities| {
12852                        capabilities.document_formatting_provider = None;
12853                    });
12854                    notify_server_capabilities_updated(&server, cx);
12855                }
12856                "textDocument/rename" => {
12857                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12858                    notify_server_capabilities_updated(&server, cx);
12859                }
12860                "textDocument/codeAction" => {
12861                    server.update_capabilities(|capabilities| {
12862                        capabilities.code_action_provider = None;
12863                    });
12864                    notify_server_capabilities_updated(&server, cx);
12865                }
12866                "textDocument/definition" => {
12867                    server.update_capabilities(|capabilities| {
12868                        capabilities.definition_provider = None;
12869                    });
12870                    notify_server_capabilities_updated(&server, cx);
12871                }
12872                "textDocument/completion" => {
12873                    server.update_capabilities(|capabilities| {
12874                        capabilities.completion_provider = None;
12875                    });
12876                    notify_server_capabilities_updated(&server, cx);
12877                }
12878                "textDocument/hover" => {
12879                    server.update_capabilities(|capabilities| {
12880                        capabilities.hover_provider = None;
12881                    });
12882                    notify_server_capabilities_updated(&server, cx);
12883                }
12884                "textDocument/signatureHelp" => {
12885                    server.update_capabilities(|capabilities| {
12886                        capabilities.signature_help_provider = None;
12887                    });
12888                    notify_server_capabilities_updated(&server, cx);
12889                }
12890                "textDocument/didChange" => {
12891                    server.update_capabilities(|capabilities| {
12892                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12893                        sync_options.change = None;
12894                        capabilities.text_document_sync =
12895                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12896                    });
12897                    notify_server_capabilities_updated(&server, cx);
12898                }
12899                "textDocument/didSave" => {
12900                    server.update_capabilities(|capabilities| {
12901                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12902                        sync_options.save = None;
12903                        capabilities.text_document_sync =
12904                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12905                    });
12906                    notify_server_capabilities_updated(&server, cx);
12907                }
12908                "textDocument/codeLens" => {
12909                    server.update_capabilities(|capabilities| {
12910                        capabilities.code_lens_provider = None;
12911                    });
12912                    notify_server_capabilities_updated(&server, cx);
12913                }
12914                "textDocument/diagnostic" => {
12915                    let local = self
12916                        .as_local_mut()
12917                        .context("Expected LSP Store to be local")?;
12918
12919                    let state = local
12920                        .language_servers
12921                        .get_mut(&server_id)
12922                        .context("Could not obtain Language Servers state")?;
12923                    let registrations = local
12924                        .language_server_dynamic_registrations
12925                        .get_mut(&server_id)
12926                        .with_context(|| {
12927                            format!("Expected dynamic registration to exist for server {server_id}")
12928                        })?;
12929                    registrations.diagnostics
12930                        .remove(&Some(unreg.id.clone()))
12931                        .with_context(|| format!(
12932                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12933                            unreg.id)
12934                        )?;
12935                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12936
12937                    if let LanguageServerState::Running {
12938                        workspace_diagnostics_refresh_tasks,
12939                        ..
12940                    } = state
12941                    {
12942                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12943                    }
12944
12945                    self.clear_unregistered_diagnostics(
12946                        server_id,
12947                        SharedString::from(unreg.id.clone()),
12948                        cx,
12949                    )?;
12950
12951                    if removed_last_diagnostic_provider {
12952                        server.update_capabilities(|capabilities| {
12953                            debug_assert!(capabilities.diagnostic_provider.is_some());
12954                            capabilities.diagnostic_provider = None;
12955                        });
12956                    }
12957
12958                    notify_server_capabilities_updated(&server, cx);
12959                }
12960                "textDocument/documentColor" => {
12961                    server.update_capabilities(|capabilities| {
12962                        capabilities.color_provider = None;
12963                    });
12964                    notify_server_capabilities_updated(&server, cx);
12965                }
12966                "textDocument/foldingRange" => {
12967                    server.update_capabilities(|capabilities| {
12968                        capabilities.folding_range_provider = None;
12969                    });
12970                    notify_server_capabilities_updated(&server, cx);
12971                }
12972                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12973            }
12974        }
12975
12976        Ok(())
12977    }
12978
12979    fn clear_unregistered_diagnostics(
12980        &mut self,
12981        server_id: LanguageServerId,
12982        cleared_registration_id: SharedString,
12983        cx: &mut Context<Self>,
12984    ) -> anyhow::Result<()> {
12985        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12986
12987        self.buffer_store.update(cx, |buffer_store, cx| {
12988            for buffer_handle in buffer_store.buffers() {
12989                let buffer = buffer_handle.read(cx);
12990                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12991                let Some(abs_path) = abs_path else {
12992                    continue;
12993                };
12994                affected_abs_paths.insert(abs_path);
12995            }
12996        });
12997
12998        let local = self.as_local().context("Expected LSP Store to be local")?;
12999        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13000            let Some(worktree) = self
13001                .worktree_store
13002                .read(cx)
13003                .worktree_for_id(*worktree_id, cx)
13004            else {
13005                continue;
13006            };
13007
13008            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13009                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13010                    let has_matching_registration =
13011                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13012                            entry.diagnostic.registration_id.as_ref()
13013                                == Some(&cleared_registration_id)
13014                        });
13015                    if has_matching_registration {
13016                        let abs_path = worktree.read(cx).absolutize(rel_path);
13017                        affected_abs_paths.insert(abs_path);
13018                    }
13019                }
13020            }
13021        }
13022
13023        if affected_abs_paths.is_empty() {
13024            return Ok(());
13025        }
13026
13027        // Send a fake diagnostic update which clears the state for the registration ID
13028        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13029            affected_abs_paths
13030                .into_iter()
13031                .map(|abs_path| DocumentDiagnosticsUpdate {
13032                    diagnostics: DocumentDiagnostics {
13033                        diagnostics: Vec::new(),
13034                        document_abs_path: abs_path,
13035                        version: None,
13036                    },
13037                    result_id: None,
13038                    registration_id: Some(cleared_registration_id.clone()),
13039                    server_id,
13040                    disk_based_sources: Cow::Borrowed(&[]),
13041                })
13042                .collect();
13043
13044        let merge_registration_id = cleared_registration_id.clone();
13045        self.merge_diagnostic_entries(
13046            clears,
13047            move |_, diagnostic, _| {
13048                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13049                    diagnostic.registration_id != Some(merge_registration_id.clone())
13050                } else {
13051                    true
13052                }
13053            },
13054            cx,
13055        )?;
13056
13057        Ok(())
13058    }
13059
13060    async fn deduplicate_range_based_lsp_requests<T>(
13061        lsp_store: &Entity<Self>,
13062        server_id: Option<LanguageServerId>,
13063        lsp_request_id: LspRequestId,
13064        proto_request: &T::ProtoRequest,
13065        range: Range<Anchor>,
13066        cx: &mut AsyncApp,
13067    ) -> Result<()>
13068    where
13069        T: LspCommand,
13070        T::ProtoRequest: proto::LspRequestMessage,
13071    {
13072        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13073        let version = deserialize_version(proto_request.buffer_version());
13074        let buffer = lsp_store.update(cx, |this, cx| {
13075            this.buffer_store.read(cx).get_existing(buffer_id)
13076        })?;
13077        buffer
13078            .update(cx, |buffer, _| buffer.wait_for_version(version))
13079            .await?;
13080        lsp_store.update(cx, |lsp_store, cx| {
13081            let buffer_snapshot = buffer.read(cx).snapshot();
13082            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13083            let chunks_queried_for = lsp_data
13084                .inlay_hints
13085                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13086                .collect::<Vec<_>>();
13087            match chunks_queried_for.as_slice() {
13088                &[chunk] => {
13089                    let key = LspKey {
13090                        request_type: TypeId::of::<T>(),
13091                        server_queried: server_id,
13092                    };
13093                    let previous_request = lsp_data
13094                        .chunk_lsp_requests
13095                        .entry(key)
13096                        .or_default()
13097                        .insert(chunk, lsp_request_id);
13098                    if let Some((previous_request, running_requests)) =
13099                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13100                    {
13101                        running_requests.remove(&previous_request);
13102                    }
13103                }
13104                _ambiguous_chunks => {
13105                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13106                    // there, a buffer version-based check will be performed and outdated requests discarded.
13107                }
13108            }
13109            anyhow::Ok(())
13110        })?;
13111
13112        Ok(())
13113    }
13114
13115    async fn query_lsp_locally<T>(
13116        lsp_store: Entity<Self>,
13117        for_server_id: Option<LanguageServerId>,
13118        sender_id: proto::PeerId,
13119        lsp_request_id: LspRequestId,
13120        proto_request: T::ProtoRequest,
13121        position: Option<Anchor>,
13122        cx: &mut AsyncApp,
13123    ) -> Result<()>
13124    where
13125        T: LspCommand + Clone,
13126        T::ProtoRequest: proto::LspRequestMessage,
13127        <T::ProtoRequest as proto::RequestMessage>::Response:
13128            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13129    {
13130        let (buffer_version, buffer) =
13131            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13132        let request =
13133            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13134        let key = LspKey {
13135            request_type: TypeId::of::<T>(),
13136            server_queried: for_server_id,
13137        };
13138        lsp_store.update(cx, |lsp_store, cx| {
13139            let request_task = match for_server_id {
13140                Some(server_id) => {
13141                    let server_task = lsp_store.request_lsp(
13142                        buffer.clone(),
13143                        LanguageServerToQuery::Other(server_id),
13144                        request.clone(),
13145                        cx,
13146                    );
13147                    cx.background_spawn(async move {
13148                        let mut responses = Vec::new();
13149                        match server_task.await {
13150                            Ok(response) => responses.push((server_id, response)),
13151                            // rust-analyzer likes to error with this when its still loading up
13152                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13153                            Err(e) => log::error!(
13154                                "Error handling response for request {request:?}: {e:#}"
13155                            ),
13156                        }
13157                        responses
13158                    })
13159                }
13160                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13161            };
13162            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13163            if T::ProtoRequest::stop_previous_requests() {
13164                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13165                    lsp_requests.clear();
13166                }
13167            }
13168            lsp_data.lsp_requests.entry(key).or_default().insert(
13169                lsp_request_id,
13170                cx.spawn(async move |lsp_store, cx| {
13171                    let response = request_task.await;
13172                    lsp_store
13173                        .update(cx, |lsp_store, cx| {
13174                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13175                            {
13176                                let response = response
13177                                    .into_iter()
13178                                    .map(|(server_id, response)| {
13179                                        (
13180                                            server_id.to_proto(),
13181                                            T::response_to_proto(
13182                                                response,
13183                                                lsp_store,
13184                                                sender_id,
13185                                                &buffer_version,
13186                                                cx,
13187                                            )
13188                                            .into(),
13189                                        )
13190                                    })
13191                                    .collect::<HashMap<_, _>>();
13192                                match client.send_lsp_response::<T::ProtoRequest>(
13193                                    project_id,
13194                                    lsp_request_id,
13195                                    response,
13196                                ) {
13197                                    Ok(()) => {}
13198                                    Err(e) => {
13199                                        log::error!("Failed to send LSP response: {e:#}",)
13200                                    }
13201                                }
13202                            }
13203                        })
13204                        .ok();
13205                }),
13206            );
13207        });
13208        Ok(())
13209    }
13210
13211    async fn wait_for_buffer_version<T>(
13212        lsp_store: &Entity<Self>,
13213        proto_request: &T::ProtoRequest,
13214        cx: &mut AsyncApp,
13215    ) -> Result<(Global, Entity<Buffer>)>
13216    where
13217        T: LspCommand,
13218        T::ProtoRequest: proto::LspRequestMessage,
13219    {
13220        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13221        let version = deserialize_version(proto_request.buffer_version());
13222        let buffer = lsp_store.update(cx, |this, cx| {
13223            this.buffer_store.read(cx).get_existing(buffer_id)
13224        })?;
13225        buffer
13226            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13227            .await?;
13228        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13229        Ok((buffer_version, buffer))
13230    }
13231
13232    fn take_text_document_sync_options(
13233        capabilities: &mut lsp::ServerCapabilities,
13234    ) -> lsp::TextDocumentSyncOptions {
13235        match capabilities.text_document_sync.take() {
13236            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13237            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13238                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13239                sync_options.change = Some(sync_kind);
13240                sync_options
13241            }
13242            None => lsp::TextDocumentSyncOptions::default(),
13243        }
13244    }
13245
13246    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13247        self.downstream_client.clone()
13248    }
13249
13250    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13251        self.worktree_store.clone()
13252    }
13253
13254    /// Gets what's stored in the LSP data for the given buffer.
13255    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13256        self.lsp_data.get_mut(&buffer_id)
13257    }
13258
13259    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13260    /// new [`BufferLspData`] will be created to replace the previous state.
13261    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13262        let (buffer_id, buffer_version) =
13263            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13264        let lsp_data = self
13265            .lsp_data
13266            .entry(buffer_id)
13267            .or_insert_with(|| BufferLspData::new(buffer, cx));
13268        if buffer_version.changed_since(&lsp_data.buffer_version) {
13269            // To send delta requests for semantic tokens, the previous tokens
13270            // need to be kept between buffer changes.
13271            let semantic_tokens = lsp_data.semantic_tokens.take();
13272            *lsp_data = BufferLspData::new(buffer, cx);
13273            lsp_data.semantic_tokens = semantic_tokens;
13274        }
13275        lsp_data
13276    }
13277}
13278
13279// Registration with registerOptions as null, should fallback to true.
13280// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13281fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13282    reg: lsp::Registration,
13283) -> Result<OneOf<bool, T>> {
13284    Ok(match reg.register_options {
13285        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13286        None => OneOf::Left(true),
13287    })
13288}
13289
13290fn subscribe_to_binary_statuses(
13291    languages: &Arc<LanguageRegistry>,
13292    cx: &mut Context<'_, LspStore>,
13293) -> Task<()> {
13294    let mut server_statuses = languages.language_server_binary_statuses();
13295    cx.spawn(async move |lsp_store, cx| {
13296        while let Some((server_name, binary_status)) = server_statuses.next().await {
13297            if lsp_store
13298                .update(cx, |_, cx| {
13299                    let mut message = None;
13300                    let binary_status = match binary_status {
13301                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13302                        BinaryStatus::CheckingForUpdate => {
13303                            proto::ServerBinaryStatus::CheckingForUpdate
13304                        }
13305                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13306                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13307                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13308                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13309                        BinaryStatus::Failed { error } => {
13310                            message = Some(error);
13311                            proto::ServerBinaryStatus::Failed
13312                        }
13313                    };
13314                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13315                        // Binary updates are about the binary that might not have any language server id at that point.
13316                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13317                        language_server_id: LanguageServerId(0),
13318                        name: Some(server_name),
13319                        message: proto::update_language_server::Variant::StatusUpdate(
13320                            proto::StatusUpdate {
13321                                message,
13322                                status: Some(proto::status_update::Status::Binary(
13323                                    binary_status as i32,
13324                                )),
13325                            },
13326                        ),
13327                    });
13328                })
13329                .is_err()
13330            {
13331                break;
13332            }
13333        }
13334    })
13335}
13336
13337fn lsp_workspace_diagnostics_refresh(
13338    registration_id: Option<String>,
13339    options: DiagnosticServerCapabilities,
13340    server: Arc<LanguageServer>,
13341    cx: &mut Context<'_, LspStore>,
13342) -> Option<WorkspaceRefreshTask> {
13343    let identifier = workspace_diagnostic_identifier(&options)?;
13344    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13345
13346    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13347    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13348    refresh_tx.try_send(()).ok();
13349
13350    let request_timeout = ProjectSettings::get_global(cx)
13351        .global_lsp_settings
13352        .get_request_timeout();
13353
13354    // 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.
13355    // This allows users to increase the duration if need be
13356    let timeout = if request_timeout != Duration::ZERO {
13357        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13358    } else {
13359        request_timeout
13360    };
13361
13362    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13363        let mut attempts = 0;
13364        let max_attempts = 50;
13365        let mut requests = 0;
13366
13367        loop {
13368            let Some(()) = refresh_rx.recv().await else {
13369                return;
13370            };
13371
13372            'request: loop {
13373                requests += 1;
13374                if attempts > max_attempts {
13375                    log::error!(
13376                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13377                    );
13378                    return;
13379                }
13380                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13381                cx.background_executor()
13382                    .timer(Duration::from_millis(backoff_millis))
13383                    .await;
13384                attempts += 1;
13385
13386                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13387                    lsp_store
13388                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13389                        .into_iter()
13390                        .filter_map(|(abs_path, result_id)| {
13391                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13392                            Some(lsp::PreviousResultId {
13393                                uri,
13394                                value: result_id.to_string(),
13395                            })
13396                        })
13397                        .collect()
13398                }) else {
13399                    return;
13400                };
13401
13402                let token = if let Some(registration_id) = &registration_id {
13403                    format!(
13404                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13405                        server.server_id(),
13406                    )
13407                } else {
13408                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13409                };
13410
13411                progress_rx.try_recv().ok();
13412                let timer = server.request_timer(timeout).fuse();
13413                let progress = pin!(progress_rx.recv().fuse());
13414                let response_result = server
13415                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13416                        lsp::WorkspaceDiagnosticParams {
13417                            previous_result_ids,
13418                            identifier: identifier.clone(),
13419                            work_done_progress_params: Default::default(),
13420                            partial_result_params: lsp::PartialResultParams {
13421                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13422                            },
13423                        },
13424                        select(timer, progress).then(|either| match either {
13425                            Either::Left((message, ..)) => ready(message).left_future(),
13426                            Either::Right(..) => pending::<String>().right_future(),
13427                        }),
13428                    )
13429                    .await;
13430
13431                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13432                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13433                match response_result {
13434                    ConnectionResult::Timeout => {
13435                        log::error!("Timeout during workspace diagnostics pull");
13436                        continue 'request;
13437                    }
13438                    ConnectionResult::ConnectionReset => {
13439                        log::error!("Server closed a workspace diagnostics pull request");
13440                        continue 'request;
13441                    }
13442                    ConnectionResult::Result(Err(e)) => {
13443                        log::error!("Error during workspace diagnostics pull: {e:#}");
13444                        break 'request;
13445                    }
13446                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13447                        attempts = 0;
13448                        if lsp_store
13449                            .update(cx, |lsp_store, cx| {
13450                                lsp_store.apply_workspace_diagnostic_report(
13451                                    server.server_id(),
13452                                    pulled_diagnostics,
13453                                    registration_id_shared.clone(),
13454                                    cx,
13455                                )
13456                            })
13457                            .is_err()
13458                        {
13459                            return;
13460                        }
13461                        break 'request;
13462                    }
13463                }
13464            }
13465        }
13466    });
13467
13468    Some(WorkspaceRefreshTask {
13469        refresh_tx,
13470        progress_tx,
13471        task: workspace_query_language_server,
13472    })
13473}
13474
13475fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13476    match &options {
13477        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13478            .identifier
13479            .as_deref()
13480            .map(SharedString::new),
13481        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13482            let diagnostic_options = &registration_options.diagnostic_options;
13483            diagnostic_options
13484                .identifier
13485                .as_deref()
13486                .map(SharedString::new)
13487        }
13488    }
13489}
13490
13491fn workspace_diagnostic_identifier(
13492    options: &DiagnosticServerCapabilities,
13493) -> Option<Option<String>> {
13494    match &options {
13495        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13496            if !diagnostic_options.workspace_diagnostics {
13497                return None;
13498            }
13499            Some(diagnostic_options.identifier.clone())
13500        }
13501        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13502            let diagnostic_options = &registration_options.diagnostic_options;
13503            if !diagnostic_options.workspace_diagnostics {
13504                return None;
13505            }
13506            Some(diagnostic_options.identifier.clone())
13507        }
13508    }
13509}
13510
13511fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13512    let CompletionSource::BufferWord {
13513        word_range,
13514        resolved,
13515    } = &mut completion.source
13516    else {
13517        return;
13518    };
13519    if *resolved {
13520        return;
13521    }
13522
13523    if completion.new_text
13524        != snapshot
13525            .text_for_range(word_range.clone())
13526            .collect::<String>()
13527    {
13528        return;
13529    }
13530
13531    let mut offset = 0;
13532    for chunk in snapshot.chunks(
13533        word_range.clone(),
13534        LanguageAwareStyling {
13535            tree_sitter: true,
13536            diagnostics: true,
13537        },
13538    ) {
13539        let end_offset = offset + chunk.text.len();
13540        if let Some(highlight_id) = chunk.syntax_highlight_id {
13541            completion
13542                .label
13543                .runs
13544                .push((offset..end_offset, highlight_id));
13545        }
13546        offset = end_offset;
13547    }
13548    *resolved = true;
13549}
13550
13551impl EventEmitter<LspStoreEvent> for LspStore {}
13552
13553fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13554    hover
13555        .contents
13556        .retain(|hover_block| !hover_block.text.trim().is_empty());
13557    if hover.contents.is_empty() {
13558        None
13559    } else {
13560        Some(hover)
13561    }
13562}
13563
13564async fn populate_labels_for_completions(
13565    new_completions: Vec<CoreCompletion>,
13566    language: Option<Arc<Language>>,
13567    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13568) -> Vec<Completion> {
13569    let lsp_completions = new_completions
13570        .iter()
13571        .filter_map(|new_completion| {
13572            new_completion
13573                .source
13574                .lsp_completion(true)
13575                .map(|lsp_completion| lsp_completion.into_owned())
13576        })
13577        .collect::<Vec<_>>();
13578
13579    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13580        lsp_adapter
13581            .labels_for_completions(&lsp_completions, language)
13582            .await
13583            .log_err()
13584            .unwrap_or_default()
13585    } else {
13586        Vec::new()
13587    }
13588    .into_iter()
13589    .fuse();
13590
13591    let mut completions = Vec::new();
13592    for completion in new_completions {
13593        match completion.source.lsp_completion(true) {
13594            Some(lsp_completion) => {
13595                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13596
13597                let mut label = labels.next().flatten().unwrap_or_else(|| {
13598                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13599                });
13600                ensure_uniform_list_compatible_label(&mut label);
13601                completions.push(Completion {
13602                    label,
13603                    documentation,
13604                    replace_range: completion.replace_range,
13605                    new_text: completion.new_text,
13606                    insert_text_mode: lsp_completion.insert_text_mode,
13607                    source: completion.source,
13608                    icon_path: None,
13609                    confirm: None,
13610                    match_start: None,
13611                    snippet_deduplication_key: None,
13612                });
13613            }
13614            None => {
13615                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13616                ensure_uniform_list_compatible_label(&mut label);
13617                completions.push(Completion {
13618                    label,
13619                    documentation: None,
13620                    replace_range: completion.replace_range,
13621                    new_text: completion.new_text,
13622                    source: completion.source,
13623                    insert_text_mode: None,
13624                    icon_path: None,
13625                    confirm: None,
13626                    match_start: None,
13627                    snippet_deduplication_key: None,
13628                });
13629            }
13630        }
13631    }
13632    completions
13633}
13634
13635#[derive(Debug)]
13636pub enum LanguageServerToQuery {
13637    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13638    FirstCapable,
13639    /// Query a specific language server.
13640    Other(LanguageServerId),
13641}
13642
13643#[derive(Default)]
13644struct RenamePathsWatchedForServer {
13645    did_rename: Vec<RenameActionPredicate>,
13646    will_rename: Vec<RenameActionPredicate>,
13647}
13648
13649impl RenamePathsWatchedForServer {
13650    fn with_did_rename_patterns(
13651        mut self,
13652        did_rename: Option<&FileOperationRegistrationOptions>,
13653    ) -> Self {
13654        if let Some(did_rename) = did_rename {
13655            self.did_rename = did_rename
13656                .filters
13657                .iter()
13658                .filter_map(|filter| filter.try_into().log_err())
13659                .collect();
13660        }
13661        self
13662    }
13663    fn with_will_rename_patterns(
13664        mut self,
13665        will_rename: Option<&FileOperationRegistrationOptions>,
13666    ) -> Self {
13667        if let Some(will_rename) = will_rename {
13668            self.will_rename = will_rename
13669                .filters
13670                .iter()
13671                .filter_map(|filter| filter.try_into().log_err())
13672                .collect();
13673        }
13674        self
13675    }
13676
13677    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13678        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13679    }
13680    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13681        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13682    }
13683}
13684
13685impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13686    type Error = globset::Error;
13687    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13688        Ok(Self {
13689            kind: ops.pattern.matches.clone(),
13690            glob: GlobBuilder::new(&ops.pattern.glob)
13691                .case_insensitive(
13692                    ops.pattern
13693                        .options
13694                        .as_ref()
13695                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13696                )
13697                .build()?
13698                .compile_matcher(),
13699        })
13700    }
13701}
13702struct RenameActionPredicate {
13703    glob: GlobMatcher,
13704    kind: Option<FileOperationPatternKind>,
13705}
13706
13707impl RenameActionPredicate {
13708    // Returns true if language server should be notified
13709    fn eval(&self, path: &str, is_dir: bool) -> bool {
13710        self.kind.as_ref().is_none_or(|kind| {
13711            let expected_kind = if is_dir {
13712                FileOperationPatternKind::Folder
13713            } else {
13714                FileOperationPatternKind::File
13715            };
13716            kind == &expected_kind
13717        }) && self.glob.is_match(path)
13718    }
13719}
13720
13721#[derive(Default)]
13722struct LanguageServerWatchedPaths {
13723    worktree_paths: HashMap<WorktreeId, GlobSet>,
13724    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13725}
13726
13727#[derive(Default)]
13728struct LanguageServerWatchedPathsBuilder {
13729    worktree_paths: HashMap<WorktreeId, GlobSet>,
13730    abs_paths: HashMap<Arc<Path>, GlobSet>,
13731}
13732
13733impl LanguageServerWatchedPathsBuilder {
13734    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13735        self.worktree_paths.insert(worktree_id, glob_set);
13736    }
13737    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13738        self.abs_paths.insert(path, glob_set);
13739    }
13740    fn build(
13741        self,
13742        fs: Arc<dyn Fs>,
13743        language_server_id: LanguageServerId,
13744        cx: &mut Context<LspStore>,
13745    ) -> LanguageServerWatchedPaths {
13746        let lsp_store = cx.weak_entity();
13747
13748        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13749        let abs_paths = self
13750            .abs_paths
13751            .into_iter()
13752            .map(|(abs_path, globset)| {
13753                let task = cx.spawn({
13754                    let abs_path = abs_path.clone();
13755                    let fs = fs.clone();
13756
13757                    let lsp_store = lsp_store.clone();
13758                    async move |_, cx| {
13759                        maybe!(async move {
13760                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13761                            while let Some(update) = push_updates.0.next().await {
13762                                let action = lsp_store
13763                                    .update(cx, |this, _| {
13764                                        let Some(local) = this.as_local() else {
13765                                            return ControlFlow::Break(());
13766                                        };
13767                                        let Some(watcher) = local
13768                                            .language_server_watched_paths
13769                                            .get(&language_server_id)
13770                                        else {
13771                                            return ControlFlow::Break(());
13772                                        };
13773                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13774                                            "Watched abs path is not registered with a watcher",
13775                                        );
13776                                        let matching_entries = update
13777                                            .into_iter()
13778                                            .filter(|event| globs.is_match(&event.path))
13779                                            .collect::<Vec<_>>();
13780                                        this.lsp_notify_abs_paths_changed(
13781                                            language_server_id,
13782                                            matching_entries,
13783                                        );
13784                                        ControlFlow::Continue(())
13785                                    })
13786                                    .ok()?;
13787
13788                                if action.is_break() {
13789                                    break;
13790                                }
13791                            }
13792                            Some(())
13793                        })
13794                        .await;
13795                    }
13796                });
13797                (abs_path, (globset, task))
13798            })
13799            .collect();
13800        LanguageServerWatchedPaths {
13801            worktree_paths: self.worktree_paths,
13802            abs_paths,
13803        }
13804    }
13805}
13806
13807struct LspBufferSnapshot {
13808    version: i32,
13809    snapshot: TextBufferSnapshot,
13810}
13811
13812/// A prompt requested by LSP server.
13813#[derive(Clone, Debug)]
13814pub struct LanguageServerPromptRequest {
13815    pub id: usize,
13816    pub level: PromptLevel,
13817    pub message: String,
13818    pub actions: Vec<MessageActionItem>,
13819    pub lsp_name: String,
13820    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13821}
13822
13823impl LanguageServerPromptRequest {
13824    pub fn new(
13825        level: PromptLevel,
13826        message: String,
13827        actions: Vec<MessageActionItem>,
13828        lsp_name: String,
13829        response_channel: smol::channel::Sender<MessageActionItem>,
13830    ) -> Self {
13831        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13832        LanguageServerPromptRequest {
13833            id,
13834            level,
13835            message,
13836            actions,
13837            lsp_name,
13838            response_channel,
13839        }
13840    }
13841    pub async fn respond(self, index: usize) -> Option<()> {
13842        if let Some(response) = self.actions.into_iter().nth(index) {
13843            self.response_channel.send(response).await.ok()
13844        } else {
13845            None
13846        }
13847    }
13848
13849    #[cfg(any(test, feature = "test-support"))]
13850    pub fn test(
13851        level: PromptLevel,
13852        message: String,
13853        actions: Vec<MessageActionItem>,
13854        lsp_name: String,
13855    ) -> Self {
13856        let (tx, _rx) = smol::channel::unbounded();
13857        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13858    }
13859}
13860impl PartialEq for LanguageServerPromptRequest {
13861    fn eq(&self, other: &Self) -> bool {
13862        self.message == other.message && self.actions == other.actions
13863    }
13864}
13865
13866#[derive(Clone, Debug, PartialEq)]
13867pub enum LanguageServerLogType {
13868    Log(MessageType),
13869    Trace { verbose_info: Option<String> },
13870    Rpc { received: bool },
13871}
13872
13873impl LanguageServerLogType {
13874    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13875        match self {
13876            Self::Log(log_type) => {
13877                use proto::log_message::LogLevel;
13878                let level = match *log_type {
13879                    MessageType::ERROR => LogLevel::Error,
13880                    MessageType::WARNING => LogLevel::Warning,
13881                    MessageType::INFO => LogLevel::Info,
13882                    MessageType::LOG => LogLevel::Log,
13883                    other => {
13884                        log::warn!("Unknown lsp log message type: {other:?}");
13885                        LogLevel::Log
13886                    }
13887                };
13888                proto::language_server_log::LogType::Log(proto::LogMessage {
13889                    level: level as i32,
13890                })
13891            }
13892            Self::Trace { verbose_info } => {
13893                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13894                    verbose_info: verbose_info.to_owned(),
13895                })
13896            }
13897            Self::Rpc { received } => {
13898                let kind = if *received {
13899                    proto::rpc_message::Kind::Received
13900                } else {
13901                    proto::rpc_message::Kind::Sent
13902                };
13903                let kind = kind as i32;
13904                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13905            }
13906        }
13907    }
13908
13909    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13910        use proto::log_message::LogLevel;
13911        use proto::rpc_message;
13912        match log_type {
13913            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13914                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13915                    LogLevel::Error => MessageType::ERROR,
13916                    LogLevel::Warning => MessageType::WARNING,
13917                    LogLevel::Info => MessageType::INFO,
13918                    LogLevel::Log => MessageType::LOG,
13919                },
13920            ),
13921            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13922                verbose_info: trace_message.verbose_info,
13923            },
13924            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13925                received: match rpc_message::Kind::from_i32(message.kind)
13926                    .unwrap_or(rpc_message::Kind::Received)
13927                {
13928                    rpc_message::Kind::Received => true,
13929                    rpc_message::Kind::Sent => false,
13930                },
13931            },
13932        }
13933    }
13934}
13935
13936pub struct WorkspaceRefreshTask {
13937    refresh_tx: mpsc::Sender<()>,
13938    progress_tx: mpsc::Sender<()>,
13939    #[allow(dead_code)]
13940    task: Task<()>,
13941}
13942
13943pub enum LanguageServerState {
13944    Starting {
13945        startup: Task<Option<Arc<LanguageServer>>>,
13946        /// List of language servers that will be added to the workspace once it's initialization completes.
13947        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13948    },
13949
13950    Running {
13951        adapter: Arc<CachedLspAdapter>,
13952        server: Arc<LanguageServer>,
13953        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13954        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13955    },
13956}
13957
13958impl LanguageServerState {
13959    fn add_workspace_folder(&self, uri: Uri) {
13960        match self {
13961            LanguageServerState::Starting {
13962                pending_workspace_folders,
13963                ..
13964            } => {
13965                pending_workspace_folders.lock().insert(uri);
13966            }
13967            LanguageServerState::Running { server, .. } => {
13968                server.add_workspace_folder(uri);
13969            }
13970        }
13971    }
13972    fn _remove_workspace_folder(&self, uri: Uri) {
13973        match self {
13974            LanguageServerState::Starting {
13975                pending_workspace_folders,
13976                ..
13977            } => {
13978                pending_workspace_folders.lock().remove(&uri);
13979            }
13980            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13981        }
13982    }
13983}
13984
13985impl std::fmt::Debug for LanguageServerState {
13986    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13987        match self {
13988            LanguageServerState::Starting { .. } => {
13989                f.debug_struct("LanguageServerState::Starting").finish()
13990            }
13991            LanguageServerState::Running { .. } => {
13992                f.debug_struct("LanguageServerState::Running").finish()
13993            }
13994        }
13995    }
13996}
13997
13998#[derive(Clone, Debug, Serialize)]
13999pub struct LanguageServerProgress {
14000    pub is_disk_based_diagnostics_progress: bool,
14001    pub is_cancellable: bool,
14002    pub title: Option<String>,
14003    pub message: Option<String>,
14004    pub percentage: Option<usize>,
14005    #[serde(skip_serializing)]
14006    pub last_update_at: Instant,
14007}
14008
14009#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14010pub struct DiagnosticSummary {
14011    pub error_count: usize,
14012    pub warning_count: usize,
14013}
14014
14015impl DiagnosticSummary {
14016    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14017        let mut this = Self {
14018            error_count: 0,
14019            warning_count: 0,
14020        };
14021
14022        for entry in diagnostics {
14023            if entry.diagnostic.is_primary {
14024                match entry.diagnostic.severity {
14025                    DiagnosticSeverity::ERROR => this.error_count += 1,
14026                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14027                    _ => {}
14028                }
14029            }
14030        }
14031
14032        this
14033    }
14034
14035    pub fn is_empty(&self) -> bool {
14036        self.error_count == 0 && self.warning_count == 0
14037    }
14038
14039    pub fn to_proto(
14040        self,
14041        language_server_id: LanguageServerId,
14042        path: &RelPath,
14043    ) -> proto::DiagnosticSummary {
14044        proto::DiagnosticSummary {
14045            path: path.to_proto(),
14046            language_server_id: language_server_id.0 as u64,
14047            error_count: self.error_count as u32,
14048            warning_count: self.warning_count as u32,
14049        }
14050    }
14051}
14052
14053#[derive(Clone, Debug)]
14054pub enum CompletionDocumentation {
14055    /// There is no documentation for this completion.
14056    Undocumented,
14057    /// A single line of documentation.
14058    SingleLine(SharedString),
14059    /// Multiple lines of plain text documentation.
14060    MultiLinePlainText(SharedString),
14061    /// Markdown documentation.
14062    MultiLineMarkdown(SharedString),
14063    /// Both single line and multiple lines of plain text documentation.
14064    SingleLineAndMultiLinePlainText {
14065        single_line: SharedString,
14066        plain_text: Option<SharedString>,
14067    },
14068}
14069
14070impl CompletionDocumentation {
14071    #[cfg(any(test, feature = "test-support"))]
14072    pub fn text(&self) -> SharedString {
14073        match self {
14074            CompletionDocumentation::Undocumented => "".into(),
14075            CompletionDocumentation::SingleLine(s) => s.clone(),
14076            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14077            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14078            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14079                single_line.clone()
14080            }
14081        }
14082    }
14083}
14084
14085impl From<lsp::Documentation> for CompletionDocumentation {
14086    fn from(docs: lsp::Documentation) -> Self {
14087        match docs {
14088            lsp::Documentation::String(text) => {
14089                if text.lines().count() <= 1 {
14090                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14091                } else {
14092                    CompletionDocumentation::MultiLinePlainText(text.into())
14093                }
14094            }
14095
14096            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14097                lsp::MarkupKind::PlainText => {
14098                    if value.lines().count() <= 1 {
14099                        CompletionDocumentation::SingleLine(value.into())
14100                    } else {
14101                        CompletionDocumentation::MultiLinePlainText(value.into())
14102                    }
14103                }
14104
14105                lsp::MarkupKind::Markdown => {
14106                    CompletionDocumentation::MultiLineMarkdown(value.into())
14107                }
14108            },
14109        }
14110    }
14111}
14112
14113pub enum ResolvedHint {
14114    Resolved(InlayHint),
14115    Resolving(Shared<Task<()>>),
14116}
14117
14118pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14119    glob.components()
14120        .take_while(|component| match component {
14121            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14122            _ => true,
14123        })
14124        .collect()
14125}
14126
14127pub struct SshLspAdapter {
14128    name: LanguageServerName,
14129    binary: LanguageServerBinary,
14130    initialization_options: Option<String>,
14131    code_action_kinds: Option<Vec<CodeActionKind>>,
14132}
14133
14134impl SshLspAdapter {
14135    pub fn new(
14136        name: LanguageServerName,
14137        binary: LanguageServerBinary,
14138        initialization_options: Option<String>,
14139        code_action_kinds: Option<String>,
14140    ) -> Self {
14141        Self {
14142            name,
14143            binary,
14144            initialization_options,
14145            code_action_kinds: code_action_kinds
14146                .as_ref()
14147                .and_then(|c| serde_json::from_str(c).ok()),
14148        }
14149    }
14150}
14151
14152impl LspInstaller for SshLspAdapter {
14153    type BinaryVersion = ();
14154    async fn check_if_user_installed(
14155        &self,
14156        _: &dyn LspAdapterDelegate,
14157        _: Option<Toolchain>,
14158        _: &AsyncApp,
14159    ) -> Option<LanguageServerBinary> {
14160        Some(self.binary.clone())
14161    }
14162
14163    async fn cached_server_binary(
14164        &self,
14165        _: PathBuf,
14166        _: &dyn LspAdapterDelegate,
14167    ) -> Option<LanguageServerBinary> {
14168        None
14169    }
14170
14171    async fn fetch_latest_server_version(
14172        &self,
14173        _: &dyn LspAdapterDelegate,
14174        _: bool,
14175        _: &mut AsyncApp,
14176    ) -> Result<()> {
14177        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14178    }
14179
14180    async fn fetch_server_binary(
14181        &self,
14182        _: (),
14183        _: PathBuf,
14184        _: &dyn LspAdapterDelegate,
14185    ) -> Result<LanguageServerBinary> {
14186        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14187    }
14188}
14189
14190#[async_trait(?Send)]
14191impl LspAdapter for SshLspAdapter {
14192    fn name(&self) -> LanguageServerName {
14193        self.name.clone()
14194    }
14195
14196    async fn initialization_options(
14197        self: Arc<Self>,
14198        _: &Arc<dyn LspAdapterDelegate>,
14199        _: &mut AsyncApp,
14200    ) -> Result<Option<serde_json::Value>> {
14201        let Some(options) = &self.initialization_options else {
14202            return Ok(None);
14203        };
14204        let result = serde_json::from_str(options)?;
14205        Ok(result)
14206    }
14207
14208    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14209        self.code_action_kinds.clone()
14210    }
14211}
14212
14213pub fn language_server_settings<'a>(
14214    delegate: &'a dyn LspAdapterDelegate,
14215    language: &LanguageServerName,
14216    cx: &'a App,
14217) -> Option<&'a LspSettings> {
14218    language_server_settings_for(
14219        SettingsLocation {
14220            worktree_id: delegate.worktree_id(),
14221            path: RelPath::empty(),
14222        },
14223        language,
14224        cx,
14225    )
14226}
14227
14228pub fn language_server_settings_for<'a>(
14229    location: SettingsLocation<'a>,
14230    language: &LanguageServerName,
14231    cx: &'a App,
14232) -> Option<&'a LspSettings> {
14233    ProjectSettings::get(Some(location), cx).lsp.get(language)
14234}
14235
14236pub struct LocalLspAdapterDelegate {
14237    lsp_store: WeakEntity<LspStore>,
14238    worktree: worktree::Snapshot,
14239    fs: Arc<dyn Fs>,
14240    http_client: Arc<dyn HttpClient>,
14241    language_registry: Arc<LanguageRegistry>,
14242    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14243}
14244
14245impl LocalLspAdapterDelegate {
14246    pub fn new(
14247        language_registry: Arc<LanguageRegistry>,
14248        environment: &Entity<ProjectEnvironment>,
14249        lsp_store: WeakEntity<LspStore>,
14250        worktree: &Entity<Worktree>,
14251        http_client: Arc<dyn HttpClient>,
14252        fs: Arc<dyn Fs>,
14253        cx: &mut App,
14254    ) -> Arc<Self> {
14255        let load_shell_env_task =
14256            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14257
14258        Arc::new(Self {
14259            lsp_store,
14260            worktree: worktree.read(cx).snapshot(),
14261            fs,
14262            http_client,
14263            language_registry,
14264            load_shell_env_task,
14265        })
14266    }
14267
14268    pub fn from_local_lsp(
14269        local: &LocalLspStore,
14270        worktree: &Entity<Worktree>,
14271        cx: &mut App,
14272    ) -> Arc<Self> {
14273        Self::new(
14274            local.languages.clone(),
14275            &local.environment,
14276            local.weak.clone(),
14277            worktree,
14278            local.http_client.clone(),
14279            local.fs.clone(),
14280            cx,
14281        )
14282    }
14283}
14284
14285#[async_trait]
14286impl LspAdapterDelegate for LocalLspAdapterDelegate {
14287    fn show_notification(&self, message: &str, cx: &mut App) {
14288        self.lsp_store
14289            .update(cx, |_, cx| {
14290                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14291            })
14292            .ok();
14293    }
14294
14295    fn http_client(&self) -> Arc<dyn HttpClient> {
14296        self.http_client.clone()
14297    }
14298
14299    fn worktree_id(&self) -> WorktreeId {
14300        self.worktree.id()
14301    }
14302
14303    fn worktree_root_path(&self) -> &Path {
14304        self.worktree.abs_path().as_ref()
14305    }
14306
14307    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14308        self.worktree.resolve_relative_path(path)
14309    }
14310
14311    async fn shell_env(&self) -> HashMap<String, String> {
14312        let task = self.load_shell_env_task.clone();
14313        task.await.unwrap_or_default()
14314    }
14315
14316    async fn npm_package_installed_version(
14317        &self,
14318        package_name: &str,
14319    ) -> Result<Option<(PathBuf, Version)>> {
14320        let local_package_directory = self.worktree_root_path();
14321        let node_modules_directory = local_package_directory.join("node_modules");
14322
14323        if let Some(version) =
14324            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14325        {
14326            return Ok(Some((node_modules_directory, version)));
14327        }
14328        let Some(npm) = self.which("npm".as_ref()).await else {
14329            log::warn!(
14330                "Failed to find npm executable for {:?}",
14331                local_package_directory
14332            );
14333            return Ok(None);
14334        };
14335
14336        let env = self.shell_env().await;
14337        let output = util::command::new_command(&npm)
14338            .args(["root", "-g"])
14339            .envs(env)
14340            .current_dir(local_package_directory)
14341            .output()
14342            .await?;
14343        let global_node_modules =
14344            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14345
14346        if let Some(version) =
14347            read_package_installed_version(global_node_modules.clone(), package_name).await?
14348        {
14349            return Ok(Some((global_node_modules, version)));
14350        }
14351        return Ok(None);
14352    }
14353
14354    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14355        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14356        if self.fs.is_file(&worktree_abs_path).await {
14357            worktree_abs_path.pop();
14358        }
14359
14360        let env = self.shell_env().await;
14361
14362        let shell_path = env.get("PATH").cloned();
14363
14364        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14365    }
14366
14367    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14368        let mut working_dir = self.worktree_root_path().to_path_buf();
14369        if self.fs.is_file(&working_dir).await {
14370            working_dir.pop();
14371        }
14372        let output = util::command::new_command(&command.path)
14373            .args(command.arguments)
14374            .envs(command.env.clone().unwrap_or_default())
14375            .current_dir(working_dir)
14376            .output()
14377            .await?;
14378
14379        anyhow::ensure!(
14380            output.status.success(),
14381            "{}, stdout: {:?}, stderr: {:?}",
14382            output.status,
14383            String::from_utf8_lossy(&output.stdout),
14384            String::from_utf8_lossy(&output.stderr)
14385        );
14386        Ok(())
14387    }
14388
14389    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14390        self.language_registry
14391            .update_lsp_binary_status(server_name, status);
14392    }
14393
14394    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14395        self.language_registry
14396            .all_lsp_adapters()
14397            .into_iter()
14398            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14399            .collect()
14400    }
14401
14402    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14403        let dir = self.language_registry.language_server_download_dir(name)?;
14404
14405        if !dir.exists() {
14406            smol::fs::create_dir_all(&dir)
14407                .await
14408                .context("failed to create container directory")
14409                .log_err()?;
14410        }
14411
14412        Some(dir)
14413    }
14414
14415    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14416        let entry = self
14417            .worktree
14418            .entry_for_path(path)
14419            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14420        let abs_path = self.worktree.absolutize(&entry.path);
14421        self.fs.load(&abs_path).await
14422    }
14423}
14424
14425async fn populate_labels_for_symbols(
14426    symbols: Vec<CoreSymbol>,
14427    language_registry: &Arc<LanguageRegistry>,
14428    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14429    output: &mut Vec<Symbol>,
14430) {
14431    #[allow(clippy::mutable_key_type)]
14432    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14433
14434    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14435    for symbol in symbols {
14436        let Some(file_name) = symbol.path.file_name() else {
14437            continue;
14438        };
14439        let language = language_registry
14440            .load_language_for_file_path(Path::new(file_name))
14441            .await
14442            .ok()
14443            .or_else(|| {
14444                unknown_paths.insert(file_name.into());
14445                None
14446            });
14447        symbols_by_language
14448            .entry(language)
14449            .or_default()
14450            .push(symbol);
14451    }
14452
14453    for unknown_path in unknown_paths {
14454        log::info!("no language found for symbol in file {unknown_path:?}");
14455    }
14456
14457    let mut label_params = Vec::new();
14458    for (language, mut symbols) in symbols_by_language {
14459        label_params.clear();
14460        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14461            name: mem::take(&mut symbol.name),
14462            kind: symbol.kind,
14463            container_name: symbol.container_name.take(),
14464        }));
14465
14466        let mut labels = Vec::new();
14467        if let Some(language) = language {
14468            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14469                language_registry
14470                    .lsp_adapters(&language.name())
14471                    .first()
14472                    .cloned()
14473            });
14474            if let Some(lsp_adapter) = lsp_adapter {
14475                labels = lsp_adapter
14476                    .labels_for_symbols(&label_params, &language)
14477                    .await
14478                    .log_err()
14479                    .unwrap_or_default();
14480            }
14481        }
14482
14483        for (
14484            (
14485                symbol,
14486                language::Symbol {
14487                    name,
14488                    container_name,
14489                    ..
14490                },
14491            ),
14492            label,
14493        ) in symbols
14494            .into_iter()
14495            .zip(label_params.drain(..))
14496            .zip(labels.into_iter().chain(iter::repeat(None)))
14497        {
14498            output.push(Symbol {
14499                language_server_name: symbol.language_server_name,
14500                source_worktree_id: symbol.source_worktree_id,
14501                source_language_server_id: symbol.source_language_server_id,
14502                path: symbol.path,
14503                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14504                name,
14505                kind: symbol.kind,
14506                range: symbol.range,
14507                container_name,
14508            });
14509        }
14510    }
14511}
14512
14513pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14514    text.lines()
14515        .map(|line| line.trim())
14516        .filter(|line| !line.is_empty())
14517        .join(separator)
14518}
14519
14520fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14521    match server.capabilities().text_document_sync.as_ref()? {
14522        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14523            // Server wants didSave but didn't specify includeText.
14524            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14525            // Server doesn't want didSave at all.
14526            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14527            // Server provided SaveOptions.
14528            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14529                Some(save_options.include_text.unwrap_or(false))
14530            }
14531        },
14532        // We do not have any save info. Kind affects didChange only.
14533        lsp::TextDocumentSyncCapability::Kind(_) => None,
14534    }
14535}
14536
14537/// Completion items are displayed in a `UniformList`.
14538/// Usually, those items are single-line strings, but in LSP responses,
14539/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14540/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14541/// 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,
14542/// breaking the completions menu presentation.
14543///
14544/// 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.
14545pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14546    let mut new_text = String::with_capacity(label.text.len());
14547    let mut offset_map = vec![0; label.text.len() + 1];
14548    let mut last_char_was_space = false;
14549    let mut new_idx = 0;
14550    let chars = label.text.char_indices().fuse();
14551    let mut newlines_removed = false;
14552
14553    for (idx, c) in chars {
14554        offset_map[idx] = new_idx;
14555
14556        match c {
14557            '\n' if last_char_was_space => {
14558                newlines_removed = true;
14559            }
14560            '\t' | ' ' if last_char_was_space => {}
14561            '\n' if !last_char_was_space => {
14562                new_text.push(' ');
14563                new_idx += 1;
14564                last_char_was_space = true;
14565                newlines_removed = true;
14566            }
14567            ' ' | '\t' => {
14568                new_text.push(' ');
14569                new_idx += 1;
14570                last_char_was_space = true;
14571            }
14572            _ => {
14573                new_text.push(c);
14574                new_idx += c.len_utf8();
14575                last_char_was_space = false;
14576            }
14577        }
14578    }
14579    offset_map[label.text.len()] = new_idx;
14580
14581    // Only modify the label if newlines were removed.
14582    if !newlines_removed {
14583        return;
14584    }
14585
14586    let last_index = new_idx;
14587    let mut run_ranges_errors = Vec::new();
14588    label.runs.retain_mut(|(range, _)| {
14589        match offset_map.get(range.start) {
14590            Some(&start) => range.start = start,
14591            None => {
14592                run_ranges_errors.push(range.clone());
14593                return false;
14594            }
14595        }
14596
14597        match offset_map.get(range.end) {
14598            Some(&end) => range.end = end,
14599            None => {
14600                run_ranges_errors.push(range.clone());
14601                range.end = last_index;
14602            }
14603        }
14604        true
14605    });
14606    if !run_ranges_errors.is_empty() {
14607        log::error!(
14608            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14609            label.text
14610        );
14611    }
14612
14613    let mut wrong_filter_range = None;
14614    if label.filter_range == (0..label.text.len()) {
14615        label.filter_range = 0..new_text.len();
14616    } else {
14617        let mut original_filter_range = Some(label.filter_range.clone());
14618        match offset_map.get(label.filter_range.start) {
14619            Some(&start) => label.filter_range.start = start,
14620            None => {
14621                wrong_filter_range = original_filter_range.take();
14622                label.filter_range.start = last_index;
14623            }
14624        }
14625
14626        match offset_map.get(label.filter_range.end) {
14627            Some(&end) => label.filter_range.end = end,
14628            None => {
14629                wrong_filter_range = original_filter_range.take();
14630                label.filter_range.end = last_index;
14631            }
14632        }
14633    }
14634    if let Some(wrong_filter_range) = wrong_filter_range {
14635        log::error!(
14636            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14637            label.text
14638        );
14639    }
14640
14641    label.text = new_text;
14642}
14643
14644/// Apply edits to the buffer that will become part of the formatting transaction.
14645/// Fails if the buffer has been edited since the start of that transaction.
14646fn extend_formatting_transaction(
14647    buffer: &FormattableBuffer,
14648    formatting_transaction_id: text::TransactionId,
14649    cx: &mut AsyncApp,
14650    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14651) -> anyhow::Result<()> {
14652    buffer.handle.update(cx, |buffer, cx| {
14653        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14654        if last_transaction_id != Some(formatting_transaction_id) {
14655            anyhow::bail!("Buffer edited while formatting. Aborting")
14656        }
14657        buffer.start_transaction();
14658        operation(buffer, cx);
14659        if let Some(transaction_id) = buffer.end_transaction(cx) {
14660            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14661        }
14662        Ok(())
14663    })
14664}