lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate,
   76    LspInstaller, ManifestDelegate, ManifestName, ModelineSettings, OffsetUtf16, Patch, PointUtf16,
   77    TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16, Toolchain, Transaction, Unclipped,
   78    language_settings::{
   79        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   80    },
   81    modeline, point_to_lsp,
   82    proto::{
   83        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   84        serialize_anchor_range, serialize_version,
   85    },
   86    range_from_lsp, range_to_lsp,
   87    row_chunk::RowChunk,
   88};
   89use lsp::{
   90    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   91    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   92    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   93    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   94    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   95    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   96    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   97    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   98};
   99use node_runtime::read_package_installed_version;
  100use parking_lot::Mutex;
  101use postage::{mpsc, sink::Sink, stream::Stream, watch};
  102use rand::prelude::*;
  103use rpc::{
  104    AnyProtoClient, ErrorCode, ErrorExt as _,
  105    proto::{LspRequestId, LspRequestMessage as _},
  106};
  107use semver::Version;
  108use serde::Serialize;
  109use serde_json::Value;
  110use settings::{Settings, SettingsLocation, SettingsStore};
  111use sha2::{Digest, Sha256};
  112use snippet::Snippet;
  113use std::{
  114    any::TypeId,
  115    borrow::Cow,
  116    cell::RefCell,
  117    cmp::{Ordering, Reverse},
  118    collections::{VecDeque, hash_map},
  119    convert::TryInto,
  120    ffi::OsStr,
  121    future::ready,
  122    iter, mem,
  123    ops::{ControlFlow, Range},
  124    path::{self, Path, PathBuf},
  125    pin::pin,
  126    rc::Rc,
  127    sync::{
  128        Arc,
  129        atomic::{self, AtomicUsize},
  130    },
  131    time::{Duration, Instant},
  132    vec,
  133};
  134use sum_tree::Dimensions;
  135use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  136
  137use util::{
  138    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  139    paths::{PathStyle, SanitizedPath, UrlExt},
  140    post_inc,
  141    redact::redact_command,
  142    rel_path::RelPath,
  143};
  144
  145pub use document_colors::DocumentColors;
  146pub use folding_ranges::LspFoldingRange;
  147pub use fs::*;
  148pub use language::Location;
  149pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  150#[cfg(any(test, feature = "test-support"))]
  151pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  152#[cfg(any(test, feature = "test-support"))]
  153pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  154pub use semantic_tokens::{
  155    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  156};
  157
  158pub use worktree::{
  159    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  160    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  161};
  162
  163const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  164pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  165const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  166const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  167static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  168
  169#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  170pub enum ProgressToken {
  171    Number(i32),
  172    String(SharedString),
  173}
  174
  175impl std::fmt::Display for ProgressToken {
  176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  177        match self {
  178            Self::Number(number) => write!(f, "{number}"),
  179            Self::String(string) => write!(f, "{string}"),
  180        }
  181    }
  182}
  183
  184impl ProgressToken {
  185    fn from_lsp(value: lsp::NumberOrString) -> Self {
  186        match value {
  187            lsp::NumberOrString::Number(number) => Self::Number(number),
  188            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  189        }
  190    }
  191
  192    fn to_lsp(&self) -> lsp::NumberOrString {
  193        match self {
  194            Self::Number(number) => lsp::NumberOrString::Number(*number),
  195            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  196        }
  197    }
  198
  199    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  200        Some(match value.value? {
  201            proto::progress_token::Value::Number(number) => Self::Number(number),
  202            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  203        })
  204    }
  205
  206    fn to_proto(&self) -> proto::ProgressToken {
  207        proto::ProgressToken {
  208            value: Some(match self {
  209                Self::Number(number) => proto::progress_token::Value::Number(*number),
  210                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  211            }),
  212        }
  213    }
  214}
  215
  216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  217pub enum FormatTrigger {
  218    Save,
  219    Manual,
  220}
  221
  222pub enum LspFormatTarget {
  223    Buffers,
  224    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  225}
  226
  227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  228pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  229
  230struct OpenLspBuffer(Entity<Buffer>);
  231
  232impl FormatTrigger {
  233    fn from_proto(value: i32) -> FormatTrigger {
  234        match value {
  235            0 => FormatTrigger::Save,
  236            1 => FormatTrigger::Manual,
  237            _ => FormatTrigger::Save,
  238        }
  239    }
  240}
  241
  242#[derive(Clone)]
  243struct UnifiedLanguageServer {
  244    id: LanguageServerId,
  245    project_roots: HashSet<Arc<RelPath>>,
  246}
  247
  248/// Settings that affect language server identity.
  249///
  250/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  251/// updated via `workspace/didChangeConfiguration` without restarting the server.
  252#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  253struct LanguageServerSeedSettings {
  254    binary: Option<BinarySettings>,
  255    initialization_options: Option<serde_json::Value>,
  256}
  257
  258#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  259struct LanguageServerSeed {
  260    worktree_id: WorktreeId,
  261    name: LanguageServerName,
  262    toolchain: Option<Toolchain>,
  263    settings: LanguageServerSeedSettings,
  264}
  265
  266#[derive(Debug)]
  267pub struct DocumentDiagnosticsUpdate<'a, D> {
  268    pub diagnostics: D,
  269    pub result_id: Option<SharedString>,
  270    pub registration_id: Option<SharedString>,
  271    pub server_id: LanguageServerId,
  272    pub disk_based_sources: Cow<'a, [String]>,
  273}
  274
  275pub struct DocumentDiagnostics {
  276    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  277    document_abs_path: PathBuf,
  278    version: Option<i32>,
  279}
  280
  281#[derive(Default, Debug)]
  282struct DynamicRegistrations {
  283    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  284    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  285}
  286
  287pub struct LocalLspStore {
  288    weak: WeakEntity<LspStore>,
  289    pub worktree_store: Entity<WorktreeStore>,
  290    toolchain_store: Entity<LocalToolchainStore>,
  291    http_client: Arc<dyn HttpClient>,
  292    environment: Entity<ProjectEnvironment>,
  293    fs: Arc<dyn Fs>,
  294    languages: Arc<LanguageRegistry>,
  295    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  296    yarn: Entity<YarnPathStore>,
  297    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  298    buffers_being_formatted: HashSet<BufferId>,
  299    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  300    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  301    watched_manifest_filenames: HashSet<ManifestName>,
  302    language_server_paths_watched_for_rename:
  303        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  304    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  305    supplementary_language_servers:
  306        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  307    prettier_store: Entity<PrettierStore>,
  308    next_diagnostic_group_id: usize,
  309    diagnostics: HashMap<
  310        WorktreeId,
  311        HashMap<
  312            Arc<RelPath>,
  313            Vec<(
  314                LanguageServerId,
  315                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  316            )>,
  317        >,
  318    >,
  319    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  320    _subscription: gpui::Subscription,
  321    lsp_tree: LanguageServerTree,
  322    registered_buffers: HashMap<BufferId, usize>,
  323    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  324    buffer_pull_diagnostics_result_ids: HashMap<
  325        LanguageServerId,
  326        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  327    >,
  328    workspace_pull_diagnostics_result_ids: HashMap<
  329        LanguageServerId,
  330        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  331    >,
  332    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  333
  334    buffers_to_refresh_hash_set: HashSet<BufferId>,
  335    buffers_to_refresh_queue: VecDeque<BufferId>,
  336    _background_diagnostics_worker: Shared<Task<()>>,
  337}
  338
  339impl LocalLspStore {
  340    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  341    pub fn running_language_server_for_id(
  342        &self,
  343        id: LanguageServerId,
  344    ) -> Option<&Arc<LanguageServer>> {
  345        let language_server_state = self.language_servers.get(&id)?;
  346
  347        match language_server_state {
  348            LanguageServerState::Running { server, .. } => Some(server),
  349            LanguageServerState::Starting { .. } => None,
  350        }
  351    }
  352
  353    fn get_or_insert_language_server(
  354        &mut self,
  355        worktree_handle: &Entity<Worktree>,
  356        delegate: Arc<LocalLspAdapterDelegate>,
  357        disposition: &Arc<LaunchDisposition>,
  358        language_name: &LanguageName,
  359        cx: &mut App,
  360    ) -> LanguageServerId {
  361        let key = LanguageServerSeed {
  362            worktree_id: worktree_handle.read(cx).id(),
  363            name: disposition.server_name.clone(),
  364            settings: LanguageServerSeedSettings {
  365                binary: disposition.settings.binary.clone(),
  366                initialization_options: disposition.settings.initialization_options.clone(),
  367            },
  368            toolchain: disposition.toolchain.clone(),
  369        };
  370        if let Some(state) = self.language_server_ids.get_mut(&key) {
  371            state.project_roots.insert(disposition.path.path.clone());
  372            state.id
  373        } else {
  374            let adapter = self
  375                .languages
  376                .lsp_adapters(language_name)
  377                .into_iter()
  378                .find(|adapter| adapter.name() == disposition.server_name)
  379                .expect("To find LSP adapter");
  380            let new_language_server_id = self.start_language_server(
  381                worktree_handle,
  382                delegate,
  383                adapter,
  384                disposition.settings.clone(),
  385                key.clone(),
  386                language_name.clone(),
  387                cx,
  388            );
  389            if let Some(state) = self.language_server_ids.get_mut(&key) {
  390                state.project_roots.insert(disposition.path.path.clone());
  391            } else {
  392                debug_assert!(
  393                    false,
  394                    "Expected `start_language_server` to ensure that `key` exists in a map"
  395                );
  396            }
  397            new_language_server_id
  398        }
  399    }
  400
  401    fn start_language_server(
  402        &mut self,
  403        worktree_handle: &Entity<Worktree>,
  404        delegate: Arc<LocalLspAdapterDelegate>,
  405        adapter: Arc<CachedLspAdapter>,
  406        settings: Arc<LspSettings>,
  407        key: LanguageServerSeed,
  408        language_name: LanguageName,
  409        cx: &mut App,
  410    ) -> LanguageServerId {
  411        let worktree = worktree_handle.read(cx);
  412
  413        let worktree_id = worktree.id();
  414        let worktree_abs_path = worktree.abs_path();
  415        let toolchain = key.toolchain.clone();
  416        let override_options = settings.initialization_options.clone();
  417
  418        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  419
  420        let server_id = self.languages.next_language_server_id();
  421        log::trace!(
  422            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  423            adapter.name.0
  424        );
  425
  426        let wait_until_worktree_trust =
  427            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  428                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  429                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  430                });
  431                if can_trust {
  432                    self.restricted_worktrees_tasks.remove(&worktree_id);
  433                    None
  434                } else {
  435                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  436                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  437                        hash_map::Entry::Vacant(v) => {
  438                            let (mut tx, rx) = watch::channel::<bool>();
  439                            let lsp_store = self.weak.clone();
  440                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  441                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  442                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  443                                        tx.blocking_send(true).ok();
  444                                        lsp_store
  445                                            .update(cx, |lsp_store, _| {
  446                                                if let Some(local_lsp_store) =
  447                                                    lsp_store.as_local_mut()
  448                                                {
  449                                                    local_lsp_store
  450                                                        .restricted_worktrees_tasks
  451                                                        .remove(&worktree_id);
  452                                                }
  453                                            })
  454                                            .ok();
  455                                    }
  456                                }
  457                            });
  458                            v.insert((subscription, rx.clone()));
  459                            Some(rx)
  460                        }
  461                    }
  462                }
  463            });
  464        let update_binary_status = wait_until_worktree_trust.is_none();
  465
  466        let binary = self.get_language_server_binary(
  467            worktree_abs_path.clone(),
  468            adapter.clone(),
  469            settings,
  470            toolchain.clone(),
  471            delegate.clone(),
  472            true,
  473            wait_until_worktree_trust,
  474            cx,
  475        );
  476        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  477
  478        let pending_server = cx.spawn({
  479            let adapter = adapter.clone();
  480            let server_name = adapter.name.clone();
  481            let stderr_capture = stderr_capture.clone();
  482            #[cfg(any(test, feature = "test-support"))]
  483            let lsp_store = self.weak.clone();
  484            let pending_workspace_folders = pending_workspace_folders.clone();
  485            async move |cx| {
  486                let binary = binary.await?;
  487                #[cfg(any(test, feature = "test-support"))]
  488                if let Some(server) = lsp_store
  489                    .update(&mut cx.clone(), |this, cx| {
  490                        this.languages.create_fake_language_server(
  491                            server_id,
  492                            &server_name,
  493                            binary.clone(),
  494                            &mut cx.to_async(),
  495                        )
  496                    })
  497                    .ok()
  498                    .flatten()
  499                {
  500                    return Ok(server);
  501                }
  502
  503                let code_action_kinds = adapter.code_action_kinds();
  504                lsp::LanguageServer::new(
  505                    stderr_capture,
  506                    server_id,
  507                    server_name,
  508                    binary,
  509                    &worktree_abs_path,
  510                    code_action_kinds,
  511                    Some(pending_workspace_folders),
  512                    cx,
  513                )
  514            }
  515        });
  516
  517        let startup = {
  518            let server_name = adapter.name.0.clone();
  519            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  520            let key = key.clone();
  521            let adapter = adapter.clone();
  522            let lsp_store = self.weak.clone();
  523            let pending_workspace_folders = pending_workspace_folders.clone();
  524            let pull_diagnostics = ProjectSettings::get_global(cx)
  525                .diagnostics
  526                .lsp_pull_diagnostics
  527                .enabled;
  528            let settings_location = SettingsLocation {
  529                worktree_id,
  530                path: RelPath::empty(),
  531            };
  532            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  533                .language(Some(settings_location), Some(&language_name), cx)
  534                .semantic_tokens
  535                .use_tree_sitter();
  536            cx.spawn(async move |cx| {
  537                let result = async {
  538                    let language_server = pending_server.await?;
  539
  540                    let workspace_config = Self::workspace_configuration_for_adapter(
  541                        adapter.adapter.clone(),
  542                        &delegate,
  543                        toolchain,
  544                        None,
  545                        cx,
  546                    )
  547                    .await?;
  548
  549                    let mut initialization_options = Self::initialization_options_for_adapter(
  550                        adapter.adapter.clone(),
  551                        &delegate,
  552                        cx,
  553                    )
  554                    .await?;
  555
  556                    match (&mut initialization_options, override_options) {
  557                        (Some(initialization_options), Some(override_options)) => {
  558                            merge_json_value_into(override_options, initialization_options);
  559                        }
  560                        (None, override_options) => initialization_options = override_options,
  561                        _ => {}
  562                    }
  563
  564                    let initialization_params = cx.update(|cx| {
  565                        let mut params = language_server.default_initialize_params(
  566                            pull_diagnostics,
  567                            augments_syntax_tokens,
  568                            cx,
  569                        );
  570                        params.initialization_options = initialization_options;
  571                        adapter.adapter.prepare_initialize_params(params, cx)
  572                    })?;
  573
  574                    Self::setup_lsp_messages(
  575                        lsp_store.clone(),
  576                        &language_server,
  577                        delegate.clone(),
  578                        adapter.clone(),
  579                    );
  580
  581                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  582                        settings: workspace_config,
  583                    };
  584                    let language_server = cx
  585                        .update(|cx| {
  586                            let request_timeout = ProjectSettings::get_global(cx)
  587                                .global_lsp_settings
  588                                .get_request_timeout();
  589
  590                            language_server.initialize(
  591                                initialization_params,
  592                                Arc::new(did_change_configuration_params.clone()),
  593                                request_timeout,
  594                                cx,
  595                            )
  596                        })
  597                        .await
  598                        .inspect_err(|_| {
  599                            if let Some(lsp_store) = lsp_store.upgrade() {
  600                                lsp_store.update(cx, |lsp_store, cx| {
  601                                    lsp_store.cleanup_lsp_data(server_id);
  602                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  603                                });
  604                            }
  605                        })?;
  606
  607                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  608                        did_change_configuration_params,
  609                    )?;
  610
  611                    anyhow::Ok(language_server)
  612                }
  613                .await;
  614
  615                match result {
  616                    Ok(server) => {
  617                        lsp_store
  618                            .update(cx, |lsp_store, cx| {
  619                                lsp_store.insert_newly_running_language_server(
  620                                    adapter,
  621                                    server.clone(),
  622                                    server_id,
  623                                    key,
  624                                    pending_workspace_folders,
  625                                    cx,
  626                                );
  627                            })
  628                            .ok();
  629                        stderr_capture.lock().take();
  630                        Some(server)
  631                    }
  632
  633                    Err(err) => {
  634                        let log = stderr_capture.lock().take().unwrap_or_default();
  635                        delegate.update_status(
  636                            adapter.name(),
  637                            BinaryStatus::Failed {
  638                                error: if log.is_empty() {
  639                                    format!("{err:#}")
  640                                } else {
  641                                    format!("{err:#}\n-- stderr --\n{log}")
  642                                },
  643                            },
  644                        );
  645                        log::error!(
  646                            "Failed to start language server {server_name:?}: {}",
  647                            redact_command(&format!("{err:?}"))
  648                        );
  649                        if !log.is_empty() {
  650                            log::error!("server stderr: {}", redact_command(&log));
  651                        }
  652                        None
  653                    }
  654                }
  655            })
  656        };
  657        let state = LanguageServerState::Starting {
  658            startup,
  659            pending_workspace_folders,
  660        };
  661
  662        if update_binary_status {
  663            self.languages
  664                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  665        }
  666
  667        self.language_servers.insert(server_id, state);
  668        self.language_server_ids
  669            .entry(key)
  670            .or_insert(UnifiedLanguageServer {
  671                id: server_id,
  672                project_roots: Default::default(),
  673            });
  674        server_id
  675    }
  676
  677    fn get_language_server_binary(
  678        &self,
  679        worktree_abs_path: Arc<Path>,
  680        adapter: Arc<CachedLspAdapter>,
  681        settings: Arc<LspSettings>,
  682        toolchain: Option<Toolchain>,
  683        delegate: Arc<dyn LspAdapterDelegate>,
  684        allow_binary_download: bool,
  685        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  686        cx: &mut App,
  687    ) -> Task<Result<LanguageServerBinary>> {
  688        if let Some(settings) = &settings.binary
  689            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  690        {
  691            let settings = settings.clone();
  692            let languages = self.languages.clone();
  693            return cx.background_spawn(async move {
  694                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  695                    let already_trusted =  *wait_until_worktree_trust.borrow();
  696                    if !already_trusted {
  697                        log::info!(
  698                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  699                            adapter.name(),
  700                        );
  701                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  702                            if worktree_trusted {
  703                                break;
  704                            }
  705                        }
  706                        log::info!(
  707                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  708                            adapter.name(),
  709                        );
  710                    }
  711                    languages
  712                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  713                }
  714                let mut env = delegate.shell_env().await;
  715                env.extend(settings.env.unwrap_or_default());
  716
  717                Ok(LanguageServerBinary {
  718                    path: delegate.resolve_relative_path(path),
  719                    env: Some(env),
  720                    arguments: settings
  721                        .arguments
  722                        .unwrap_or_default()
  723                        .iter()
  724                        .map(Into::into)
  725                        .collect(),
  726                })
  727            });
  728        }
  729        let lsp_binary_options = LanguageServerBinaryOptions {
  730            allow_path_lookup: !settings
  731                .binary
  732                .as_ref()
  733                .and_then(|b| b.ignore_system_version)
  734                .unwrap_or_default(),
  735            allow_binary_download,
  736            pre_release: settings
  737                .fetch
  738                .as_ref()
  739                .and_then(|f| f.pre_release)
  740                .unwrap_or(false),
  741        };
  742
  743        cx.spawn(async move |cx| {
  744            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  745                let already_trusted =  *wait_until_worktree_trust.borrow();
  746                if !already_trusted {
  747                    log::info!(
  748                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  749                        adapter.name(),
  750                    );
  751                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  752                        if worktree_trusted {
  753                            break;
  754                        }
  755                    }
  756                    log::info!(
  757                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  758                            adapter.name(),
  759                    );
  760                }
  761            }
  762
  763            let (existing_binary, maybe_download_binary) = adapter
  764                .clone()
  765                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  766                .await
  767                .await;
  768
  769            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  770
  771            let mut binary = match (existing_binary, maybe_download_binary) {
  772                (binary, None) => binary?,
  773                (Err(_), Some(downloader)) => downloader.await?,
  774                (Ok(existing_binary), Some(downloader)) => {
  775                    let mut download_timeout = cx
  776                        .background_executor()
  777                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  778                        .fuse();
  779                    let mut downloader = downloader.fuse();
  780                    futures::select! {
  781                        _ = download_timeout => {
  782                            // Return existing binary and kick the existing work to the background.
  783                            cx.spawn(async move |_| downloader.await).detach();
  784                            Ok(existing_binary)
  785                        },
  786                        downloaded_or_existing_binary = downloader => {
  787                            // If download fails, this results in the existing binary.
  788                            downloaded_or_existing_binary
  789                        }
  790                    }?
  791                }
  792            };
  793            let mut shell_env = delegate.shell_env().await;
  794
  795            shell_env.extend(binary.env.unwrap_or_default());
  796
  797            if let Some(settings) = settings.binary.as_ref() {
  798                if let Some(arguments) = &settings.arguments {
  799                    binary.arguments = arguments.iter().map(Into::into).collect();
  800                }
  801                if let Some(env) = &settings.env {
  802                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  803                }
  804            }
  805
  806            binary.env = Some(shell_env);
  807            Ok(binary)
  808        })
  809    }
  810
  811    fn setup_lsp_messages(
  812        lsp_store: WeakEntity<LspStore>,
  813        language_server: &LanguageServer,
  814        delegate: Arc<dyn LspAdapterDelegate>,
  815        adapter: Arc<CachedLspAdapter>,
  816    ) {
  817        let name = language_server.name();
  818        let server_id = language_server.server_id();
  819        language_server
  820            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  821                let adapter = adapter.clone();
  822                let this = lsp_store.clone();
  823                move |mut params, cx| {
  824                    let adapter = adapter.clone();
  825                    if let Some(this) = this.upgrade() {
  826                        this.update(cx, |this, cx| {
  827                            adapter.process_diagnostics(&mut params, server_id);
  828
  829                            this.merge_lsp_diagnostics(
  830                                DiagnosticSourceKind::Pushed,
  831                                vec![DocumentDiagnosticsUpdate {
  832                                    server_id,
  833                                    diagnostics: params,
  834                                    result_id: None,
  835                                    disk_based_sources: Cow::Borrowed(
  836                                        &adapter.disk_based_diagnostic_sources,
  837                                    ),
  838                                    registration_id: None,
  839                                }],
  840                                |_, diagnostic, _cx| match diagnostic.source_kind {
  841                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  842                                        adapter.retain_old_diagnostic(diagnostic)
  843                                    }
  844                                    DiagnosticSourceKind::Pulled => true,
  845                                },
  846                                cx,
  847                            )
  848                            .log_err();
  849                        });
  850                    }
  851                }
  852            })
  853            .detach();
  854        language_server
  855            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  856                let adapter = adapter.adapter.clone();
  857                let delegate = delegate.clone();
  858                let this = lsp_store.clone();
  859                move |params, cx| {
  860                    let adapter = adapter.clone();
  861                    let delegate = delegate.clone();
  862                    let this = this.clone();
  863                    let mut cx = cx.clone();
  864                    async move {
  865                        let toolchain_for_id = this
  866                            .update(&mut cx, |this, _| {
  867                                this.as_local()?.language_server_ids.iter().find_map(
  868                                    |(seed, value)| {
  869                                        (value.id == server_id).then(|| seed.toolchain.clone())
  870                                    },
  871                                )
  872                            })?
  873                            .context("Expected the LSP store to be in a local mode")?;
  874
  875                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  876                        for item in &params.items {
  877                            let scope_uri = item.scope_uri.clone();
  878                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  879                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  880                            else {
  881                                // We've already queried workspace configuration of this URI.
  882                                continue;
  883                            };
  884                            let workspace_config = Self::workspace_configuration_for_adapter(
  885                                adapter.clone(),
  886                                &delegate,
  887                                toolchain_for_id.clone(),
  888                                scope_uri,
  889                                &mut cx,
  890                            )
  891                            .await?;
  892                            new_scope_uri.insert(workspace_config);
  893                        }
  894
  895                        Ok(params
  896                            .items
  897                            .into_iter()
  898                            .filter_map(|item| {
  899                                let workspace_config =
  900                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  901                                if let Some(section) = &item.section {
  902                                    Some(
  903                                        workspace_config
  904                                            .get(section)
  905                                            .cloned()
  906                                            .unwrap_or(serde_json::Value::Null),
  907                                    )
  908                                } else {
  909                                    Some(workspace_config.clone())
  910                                }
  911                            })
  912                            .collect())
  913                    }
  914                }
  915            })
  916            .detach();
  917
  918        language_server
  919            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  920                let this = lsp_store.clone();
  921                move |_, cx| {
  922                    let this = this.clone();
  923                    let cx = cx.clone();
  924                    async move {
  925                        let Some(server) =
  926                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  927                        else {
  928                            return Ok(None);
  929                        };
  930                        let root = server.workspace_folders();
  931                        Ok(Some(
  932                            root.into_iter()
  933                                .map(|uri| WorkspaceFolder {
  934                                    uri,
  935                                    name: Default::default(),
  936                                })
  937                                .collect(),
  938                        ))
  939                    }
  940                }
  941            })
  942            .detach();
  943        // Even though we don't have handling for these requests, respond to them to
  944        // avoid stalling any language server like `gopls` which waits for a response
  945        // to these requests when initializing.
  946        language_server
  947            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  948                let this = lsp_store.clone();
  949                move |params, cx| {
  950                    let this = this.clone();
  951                    let mut cx = cx.clone();
  952                    async move {
  953                        this.update(&mut cx, |this, _| {
  954                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  955                            {
  956                                status
  957                                    .progress_tokens
  958                                    .insert(ProgressToken::from_lsp(params.token));
  959                            }
  960                        })?;
  961
  962                        Ok(())
  963                    }
  964                }
  965            })
  966            .detach();
  967
  968        language_server
  969            .on_request::<lsp::request::RegisterCapability, _, _>({
  970                let lsp_store = lsp_store.clone();
  971                move |params, cx| {
  972                    let lsp_store = lsp_store.clone();
  973                    let mut cx = cx.clone();
  974                    async move {
  975                        lsp_store
  976                            .update(&mut cx, |lsp_store, cx| {
  977                                if lsp_store.as_local().is_some() {
  978                                    match lsp_store
  979                                        .register_server_capabilities(server_id, params, cx)
  980                                    {
  981                                        Ok(()) => {}
  982                                        Err(e) => {
  983                                            log::error!(
  984                                                "Failed to register server capabilities: {e:#}"
  985                                            );
  986                                        }
  987                                    };
  988                                }
  989                            })
  990                            .ok();
  991                        Ok(())
  992                    }
  993                }
  994            })
  995            .detach();
  996
  997        language_server
  998            .on_request::<lsp::request::UnregisterCapability, _, _>({
  999                let lsp_store = lsp_store.clone();
 1000                move |params, cx| {
 1001                    let lsp_store = lsp_store.clone();
 1002                    let mut cx = cx.clone();
 1003                    async move {
 1004                        lsp_store
 1005                            .update(&mut cx, |lsp_store, cx| {
 1006                                if lsp_store.as_local().is_some() {
 1007                                    match lsp_store
 1008                                        .unregister_server_capabilities(server_id, params, cx)
 1009                                    {
 1010                                        Ok(()) => {}
 1011                                        Err(e) => {
 1012                                            log::error!(
 1013                                                "Failed to unregister server capabilities: {e:#}"
 1014                                            );
 1015                                        }
 1016                                    }
 1017                                }
 1018                            })
 1019                            .ok();
 1020                        Ok(())
 1021                    }
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        language_server
 1027            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1028                let this = lsp_store.clone();
 1029                move |params, cx| {
 1030                    let mut cx = cx.clone();
 1031                    let this = this.clone();
 1032                    async move {
 1033                        LocalLspStore::on_lsp_workspace_edit(
 1034                            this.clone(),
 1035                            params,
 1036                            server_id,
 1037                            &mut cx,
 1038                        )
 1039                        .await
 1040                    }
 1041                }
 1042            })
 1043            .detach();
 1044
 1045        language_server
 1046            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1047                let lsp_store = lsp_store.clone();
 1048                let request_id = Arc::new(AtomicUsize::new(0));
 1049                move |(), cx| {
 1050                    let lsp_store = lsp_store.clone();
 1051                    let request_id = request_id.clone();
 1052                    let mut cx = cx.clone();
 1053                    async move {
 1054                        lsp_store
 1055                            .update(&mut cx, |lsp_store, cx| {
 1056                                let request_id =
 1057                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1058                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1059                                    server_id,
 1060                                    request_id,
 1061                                });
 1062                                lsp_store
 1063                                    .downstream_client
 1064                                    .as_ref()
 1065                                    .map(|(client, project_id)| {
 1066                                        client.send(proto::RefreshInlayHints {
 1067                                            project_id: *project_id,
 1068                                            server_id: server_id.to_proto(),
 1069                                            request_id: request_id.map(|id| id as u64),
 1070                                        })
 1071                                    })
 1072                            })?
 1073                            .transpose()?;
 1074                        Ok(())
 1075                    }
 1076                }
 1077            })
 1078            .detach();
 1079
 1080        language_server
 1081            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1082                let this = lsp_store.clone();
 1083                move |(), cx| {
 1084                    let this = this.clone();
 1085                    let mut cx = cx.clone();
 1086                    async move {
 1087                        this.update(&mut cx, |this, cx| {
 1088                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1089                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1090                                client.send(proto::RefreshCodeLens {
 1091                                    project_id: *project_id,
 1092                                })
 1093                            })
 1094                        })?
 1095                        .transpose()?;
 1096                        Ok(())
 1097                    }
 1098                }
 1099            })
 1100            .detach();
 1101
 1102        language_server
 1103            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1104                let lsp_store = lsp_store.clone();
 1105                let request_id = Arc::new(AtomicUsize::new(0));
 1106                move |(), cx| {
 1107                    let lsp_store = lsp_store.clone();
 1108                    let request_id = request_id.clone();
 1109                    let mut cx = cx.clone();
 1110                    async move {
 1111                        lsp_store
 1112                            .update(&mut cx, |lsp_store, cx| {
 1113                                let request_id =
 1114                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1115                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1116                                    server_id,
 1117                                    request_id,
 1118                                });
 1119                                lsp_store
 1120                                    .downstream_client
 1121                                    .as_ref()
 1122                                    .map(|(client, project_id)| {
 1123                                        client.send(proto::RefreshSemanticTokens {
 1124                                            project_id: *project_id,
 1125                                            server_id: server_id.to_proto(),
 1126                                            request_id: request_id.map(|id| id as u64),
 1127                                        })
 1128                                    })
 1129                            })?
 1130                            .transpose()?;
 1131                        Ok(())
 1132                    }
 1133                }
 1134            })
 1135            .detach();
 1136
 1137        language_server
 1138            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1139                let this = lsp_store.clone();
 1140                move |(), cx| {
 1141                    let this = this.clone();
 1142                    let mut cx = cx.clone();
 1143                    async move {
 1144                        this.update(&mut cx, |lsp_store, cx| {
 1145                            lsp_store.pull_workspace_diagnostics(server_id);
 1146                            lsp_store
 1147                                .downstream_client
 1148                                .as_ref()
 1149                                .map(|(client, project_id)| {
 1150                                    client.send(proto::PullWorkspaceDiagnostics {
 1151                                        project_id: *project_id,
 1152                                        server_id: server_id.to_proto(),
 1153                                    })
 1154                                })
 1155                                .transpose()?;
 1156                            anyhow::Ok(
 1157                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1158                            )
 1159                        })??
 1160                        .await;
 1161                        Ok(())
 1162                    }
 1163                }
 1164            })
 1165            .detach();
 1166
 1167        language_server
 1168            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1169                let this = lsp_store.clone();
 1170                let name = name.to_string();
 1171                let adapter = adapter.clone();
 1172                move |params, cx| {
 1173                    let this = this.clone();
 1174                    let name = name.to_string();
 1175                    let adapter = adapter.clone();
 1176                    let mut cx = cx.clone();
 1177                    async move {
 1178                        let actions = params.actions.unwrap_or_default();
 1179                        let message = params.message.clone();
 1180                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1181                        let level = match params.typ {
 1182                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1183                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1184                            _ => PromptLevel::Info,
 1185                        };
 1186                        let request = LanguageServerPromptRequest::new(
 1187                            level,
 1188                            params.message,
 1189                            actions,
 1190                            name.clone(),
 1191                            tx,
 1192                        );
 1193
 1194                        let did_update = this
 1195                            .update(&mut cx, |_, cx| {
 1196                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1197                            })
 1198                            .is_ok();
 1199                        if did_update {
 1200                            let response = rx.recv().await.ok();
 1201                            if let Some(ref selected_action) = response {
 1202                                let context = language::PromptResponseContext {
 1203                                    message,
 1204                                    selected_action: selected_action.clone(),
 1205                                };
 1206                                adapter.process_prompt_response(&context, &mut cx)
 1207                            }
 1208
 1209                            Ok(response)
 1210                        } else {
 1211                            Ok(None)
 1212                        }
 1213                    }
 1214                }
 1215            })
 1216            .detach();
 1217        language_server
 1218            .on_notification::<lsp::notification::ShowMessage, _>({
 1219                let this = lsp_store.clone();
 1220                let name = name.to_string();
 1221                move |params, cx| {
 1222                    let this = this.clone();
 1223                    let name = name.to_string();
 1224                    let mut cx = cx.clone();
 1225
 1226                    let (tx, _) = smol::channel::bounded(1);
 1227                    let level = match params.typ {
 1228                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1229                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1230                        _ => PromptLevel::Info,
 1231                    };
 1232                    let request =
 1233                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1234
 1235                    let _ = this.update(&mut cx, |_, cx| {
 1236                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1237                    });
 1238                }
 1239            })
 1240            .detach();
 1241
 1242        let disk_based_diagnostics_progress_token =
 1243            adapter.disk_based_diagnostics_progress_token.clone();
 1244
 1245        language_server
 1246            .on_notification::<lsp::notification::Progress, _>({
 1247                let this = lsp_store.clone();
 1248                move |params, cx| {
 1249                    if let Some(this) = this.upgrade() {
 1250                        this.update(cx, |this, cx| {
 1251                            this.on_lsp_progress(
 1252                                params,
 1253                                server_id,
 1254                                disk_based_diagnostics_progress_token.clone(),
 1255                                cx,
 1256                            );
 1257                        });
 1258                    }
 1259                }
 1260            })
 1261            .detach();
 1262
 1263        language_server
 1264            .on_notification::<lsp::notification::LogMessage, _>({
 1265                let this = lsp_store.clone();
 1266                move |params, cx| {
 1267                    if let Some(this) = this.upgrade() {
 1268                        this.update(cx, |_, cx| {
 1269                            cx.emit(LspStoreEvent::LanguageServerLog(
 1270                                server_id,
 1271                                LanguageServerLogType::Log(params.typ),
 1272                                params.message,
 1273                            ));
 1274                        });
 1275                    }
 1276                }
 1277            })
 1278            .detach();
 1279
 1280        language_server
 1281            .on_notification::<lsp::notification::LogTrace, _>({
 1282                let this = lsp_store.clone();
 1283                move |params, cx| {
 1284                    let mut cx = cx.clone();
 1285                    if let Some(this) = this.upgrade() {
 1286                        this.update(&mut cx, |_, cx| {
 1287                            cx.emit(LspStoreEvent::LanguageServerLog(
 1288                                server_id,
 1289                                LanguageServerLogType::Trace {
 1290                                    verbose_info: params.verbose,
 1291                                },
 1292                                params.message,
 1293                            ));
 1294                        });
 1295                    }
 1296                }
 1297            })
 1298            .detach();
 1299
 1300        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1301        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1302        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1303        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1304    }
 1305
 1306    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1307        let shutdown_futures = self
 1308            .language_servers
 1309            .drain()
 1310            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1311            .collect::<Vec<_>>();
 1312
 1313        async move {
 1314            join_all(shutdown_futures).await;
 1315        }
 1316    }
 1317
 1318    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1319        match server_state {
 1320            LanguageServerState::Running { server, .. } => {
 1321                if let Some(shutdown) = server.shutdown() {
 1322                    shutdown.await;
 1323                }
 1324            }
 1325            LanguageServerState::Starting { startup, .. } => {
 1326                if let Some(server) = startup.await
 1327                    && let Some(shutdown) = server.shutdown()
 1328                {
 1329                    shutdown.await;
 1330                }
 1331            }
 1332        }
 1333        Ok(())
 1334    }
 1335
 1336    fn language_servers_for_worktree(
 1337        &self,
 1338        worktree_id: WorktreeId,
 1339    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1340        self.language_server_ids
 1341            .iter()
 1342            .filter_map(move |(seed, state)| {
 1343                if seed.worktree_id != worktree_id {
 1344                    return None;
 1345                }
 1346
 1347                if let Some(LanguageServerState::Running { server, .. }) =
 1348                    self.language_servers.get(&state.id)
 1349                {
 1350                    Some(server)
 1351                } else {
 1352                    None
 1353                }
 1354            })
 1355    }
 1356
 1357    fn language_server_ids_for_project_path(
 1358        &self,
 1359        project_path: ProjectPath,
 1360        language: &Language,
 1361        cx: &mut App,
 1362    ) -> Vec<LanguageServerId> {
 1363        let Some(worktree) = self
 1364            .worktree_store
 1365            .read(cx)
 1366            .worktree_for_id(project_path.worktree_id, cx)
 1367        else {
 1368            return Vec::new();
 1369        };
 1370        let delegate: Arc<dyn ManifestDelegate> =
 1371            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1372
 1373        self.lsp_tree
 1374            .get(
 1375                project_path,
 1376                language.name(),
 1377                language.manifest(),
 1378                &delegate,
 1379                cx,
 1380            )
 1381            .collect::<Vec<_>>()
 1382    }
 1383
 1384    fn language_server_ids_for_buffer(
 1385        &self,
 1386        buffer: &Buffer,
 1387        cx: &mut App,
 1388    ) -> Vec<LanguageServerId> {
 1389        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1390            let worktree_id = file.worktree_id(cx);
 1391
 1392            let path: Arc<RelPath> = file
 1393                .path()
 1394                .parent()
 1395                .map(Arc::from)
 1396                .unwrap_or_else(|| file.path().clone());
 1397            let worktree_path = ProjectPath { worktree_id, path };
 1398            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1399        } else {
 1400            Vec::new()
 1401        }
 1402    }
 1403
 1404    fn language_servers_for_buffer<'a>(
 1405        &'a self,
 1406        buffer: &'a Buffer,
 1407        cx: &'a mut App,
 1408    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1409        self.language_server_ids_for_buffer(buffer, cx)
 1410            .into_iter()
 1411            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1412                LanguageServerState::Running {
 1413                    adapter, server, ..
 1414                } => Some((adapter, server)),
 1415                _ => None,
 1416            })
 1417    }
 1418
 1419    async fn execute_code_action_kind_locally(
 1420        lsp_store: WeakEntity<LspStore>,
 1421        mut buffers: Vec<Entity<Buffer>>,
 1422        kind: CodeActionKind,
 1423        push_to_history: bool,
 1424        cx: &mut AsyncApp,
 1425    ) -> anyhow::Result<ProjectTransaction> {
 1426        // Do not allow multiple concurrent code actions requests for the
 1427        // same buffer.
 1428        lsp_store.update(cx, |this, cx| {
 1429            let this = this.as_local_mut().unwrap();
 1430            buffers.retain(|buffer| {
 1431                this.buffers_being_formatted
 1432                    .insert(buffer.read(cx).remote_id())
 1433            });
 1434        })?;
 1435        let _cleanup = defer({
 1436            let this = lsp_store.clone();
 1437            let mut cx = cx.clone();
 1438            let buffers = &buffers;
 1439            move || {
 1440                this.update(&mut cx, |this, cx| {
 1441                    let this = this.as_local_mut().unwrap();
 1442                    for buffer in buffers {
 1443                        this.buffers_being_formatted
 1444                            .remove(&buffer.read(cx).remote_id());
 1445                    }
 1446                })
 1447                .ok();
 1448            }
 1449        });
 1450        let mut project_transaction = ProjectTransaction::default();
 1451
 1452        for buffer in &buffers {
 1453            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1454                buffer.update(cx, |buffer, cx| {
 1455                    lsp_store
 1456                        .as_local()
 1457                        .unwrap()
 1458                        .language_servers_for_buffer(buffer, cx)
 1459                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1460                        .collect::<Vec<_>>()
 1461                })
 1462            })?;
 1463            for (_, language_server) in adapters_and_servers.iter() {
 1464                let actions = Self::get_server_code_actions_from_action_kinds(
 1465                    &lsp_store,
 1466                    language_server.server_id(),
 1467                    vec![kind.clone()],
 1468                    buffer,
 1469                    cx,
 1470                )
 1471                .await?;
 1472                Self::execute_code_actions_on_server(
 1473                    &lsp_store,
 1474                    language_server,
 1475                    actions,
 1476                    push_to_history,
 1477                    &mut project_transaction,
 1478                    cx,
 1479                )
 1480                .await?;
 1481            }
 1482        }
 1483        Ok(project_transaction)
 1484    }
 1485
 1486    async fn format_locally(
 1487        lsp_store: WeakEntity<LspStore>,
 1488        mut buffers: Vec<FormattableBuffer>,
 1489        push_to_history: bool,
 1490        trigger: FormatTrigger,
 1491        logger: zlog::Logger,
 1492        cx: &mut AsyncApp,
 1493    ) -> anyhow::Result<ProjectTransaction> {
 1494        // Do not allow multiple concurrent formatting requests for the
 1495        // same buffer.
 1496        lsp_store.update(cx, |this, cx| {
 1497            let this = this.as_local_mut().unwrap();
 1498            buffers.retain(|buffer| {
 1499                this.buffers_being_formatted
 1500                    .insert(buffer.handle.read(cx).remote_id())
 1501            });
 1502        })?;
 1503
 1504        let _cleanup = defer({
 1505            let this = lsp_store.clone();
 1506            let mut cx = cx.clone();
 1507            let buffers = &buffers;
 1508            move || {
 1509                this.update(&mut cx, |this, cx| {
 1510                    let this = this.as_local_mut().unwrap();
 1511                    for buffer in buffers {
 1512                        this.buffers_being_formatted
 1513                            .remove(&buffer.handle.read(cx).remote_id());
 1514                    }
 1515                })
 1516                .ok();
 1517            }
 1518        });
 1519
 1520        let mut project_transaction = ProjectTransaction::default();
 1521
 1522        for buffer in &buffers {
 1523            zlog::debug!(
 1524                logger =>
 1525                "formatting buffer '{:?}'",
 1526                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1527            );
 1528            // Create an empty transaction to hold all of the formatting edits.
 1529            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1530                // ensure no transactions created while formatting are
 1531                // grouped with the previous transaction in the history
 1532                // based on the transaction group interval
 1533                buffer.finalize_last_transaction();
 1534                buffer
 1535                    .start_transaction()
 1536                    .context("transaction already open")?;
 1537                buffer.end_transaction(cx);
 1538                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1539                buffer.finalize_last_transaction();
 1540                anyhow::Ok(transaction_id)
 1541            })?;
 1542
 1543            let result = Self::format_buffer_locally(
 1544                lsp_store.clone(),
 1545                buffer,
 1546                formatting_transaction_id,
 1547                trigger,
 1548                logger,
 1549                cx,
 1550            )
 1551            .await;
 1552
 1553            buffer.handle.update(cx, |buffer, cx| {
 1554                let Some(formatting_transaction) =
 1555                    buffer.get_transaction(formatting_transaction_id).cloned()
 1556                else {
 1557                    zlog::warn!(logger => "no formatting transaction");
 1558                    return;
 1559                };
 1560                if formatting_transaction.edit_ids.is_empty() {
 1561                    zlog::debug!(logger => "no changes made while formatting");
 1562                    buffer.forget_transaction(formatting_transaction_id);
 1563                    return;
 1564                }
 1565                if !push_to_history {
 1566                    zlog::trace!(logger => "forgetting format transaction");
 1567                    buffer.forget_transaction(formatting_transaction.id);
 1568                }
 1569                project_transaction
 1570                    .0
 1571                    .insert(cx.entity(), formatting_transaction);
 1572            });
 1573
 1574            result?;
 1575        }
 1576
 1577        Ok(project_transaction)
 1578    }
 1579
 1580    async fn format_buffer_locally(
 1581        lsp_store: WeakEntity<LspStore>,
 1582        buffer: &FormattableBuffer,
 1583        formatting_transaction_id: clock::Lamport,
 1584        trigger: FormatTrigger,
 1585        logger: zlog::Logger,
 1586        cx: &mut AsyncApp,
 1587    ) -> Result<()> {
 1588        let (adapters_and_servers, settings, request_timeout) =
 1589            lsp_store.update(cx, |lsp_store, cx| {
 1590                buffer.handle.update(cx, |buffer, cx| {
 1591                    let adapters_and_servers = lsp_store
 1592                        .as_local()
 1593                        .unwrap()
 1594                        .language_servers_for_buffer(buffer, cx)
 1595                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1596                        .collect::<Vec<_>>();
 1597                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1598                    let request_timeout = ProjectSettings::get_global(cx)
 1599                        .global_lsp_settings
 1600                        .get_request_timeout();
 1601                    (adapters_and_servers, settings, request_timeout)
 1602                })
 1603            })?;
 1604
 1605        // handle whitespace formatting
 1606        if settings.remove_trailing_whitespace_on_save {
 1607            zlog::trace!(logger => "removing trailing whitespace");
 1608            let diff = buffer
 1609                .handle
 1610                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1611                .await;
 1612            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1613                buffer.apply_diff(diff, cx);
 1614            })?;
 1615        }
 1616
 1617        if settings.ensure_final_newline_on_save {
 1618            zlog::trace!(logger => "ensuring final newline");
 1619            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1620                buffer.ensure_final_newline(cx);
 1621            })?;
 1622        }
 1623
 1624        // Formatter for `code_actions_on_format` that runs before
 1625        // the rest of the formatters
 1626        let mut code_actions_on_format_formatters = None;
 1627        let should_run_code_actions_on_format = !matches!(
 1628            (trigger, &settings.format_on_save),
 1629            (FormatTrigger::Save, &FormatOnSave::Off)
 1630        );
 1631        if should_run_code_actions_on_format {
 1632            let have_code_actions_to_run_on_format = settings
 1633                .code_actions_on_format
 1634                .values()
 1635                .any(|enabled| *enabled);
 1636            if have_code_actions_to_run_on_format {
 1637                zlog::trace!(logger => "going to run code actions on format");
 1638                code_actions_on_format_formatters = Some(
 1639                    settings
 1640                        .code_actions_on_format
 1641                        .iter()
 1642                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1643                        .cloned()
 1644                        .map(Formatter::CodeAction)
 1645                        .collect::<Vec<_>>(),
 1646                );
 1647            }
 1648        }
 1649
 1650        let formatters = match (trigger, &settings.format_on_save) {
 1651            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1652            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1653                settings.formatter.as_ref()
 1654            }
 1655        };
 1656
 1657        let formatters = code_actions_on_format_formatters
 1658            .iter()
 1659            .flatten()
 1660            .chain(formatters);
 1661
 1662        for formatter in formatters {
 1663            let formatter = if formatter == &Formatter::Auto {
 1664                if settings.prettier.allowed {
 1665                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1666                    &Formatter::Prettier
 1667                } else {
 1668                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1669                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1670                }
 1671            } else {
 1672                formatter
 1673            };
 1674            if let Err(err) = Self::apply_formatter(
 1675                formatter,
 1676                &lsp_store,
 1677                buffer,
 1678                formatting_transaction_id,
 1679                &adapters_and_servers,
 1680                &settings,
 1681                request_timeout,
 1682                logger,
 1683                cx,
 1684            )
 1685            .await
 1686            {
 1687                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1688            }
 1689        }
 1690
 1691        Ok(())
 1692    }
 1693
 1694    async fn apply_formatter(
 1695        formatter: &Formatter,
 1696        lsp_store: &WeakEntity<LspStore>,
 1697        buffer: &FormattableBuffer,
 1698        formatting_transaction_id: clock::Lamport,
 1699        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1700        settings: &LanguageSettings,
 1701        request_timeout: Duration,
 1702        logger: zlog::Logger,
 1703        cx: &mut AsyncApp,
 1704    ) -> anyhow::Result<()> {
 1705        match formatter {
 1706            Formatter::None => {
 1707                zlog::trace!(logger => "skipping formatter 'none'");
 1708                return Ok(());
 1709            }
 1710            Formatter::Auto => {
 1711                debug_panic!("Auto resolved above");
 1712                return Ok(());
 1713            }
 1714            Formatter::Prettier => {
 1715                let logger = zlog::scoped!(logger => "prettier");
 1716                zlog::trace!(logger => "formatting");
 1717                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1718
 1719                // When selection ranges are provided (via FormatSelections), we pass the
 1720                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1721                // After diffing, we filter the resulting edits to only keep those that
 1722                // overlap with the original byte-level selection ranges.
 1723                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1724                    Some(ranges) if !ranges.is_empty() => {
 1725                        let (utf16_range, byte_ranges) =
 1726                            buffer.handle.read_with(cx, |buffer, _cx| {
 1727                                let snapshot = buffer.snapshot();
 1728                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1729                                let mut max_end_utf16 = OffsetUtf16(0);
 1730                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1731                                for range in ranges {
 1732                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1733                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1734                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1735                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1736
 1737                                    let start_byte = range.start.to_offset(&snapshot);
 1738                                    let end_byte = range.end.to_offset(&snapshot);
 1739                                    byte_ranges.push(start_byte..end_byte);
 1740                                }
 1741                                (min_start_utf16..max_end_utf16, byte_ranges)
 1742                            });
 1743                        (Some(utf16_range), Some(byte_ranges))
 1744                    }
 1745                    _ => (None, None),
 1746                };
 1747
 1748                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1749                    lsp_store.prettier_store().unwrap().downgrade()
 1750                })?;
 1751                let diff = prettier_store::format_with_prettier(
 1752                    &prettier,
 1753                    &buffer.handle,
 1754                    range_utf16,
 1755                    cx,
 1756                )
 1757                .await
 1758                .transpose()?;
 1759                let Some(mut diff) = diff else {
 1760                    zlog::trace!(logger => "No changes");
 1761                    return Ok(());
 1762                };
 1763
 1764                if let Some(byte_ranges) = byte_ranges {
 1765                    diff.edits.retain(|(edit_range, _)| {
 1766                        byte_ranges.iter().any(|selection_range| {
 1767                            edit_range.start < selection_range.end
 1768                                && edit_range.end > selection_range.start
 1769                        })
 1770                    });
 1771                    if diff.edits.is_empty() {
 1772                        zlog::trace!(logger => "No changes within selection");
 1773                        return Ok(());
 1774                    }
 1775                }
 1776
 1777                extend_formatting_transaction(
 1778                    buffer,
 1779                    formatting_transaction_id,
 1780                    cx,
 1781                    |buffer, cx| {
 1782                        buffer.apply_diff(diff, cx);
 1783                    },
 1784                )?;
 1785            }
 1786            Formatter::External { command, arguments } => {
 1787                let logger = zlog::scoped!(logger => "command");
 1788
 1789                if buffer.ranges.is_some() {
 1790                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1791                    return Ok(());
 1792                }
 1793
 1794                zlog::trace!(logger => "formatting");
 1795                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1796
 1797                let diff =
 1798                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1799                        .await
 1800                        .with_context(|| {
 1801                            format!("Failed to format buffer via external command: {}", command)
 1802                        })?;
 1803                let Some(diff) = diff else {
 1804                    zlog::trace!(logger => "No changes");
 1805                    return Ok(());
 1806                };
 1807
 1808                extend_formatting_transaction(
 1809                    buffer,
 1810                    formatting_transaction_id,
 1811                    cx,
 1812                    |buffer, cx| {
 1813                        buffer.apply_diff(diff, cx);
 1814                    },
 1815                )?;
 1816            }
 1817            Formatter::LanguageServer(specifier) => {
 1818                let logger = zlog::scoped!(logger => "language-server");
 1819                zlog::trace!(logger => "formatting");
 1820                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1821
 1822                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1823                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1824                    return Ok(());
 1825                };
 1826
 1827                let language_server = match specifier {
 1828                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1829                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1830                            if adapter.name.0.as_ref() == name {
 1831                                Some(server.clone())
 1832                            } else {
 1833                                None
 1834                            }
 1835                        })
 1836                    }
 1837                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1838                        .iter()
 1839                        .find(|(_, server)| Self::server_supports_formatting(server))
 1840                        .map(|(_, server)| server.clone()),
 1841                };
 1842
 1843                let Some(language_server) = language_server else {
 1844                    log::debug!(
 1845                        "No language server found to format buffer '{:?}'. Skipping",
 1846                        buffer_path_abs.as_path().to_string_lossy()
 1847                    );
 1848                    return Ok(());
 1849                };
 1850
 1851                zlog::trace!(
 1852                    logger =>
 1853                    "Formatting buffer '{:?}' using language server '{:?}'",
 1854                    buffer_path_abs.as_path().to_string_lossy(),
 1855                    language_server.name()
 1856                );
 1857
 1858                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1859                    zlog::trace!(logger => "formatting ranges");
 1860                    Self::format_ranges_via_lsp(
 1861                        &lsp_store,
 1862                        &buffer.handle,
 1863                        ranges,
 1864                        buffer_path_abs,
 1865                        &language_server,
 1866                        &settings,
 1867                        cx,
 1868                    )
 1869                    .await
 1870                    .context("Failed to format ranges via language server")?
 1871                } else {
 1872                    zlog::trace!(logger => "formatting full");
 1873                    Self::format_via_lsp(
 1874                        &lsp_store,
 1875                        &buffer.handle,
 1876                        buffer_path_abs,
 1877                        &language_server,
 1878                        &settings,
 1879                        cx,
 1880                    )
 1881                    .await
 1882                    .context("failed to format via language server")?
 1883                };
 1884
 1885                if edits.is_empty() {
 1886                    zlog::trace!(logger => "No changes");
 1887                    return Ok(());
 1888                }
 1889                extend_formatting_transaction(
 1890                    buffer,
 1891                    formatting_transaction_id,
 1892                    cx,
 1893                    |buffer, cx| {
 1894                        buffer.edit(edits, None, cx);
 1895                    },
 1896                )?;
 1897            }
 1898            Formatter::CodeAction(code_action_name) => {
 1899                let logger = zlog::scoped!(logger => "code-actions");
 1900                zlog::trace!(logger => "formatting");
 1901                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1902
 1903                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1904                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1905                    return Ok(());
 1906                };
 1907
 1908                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1909                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1910
 1911                let mut actions_and_servers = Vec::new();
 1912
 1913                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1914                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1915                        &lsp_store,
 1916                        language_server.server_id(),
 1917                        vec![code_action_kind.clone()],
 1918                        &buffer.handle,
 1919                        cx,
 1920                    )
 1921                    .await
 1922                    .with_context(|| {
 1923                        format!(
 1924                            "Failed to resolve code action {:?} with language server {}",
 1925                            code_action_kind,
 1926                            language_server.name()
 1927                        )
 1928                    });
 1929                    let Ok(actions) = actions_result else {
 1930                        // note: it may be better to set result to the error and break formatters here
 1931                        // but for now we try to execute the actions that we can resolve and skip the rest
 1932                        zlog::error!(
 1933                            logger =>
 1934                            "Failed to resolve code action {:?} with language server {}",
 1935                            code_action_kind,
 1936                            language_server.name()
 1937                        );
 1938                        continue;
 1939                    };
 1940                    for action in actions {
 1941                        actions_and_servers.push((action, index));
 1942                    }
 1943                }
 1944
 1945                if actions_and_servers.is_empty() {
 1946                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1947                    return Ok(());
 1948                }
 1949
 1950                'actions: for (mut action, server_index) in actions_and_servers {
 1951                    let server = &adapters_and_servers[server_index].1;
 1952
 1953                    let describe_code_action = |action: &CodeAction| {
 1954                        format!(
 1955                            "code action '{}' with title \"{}\" on server {}",
 1956                            action
 1957                                .lsp_action
 1958                                .action_kind()
 1959                                .unwrap_or("unknown".into())
 1960                                .as_str(),
 1961                            action.lsp_action.title(),
 1962                            server.name(),
 1963                        )
 1964                    };
 1965
 1966                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1967
 1968                    if let Err(err) =
 1969                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1970                    {
 1971                        zlog::error!(
 1972                            logger =>
 1973                            "Failed to resolve {}. Error: {}",
 1974                            describe_code_action(&action),
 1975                            err
 1976                        );
 1977                        continue;
 1978                    }
 1979
 1980                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1981                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1982                        // but filters out and logs warnings for code actions that require unreasonably
 1983                        // difficult handling on our part, such as:
 1984                        // - applying edits that call commands
 1985                        //   which can result in arbitrary workspace edits being sent from the server that
 1986                        //   have no way of being tied back to the command that initiated them (i.e. we
 1987                        //   can't know which edits are part of the format request, or if the server is done sending
 1988                        //   actions in response to the command)
 1989                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1990                        //   as we then would need to handle such changes correctly in the local history as well
 1991                        //   as the remote history through the ProjectTransaction
 1992                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1993                        // Supporting these actions is not impossible, but not supported as of yet.
 1994                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1995                            zlog::trace!(
 1996                                logger =>
 1997                                "No changes for code action. Skipping {}",
 1998                                describe_code_action(&action),
 1999                            );
 2000                            continue;
 2001                        }
 2002
 2003                        let mut operations = Vec::new();
 2004                        if let Some(document_changes) = edit.document_changes {
 2005                            match document_changes {
 2006                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2007                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2008                                ),
 2009                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2010                            }
 2011                        } else if let Some(changes) = edit.changes {
 2012                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2013                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2014                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2015                                        uri,
 2016                                        version: None,
 2017                                    },
 2018                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2019                                })
 2020                            }));
 2021                        }
 2022
 2023                        let mut edits = Vec::with_capacity(operations.len());
 2024
 2025                        if operations.is_empty() {
 2026                            zlog::trace!(
 2027                                logger =>
 2028                                "No changes for code action. Skipping {}",
 2029                                describe_code_action(&action),
 2030                            );
 2031                            continue;
 2032                        }
 2033                        for operation in operations {
 2034                            let op = match operation {
 2035                                lsp::DocumentChangeOperation::Edit(op) => op,
 2036                                lsp::DocumentChangeOperation::Op(_) => {
 2037                                    zlog::warn!(
 2038                                        logger =>
 2039                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2040                                        describe_code_action(&action),
 2041                                    );
 2042                                    continue 'actions;
 2043                                }
 2044                            };
 2045                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2046                                zlog::warn!(
 2047                                    logger =>
 2048                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2049                                    &op.text_document.uri,
 2050                                    describe_code_action(&action),
 2051                                );
 2052                                continue 'actions;
 2053                            };
 2054                            if &file_path != buffer_path_abs {
 2055                                zlog::warn!(
 2056                                    logger =>
 2057                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2058                                    file_path,
 2059                                    buffer_path_abs,
 2060                                    describe_code_action(&action),
 2061                                );
 2062                                continue 'actions;
 2063                            }
 2064
 2065                            let mut lsp_edits = Vec::new();
 2066                            for edit in op.edits {
 2067                                match edit {
 2068                                    Edit::Plain(edit) => {
 2069                                        if !lsp_edits.contains(&edit) {
 2070                                            lsp_edits.push(edit);
 2071                                        }
 2072                                    }
 2073                                    Edit::Annotated(edit) => {
 2074                                        if !lsp_edits.contains(&edit.text_edit) {
 2075                                            lsp_edits.push(edit.text_edit);
 2076                                        }
 2077                                    }
 2078                                    Edit::Snippet(_) => {
 2079                                        zlog::warn!(
 2080                                            logger =>
 2081                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2082                                            describe_code_action(&action),
 2083                                        );
 2084                                        continue 'actions;
 2085                                    }
 2086                                }
 2087                            }
 2088                            let edits_result = lsp_store
 2089                                .update(cx, |lsp_store, cx| {
 2090                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2091                                        &buffer.handle,
 2092                                        lsp_edits,
 2093                                        server.server_id(),
 2094                                        op.text_document.version,
 2095                                        cx,
 2096                                    )
 2097                                })?
 2098                                .await;
 2099                            let Ok(resolved_edits) = edits_result else {
 2100                                zlog::warn!(
 2101                                    logger =>
 2102                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2103                                    buffer_path_abs.as_path(),
 2104                                    describe_code_action(&action),
 2105                                );
 2106                                continue 'actions;
 2107                            };
 2108                            edits.extend(resolved_edits);
 2109                        }
 2110
 2111                        if edits.is_empty() {
 2112                            zlog::warn!(logger => "No edits resolved from LSP");
 2113                            continue;
 2114                        }
 2115
 2116                        extend_formatting_transaction(
 2117                            buffer,
 2118                            formatting_transaction_id,
 2119                            cx,
 2120                            |buffer, cx| {
 2121                                zlog::info!(
 2122                                    "Applying edits {edits:?}. Content: {:?}",
 2123                                    buffer.text()
 2124                                );
 2125                                buffer.edit(edits, None, cx);
 2126                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2127                            },
 2128                        )?;
 2129                    }
 2130
 2131                    let Some(command) = action.lsp_action.command() else {
 2132                        continue;
 2133                    };
 2134
 2135                    zlog::warn!(
 2136                        logger =>
 2137                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2138                        &command.command,
 2139                    );
 2140
 2141                    let server_capabilities = server.capabilities();
 2142                    let available_commands = server_capabilities
 2143                        .execute_command_provider
 2144                        .as_ref()
 2145                        .map(|options| options.commands.as_slice())
 2146                        .unwrap_or_default();
 2147                    if !available_commands.contains(&command.command) {
 2148                        zlog::warn!(
 2149                            logger =>
 2150                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2151                            command.command,
 2152                            server.name(),
 2153                        );
 2154                        continue;
 2155                    }
 2156
 2157                    extend_formatting_transaction(
 2158                        buffer,
 2159                        formatting_transaction_id,
 2160                        cx,
 2161                        |_, _| {},
 2162                    )?;
 2163                    zlog::info!(logger => "Executing command {}", &command.command);
 2164
 2165                    lsp_store.update(cx, |this, _| {
 2166                        this.as_local_mut()
 2167                            .unwrap()
 2168                            .last_workspace_edits_by_language_server
 2169                            .remove(&server.server_id());
 2170                    })?;
 2171
 2172                    let execute_command_result = server
 2173                        .request::<lsp::request::ExecuteCommand>(
 2174                            lsp::ExecuteCommandParams {
 2175                                command: command.command.clone(),
 2176                                arguments: command.arguments.clone().unwrap_or_default(),
 2177                                ..Default::default()
 2178                            },
 2179                            request_timeout,
 2180                        )
 2181                        .await
 2182                        .into_response();
 2183
 2184                    if execute_command_result.is_err() {
 2185                        zlog::error!(
 2186                            logger =>
 2187                            "Failed to execute command '{}' as part of {}",
 2188                            &command.command,
 2189                            describe_code_action(&action),
 2190                        );
 2191                        continue 'actions;
 2192                    }
 2193
 2194                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2195                        this.as_local_mut()
 2196                            .unwrap()
 2197                            .last_workspace_edits_by_language_server
 2198                            .remove(&server.server_id())
 2199                            .unwrap_or_default()
 2200                    })?;
 2201
 2202                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2203                    {
 2204                        zlog::trace!(
 2205                            logger =>
 2206                            "Successfully captured {} edits that resulted from command {}",
 2207                            transaction.edit_ids.len(),
 2208                            &command.command,
 2209                        );
 2210                        let transaction_id_project_transaction = transaction.id;
 2211                        buffer.handle.update(cx, |buffer, _| {
 2212                            // it may have been removed from history if push_to_history was
 2213                            // false in deserialize_workspace_edit. If so push it so we
 2214                            // can merge it with the format transaction
 2215                            // and pop the combined transaction off the history stack
 2216                            // later if push_to_history is false
 2217                            if buffer.get_transaction(transaction.id).is_none() {
 2218                                buffer.push_transaction(transaction, Instant::now());
 2219                            }
 2220                            buffer.merge_transactions(
 2221                                transaction_id_project_transaction,
 2222                                formatting_transaction_id,
 2223                            );
 2224                        });
 2225                    }
 2226
 2227                    if project_transaction_command.0.is_empty() {
 2228                        continue;
 2229                    }
 2230
 2231                    let mut extra_buffers = String::new();
 2232                    for buffer in project_transaction_command.0.keys() {
 2233                        buffer.read_with(cx, |b, cx| {
 2234                            let Some(path) = b.project_path(cx) else {
 2235                                return;
 2236                            };
 2237
 2238                            if !extra_buffers.is_empty() {
 2239                                extra_buffers.push_str(", ");
 2240                            }
 2241                            extra_buffers.push_str(path.path.as_unix_str());
 2242                        });
 2243                    }
 2244                    zlog::warn!(
 2245                        logger =>
 2246                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2247                        &command.command,
 2248                        extra_buffers,
 2249                    );
 2250                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2251                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2252                    // add it so it's included, and merge it into the format transaction when its created later
 2253                }
 2254            }
 2255        }
 2256
 2257        Ok(())
 2258    }
 2259
 2260    pub async fn format_ranges_via_lsp(
 2261        this: &WeakEntity<LspStore>,
 2262        buffer_handle: &Entity<Buffer>,
 2263        ranges: &[Range<Anchor>],
 2264        abs_path: &Path,
 2265        language_server: &Arc<LanguageServer>,
 2266        settings: &LanguageSettings,
 2267        cx: &mut AsyncApp,
 2268    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2269        let capabilities = &language_server.capabilities();
 2270        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2271        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2272            anyhow::bail!(
 2273                "{} language server does not support range formatting",
 2274                language_server.name()
 2275            );
 2276        }
 2277
 2278        let uri = file_path_to_lsp_url(abs_path)?;
 2279        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2280
 2281        let request_timeout = cx.update(|app| {
 2282            ProjectSettings::get_global(app)
 2283                .global_lsp_settings
 2284                .get_request_timeout()
 2285        });
 2286        let lsp_edits = {
 2287            let mut lsp_ranges = Vec::new();
 2288            this.update(cx, |_this, cx| {
 2289                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2290                // not have been sent to the language server. This seems like a fairly systemic
 2291                // issue, though, the resolution probably is not specific to formatting.
 2292                //
 2293                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2294                // LSP.
 2295                let snapshot = buffer_handle.read(cx).snapshot();
 2296                for range in ranges {
 2297                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2298                }
 2299                anyhow::Ok(())
 2300            })??;
 2301
 2302            let mut edits = None;
 2303            for range in lsp_ranges {
 2304                if let Some(mut edit) = language_server
 2305                    .request::<lsp::request::RangeFormatting>(
 2306                        lsp::DocumentRangeFormattingParams {
 2307                            text_document: text_document.clone(),
 2308                            range,
 2309                            options: lsp_command::lsp_formatting_options(settings),
 2310                            work_done_progress_params: Default::default(),
 2311                        },
 2312                        request_timeout,
 2313                    )
 2314                    .await
 2315                    .into_response()?
 2316                {
 2317                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2318                }
 2319            }
 2320            edits
 2321        };
 2322
 2323        if let Some(lsp_edits) = lsp_edits {
 2324            this.update(cx, |this, cx| {
 2325                this.as_local_mut().unwrap().edits_from_lsp(
 2326                    buffer_handle,
 2327                    lsp_edits,
 2328                    language_server.server_id(),
 2329                    None,
 2330                    cx,
 2331                )
 2332            })?
 2333            .await
 2334        } else {
 2335            Ok(Vec::with_capacity(0))
 2336        }
 2337    }
 2338
 2339    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2340        let capabilities = server.capabilities();
 2341        let formatting = capabilities.document_formatting_provider.as_ref();
 2342        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2343        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2344            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2345    }
 2346
 2347    async fn format_via_lsp(
 2348        this: &WeakEntity<LspStore>,
 2349        buffer: &Entity<Buffer>,
 2350        abs_path: &Path,
 2351        language_server: &Arc<LanguageServer>,
 2352        settings: &LanguageSettings,
 2353        cx: &mut AsyncApp,
 2354    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2355        let logger = zlog::scoped!("lsp_format");
 2356        zlog::debug!(logger => "Formatting via LSP");
 2357
 2358        let uri = file_path_to_lsp_url(abs_path)?;
 2359        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2360        let capabilities = &language_server.capabilities();
 2361
 2362        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2363        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2364
 2365        let request_timeout = cx.update(|app| {
 2366            ProjectSettings::get_global(app)
 2367                .global_lsp_settings
 2368                .get_request_timeout()
 2369        });
 2370
 2371        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2372            let _timer = zlog::time!(logger => "format-full");
 2373            language_server
 2374                .request::<lsp::request::Formatting>(
 2375                    lsp::DocumentFormattingParams {
 2376                        text_document,
 2377                        options: lsp_command::lsp_formatting_options(settings),
 2378                        work_done_progress_params: Default::default(),
 2379                    },
 2380                    request_timeout,
 2381                )
 2382                .await
 2383                .into_response()?
 2384        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2385            let _timer = zlog::time!(logger => "format-range");
 2386            let buffer_start = lsp::Position::new(0, 0);
 2387            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2388            language_server
 2389                .request::<lsp::request::RangeFormatting>(
 2390                    lsp::DocumentRangeFormattingParams {
 2391                        text_document: text_document.clone(),
 2392                        range: lsp::Range::new(buffer_start, buffer_end),
 2393                        options: lsp_command::lsp_formatting_options(settings),
 2394                        work_done_progress_params: Default::default(),
 2395                    },
 2396                    request_timeout,
 2397                )
 2398                .await
 2399                .into_response()?
 2400        } else {
 2401            None
 2402        };
 2403
 2404        if let Some(lsp_edits) = lsp_edits {
 2405            this.update(cx, |this, cx| {
 2406                this.as_local_mut().unwrap().edits_from_lsp(
 2407                    buffer,
 2408                    lsp_edits,
 2409                    language_server.server_id(),
 2410                    None,
 2411                    cx,
 2412                )
 2413            })?
 2414            .await
 2415        } else {
 2416            Ok(Vec::with_capacity(0))
 2417        }
 2418    }
 2419
 2420    async fn format_via_external_command(
 2421        buffer: &FormattableBuffer,
 2422        command: &str,
 2423        arguments: Option<&[String]>,
 2424        cx: &mut AsyncApp,
 2425    ) -> Result<Option<Diff>> {
 2426        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2427            let file = File::from_dyn(buffer.file())?;
 2428            let worktree = file.worktree.read(cx);
 2429            let mut worktree_path = worktree.abs_path().to_path_buf();
 2430            if worktree.root_entry()?.is_file() {
 2431                worktree_path.pop();
 2432            }
 2433            Some(worktree_path)
 2434        });
 2435
 2436        use util::command::Stdio;
 2437        let mut child = util::command::new_command(command);
 2438
 2439        if let Some(buffer_env) = buffer.env.as_ref() {
 2440            child.envs(buffer_env);
 2441        }
 2442
 2443        if let Some(working_dir_path) = working_dir_path {
 2444            child.current_dir(working_dir_path);
 2445        }
 2446
 2447        if let Some(arguments) = arguments {
 2448            child.args(arguments.iter().map(|arg| {
 2449                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2450                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2451                } else {
 2452                    arg.replace("{buffer_path}", "Untitled")
 2453                }
 2454            }));
 2455        }
 2456
 2457        let mut child = child
 2458            .stdin(Stdio::piped())
 2459            .stdout(Stdio::piped())
 2460            .stderr(Stdio::piped())
 2461            .spawn()?;
 2462
 2463        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2464        let text = buffer
 2465            .handle
 2466            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2467        for chunk in text.chunks() {
 2468            stdin.write_all(chunk.as_bytes()).await?;
 2469        }
 2470        stdin.flush().await?;
 2471
 2472        let output = child.output().await?;
 2473        anyhow::ensure!(
 2474            output.status.success(),
 2475            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2476            output.status.code(),
 2477            String::from_utf8_lossy(&output.stdout),
 2478            String::from_utf8_lossy(&output.stderr),
 2479        );
 2480
 2481        let stdout = String::from_utf8(output.stdout)?;
 2482        Ok(Some(
 2483            buffer
 2484                .handle
 2485                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2486                .await,
 2487        ))
 2488    }
 2489
 2490    async fn try_resolve_code_action(
 2491        lang_server: &LanguageServer,
 2492        action: &mut CodeAction,
 2493        request_timeout: Duration,
 2494    ) -> anyhow::Result<()> {
 2495        match &mut action.lsp_action {
 2496            LspAction::Action(lsp_action) => {
 2497                if !action.resolved
 2498                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2499                    && lsp_action.data.is_some()
 2500                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2501                {
 2502                    **lsp_action = lang_server
 2503                        .request::<lsp::request::CodeActionResolveRequest>(
 2504                            *lsp_action.clone(),
 2505                            request_timeout,
 2506                        )
 2507                        .await
 2508                        .into_response()?;
 2509                }
 2510            }
 2511            LspAction::CodeLens(lens) => {
 2512                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2513                    *lens = lang_server
 2514                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2515                        .await
 2516                        .into_response()?;
 2517                }
 2518            }
 2519            LspAction::Command(_) => {}
 2520        }
 2521
 2522        action.resolved = true;
 2523        anyhow::Ok(())
 2524    }
 2525
 2526    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2527        let buffer = buffer_handle.read(cx);
 2528
 2529        let file = buffer.file().cloned();
 2530
 2531        let Some(file) = File::from_dyn(file.as_ref()) else {
 2532            return;
 2533        };
 2534        if !file.is_local() {
 2535            return;
 2536        }
 2537        let path = ProjectPath::from_file(file, cx);
 2538        let worktree_id = file.worktree_id(cx);
 2539        let language = buffer.language().cloned();
 2540
 2541        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2542            for (server_id, diagnostics) in
 2543                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2544            {
 2545                self.update_buffer_diagnostics(
 2546                    buffer_handle,
 2547                    server_id,
 2548                    None,
 2549                    None,
 2550                    None,
 2551                    Vec::new(),
 2552                    diagnostics,
 2553                    cx,
 2554                )
 2555                .log_err();
 2556            }
 2557        }
 2558        let Some(language) = language else {
 2559            return;
 2560        };
 2561        let Some(snapshot) = self
 2562            .worktree_store
 2563            .read(cx)
 2564            .worktree_for_id(worktree_id, cx)
 2565            .map(|worktree| worktree.read(cx).snapshot())
 2566        else {
 2567            return;
 2568        };
 2569        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2570
 2571        for server_id in
 2572            self.lsp_tree
 2573                .get(path, language.name(), language.manifest(), &delegate, cx)
 2574        {
 2575            let server = self
 2576                .language_servers
 2577                .get(&server_id)
 2578                .and_then(|server_state| {
 2579                    if let LanguageServerState::Running { server, .. } = server_state {
 2580                        Some(server.clone())
 2581                    } else {
 2582                        None
 2583                    }
 2584                });
 2585            let server = match server {
 2586                Some(server) => server,
 2587                None => continue,
 2588            };
 2589
 2590            buffer_handle.update(cx, |buffer, cx| {
 2591                buffer.set_completion_triggers(
 2592                    server.server_id(),
 2593                    server
 2594                        .capabilities()
 2595                        .completion_provider
 2596                        .as_ref()
 2597                        .and_then(|provider| {
 2598                            provider
 2599                                .trigger_characters
 2600                                .as_ref()
 2601                                .map(|characters| characters.iter().cloned().collect())
 2602                        })
 2603                        .unwrap_or_default(),
 2604                    cx,
 2605                );
 2606            });
 2607        }
 2608    }
 2609
 2610    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2611        buffer.update(cx, |buffer, cx| {
 2612            let Some(language) = buffer.language() else {
 2613                return;
 2614            };
 2615            let path = ProjectPath {
 2616                worktree_id: old_file.worktree_id(cx),
 2617                path: old_file.path.clone(),
 2618            };
 2619            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2620                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2621                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2622            }
 2623        });
 2624    }
 2625
 2626    fn update_buffer_diagnostics(
 2627        &mut self,
 2628        buffer: &Entity<Buffer>,
 2629        server_id: LanguageServerId,
 2630        registration_id: Option<Option<SharedString>>,
 2631        result_id: Option<SharedString>,
 2632        version: Option<i32>,
 2633        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2634        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2635        cx: &mut Context<LspStore>,
 2636    ) -> Result<()> {
 2637        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2638            Ordering::Equal
 2639                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2640                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2641                .then_with(|| a.severity.cmp(&b.severity))
 2642                .then_with(|| a.message.cmp(&b.message))
 2643        }
 2644
 2645        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2646        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2647        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2648
 2649        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2650            Ordering::Equal
 2651                .then_with(|| a.range.start.cmp(&b.range.start))
 2652                .then_with(|| b.range.end.cmp(&a.range.end))
 2653                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2654        });
 2655
 2656        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2657
 2658        let edits_since_save = std::cell::LazyCell::new(|| {
 2659            let saved_version = buffer.read(cx).saved_version();
 2660            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2661        });
 2662
 2663        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2664
 2665        for (new_diagnostic, entry) in diagnostics {
 2666            let start;
 2667            let end;
 2668            if new_diagnostic && entry.diagnostic.is_disk_based {
 2669                // Some diagnostics are based on files on disk instead of buffers'
 2670                // current contents. Adjust these diagnostics' ranges to reflect
 2671                // any unsaved edits.
 2672                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2673                // and were properly adjusted on reuse.
 2674                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2675                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2676            } else {
 2677                start = entry.range.start;
 2678                end = entry.range.end;
 2679            }
 2680
 2681            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2682                ..snapshot.clip_point_utf16(end, Bias::Right);
 2683
 2684            // Expand empty ranges by one codepoint
 2685            if range.start == range.end {
 2686                // This will be go to the next boundary when being clipped
 2687                range.end.column += 1;
 2688                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2689                if range.start == range.end && range.end.column > 0 {
 2690                    range.start.column -= 1;
 2691                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2692                }
 2693            }
 2694
 2695            sanitized_diagnostics.push(DiagnosticEntry {
 2696                range,
 2697                diagnostic: entry.diagnostic,
 2698            });
 2699        }
 2700        drop(edits_since_save);
 2701
 2702        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2703        buffer.update(cx, |buffer, cx| {
 2704            if let Some(registration_id) = registration_id {
 2705                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2706                    self.buffer_pull_diagnostics_result_ids
 2707                        .entry(server_id)
 2708                        .or_default()
 2709                        .entry(registration_id)
 2710                        .or_default()
 2711                        .insert(abs_path, result_id);
 2712                }
 2713            }
 2714
 2715            buffer.update_diagnostics(server_id, set, cx)
 2716        });
 2717
 2718        Ok(())
 2719    }
 2720
 2721    fn register_language_server_for_invisible_worktree(
 2722        &mut self,
 2723        worktree: &Entity<Worktree>,
 2724        language_server_id: LanguageServerId,
 2725        cx: &mut App,
 2726    ) {
 2727        let worktree = worktree.read(cx);
 2728        let worktree_id = worktree.id();
 2729        debug_assert!(!worktree.is_visible());
 2730        let Some(mut origin_seed) = self
 2731            .language_server_ids
 2732            .iter()
 2733            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2734        else {
 2735            return;
 2736        };
 2737        origin_seed.worktree_id = worktree_id;
 2738        self.language_server_ids
 2739            .entry(origin_seed)
 2740            .or_insert_with(|| UnifiedLanguageServer {
 2741                id: language_server_id,
 2742                project_roots: Default::default(),
 2743            });
 2744    }
 2745
 2746    fn register_buffer_with_language_servers(
 2747        &mut self,
 2748        buffer_handle: &Entity<Buffer>,
 2749        only_register_servers: HashSet<LanguageServerSelector>,
 2750        cx: &mut Context<LspStore>,
 2751    ) {
 2752        let buffer = buffer_handle.read(cx);
 2753        let buffer_id = buffer.remote_id();
 2754
 2755        let Some(file) = File::from_dyn(buffer.file()) else {
 2756            return;
 2757        };
 2758        if !file.is_local() {
 2759            return;
 2760        }
 2761
 2762        let abs_path = file.abs_path(cx);
 2763        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2764            return;
 2765        };
 2766        let initial_snapshot = buffer.text_snapshot();
 2767        let worktree_id = file.worktree_id(cx);
 2768
 2769        let Some(language) = buffer.language().cloned() else {
 2770            return;
 2771        };
 2772        let path: Arc<RelPath> = file
 2773            .path()
 2774            .parent()
 2775            .map(Arc::from)
 2776            .unwrap_or_else(|| file.path().clone());
 2777        let Some(worktree) = self
 2778            .worktree_store
 2779            .read(cx)
 2780            .worktree_for_id(worktree_id, cx)
 2781        else {
 2782            return;
 2783        };
 2784        let language_name = language.name();
 2785        let (reused, delegate, servers) = self
 2786            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2787            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2788            .unwrap_or_else(|| {
 2789                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2790                let delegate: Arc<dyn ManifestDelegate> =
 2791                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2792
 2793                let servers = self
 2794                    .lsp_tree
 2795                    .walk(
 2796                        ProjectPath { worktree_id, path },
 2797                        language.name(),
 2798                        language.manifest(),
 2799                        &delegate,
 2800                        cx,
 2801                    )
 2802                    .collect::<Vec<_>>();
 2803                (false, lsp_delegate, servers)
 2804            });
 2805        let servers_and_adapters = servers
 2806            .into_iter()
 2807            .filter_map(|server_node| {
 2808                if reused && server_node.server_id().is_none() {
 2809                    return None;
 2810                }
 2811                if !only_register_servers.is_empty() {
 2812                    if let Some(server_id) = server_node.server_id()
 2813                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2814                    {
 2815                        return None;
 2816                    }
 2817                    if let Some(name) = server_node.name()
 2818                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2819                    {
 2820                        return None;
 2821                    }
 2822                }
 2823
 2824                let server_id = server_node.server_id_or_init(|disposition| {
 2825                    let path = &disposition.path;
 2826
 2827                    {
 2828                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2829
 2830                        let server_id = self.get_or_insert_language_server(
 2831                            &worktree,
 2832                            delegate.clone(),
 2833                            disposition,
 2834                            &language_name,
 2835                            cx,
 2836                        );
 2837
 2838                        if let Some(state) = self.language_servers.get(&server_id)
 2839                            && let Ok(uri) = uri
 2840                        {
 2841                            state.add_workspace_folder(uri);
 2842                        };
 2843                        server_id
 2844                    }
 2845                })?;
 2846                let server_state = self.language_servers.get(&server_id)?;
 2847                if let LanguageServerState::Running {
 2848                    server, adapter, ..
 2849                } = server_state
 2850                {
 2851                    Some((server.clone(), adapter.clone()))
 2852                } else {
 2853                    None
 2854                }
 2855            })
 2856            .collect::<Vec<_>>();
 2857        for (server, adapter) in servers_and_adapters {
 2858            buffer_handle.update(cx, |buffer, cx| {
 2859                buffer.set_completion_triggers(
 2860                    server.server_id(),
 2861                    server
 2862                        .capabilities()
 2863                        .completion_provider
 2864                        .as_ref()
 2865                        .and_then(|provider| {
 2866                            provider
 2867                                .trigger_characters
 2868                                .as_ref()
 2869                                .map(|characters| characters.iter().cloned().collect())
 2870                        })
 2871                        .unwrap_or_default(),
 2872                    cx,
 2873                );
 2874            });
 2875
 2876            let snapshot = LspBufferSnapshot {
 2877                version: 0,
 2878                snapshot: initial_snapshot.clone(),
 2879            };
 2880
 2881            let mut registered = false;
 2882            self.buffer_snapshots
 2883                .entry(buffer_id)
 2884                .or_default()
 2885                .entry(server.server_id())
 2886                .or_insert_with(|| {
 2887                    registered = true;
 2888                    server.register_buffer(
 2889                        uri.clone(),
 2890                        adapter.language_id(&language.name()),
 2891                        0,
 2892                        initial_snapshot.text(),
 2893                    );
 2894
 2895                    vec![snapshot]
 2896                });
 2897
 2898            self.buffers_opened_in_servers
 2899                .entry(buffer_id)
 2900                .or_default()
 2901                .insert(server.server_id());
 2902            if registered {
 2903                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2904                    language_server_id: server.server_id(),
 2905                    name: None,
 2906                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2907                        proto::RegisteredForBuffer {
 2908                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2909                            buffer_id: buffer_id.to_proto(),
 2910                        },
 2911                    ),
 2912                });
 2913            }
 2914        }
 2915    }
 2916
 2917    fn reuse_existing_language_server<'lang_name>(
 2918        &self,
 2919        server_tree: &LanguageServerTree,
 2920        worktree: &Entity<Worktree>,
 2921        language_name: &'lang_name LanguageName,
 2922        cx: &mut App,
 2923    ) -> Option<(
 2924        Arc<LocalLspAdapterDelegate>,
 2925        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2926    )> {
 2927        if worktree.read(cx).is_visible() {
 2928            return None;
 2929        }
 2930
 2931        let worktree_store = self.worktree_store.read(cx);
 2932        let servers = server_tree
 2933            .instances
 2934            .iter()
 2935            .filter(|(worktree_id, _)| {
 2936                worktree_store
 2937                    .worktree_for_id(**worktree_id, cx)
 2938                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2939            })
 2940            .flat_map(|(worktree_id, servers)| {
 2941                servers
 2942                    .roots
 2943                    .iter()
 2944                    .flat_map(|(_, language_servers)| language_servers)
 2945                    .map(move |(_, (server_node, server_languages))| {
 2946                        (worktree_id, server_node, server_languages)
 2947                    })
 2948                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2949                    .map(|(worktree_id, server_node, _)| {
 2950                        (
 2951                            *worktree_id,
 2952                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2953                        )
 2954                    })
 2955            })
 2956            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2957                acc.entry(worktree_id)
 2958                    .or_insert_with(Vec::new)
 2959                    .push(server_node);
 2960                acc
 2961            })
 2962            .into_values()
 2963            .max_by_key(|servers| servers.len())?;
 2964
 2965        let worktree_id = worktree.read(cx).id();
 2966        let apply = move |tree: &mut LanguageServerTree| {
 2967            for server_node in &servers {
 2968                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2969            }
 2970            servers
 2971        };
 2972
 2973        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2974        Some((delegate, apply))
 2975    }
 2976
 2977    pub(crate) fn unregister_old_buffer_from_language_servers(
 2978        &mut self,
 2979        buffer: &Entity<Buffer>,
 2980        old_file: &File,
 2981        cx: &mut App,
 2982    ) {
 2983        let old_path = match old_file.as_local() {
 2984            Some(local) => local.abs_path(cx),
 2985            None => return,
 2986        };
 2987
 2988        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2989            debug_panic!("{old_path:?} is not parseable as an URI");
 2990            return;
 2991        };
 2992        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2993    }
 2994
 2995    pub(crate) fn unregister_buffer_from_language_servers(
 2996        &mut self,
 2997        buffer: &Entity<Buffer>,
 2998        file_url: &lsp::Uri,
 2999        cx: &mut App,
 3000    ) {
 3001        buffer.update(cx, |buffer, cx| {
 3002            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3003
 3004            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3005                if snapshots
 3006                    .as_mut()
 3007                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3008                {
 3009                    language_server.unregister_buffer(file_url.clone());
 3010                }
 3011            }
 3012        });
 3013    }
 3014
 3015    fn buffer_snapshot_for_lsp_version(
 3016        &mut self,
 3017        buffer: &Entity<Buffer>,
 3018        server_id: LanguageServerId,
 3019        version: Option<i32>,
 3020        cx: &App,
 3021    ) -> Result<TextBufferSnapshot> {
 3022        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3023
 3024        if let Some(version) = version {
 3025            let buffer_id = buffer.read(cx).remote_id();
 3026            let snapshots = if let Some(snapshots) = self
 3027                .buffer_snapshots
 3028                .get_mut(&buffer_id)
 3029                .and_then(|m| m.get_mut(&server_id))
 3030            {
 3031                snapshots
 3032            } else if version == 0 {
 3033                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3034                // We detect this case and treat it as if the version was `None`.
 3035                return Ok(buffer.read(cx).text_snapshot());
 3036            } else {
 3037                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3038            };
 3039
 3040            let found_snapshot = snapshots
 3041                    .binary_search_by_key(&version, |e| e.version)
 3042                    .map(|ix| snapshots[ix].snapshot.clone())
 3043                    .map_err(|_| {
 3044                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3045                    })?;
 3046
 3047            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3048            Ok(found_snapshot)
 3049        } else {
 3050            Ok((buffer.read(cx)).text_snapshot())
 3051        }
 3052    }
 3053
 3054    async fn get_server_code_actions_from_action_kinds(
 3055        lsp_store: &WeakEntity<LspStore>,
 3056        language_server_id: LanguageServerId,
 3057        code_action_kinds: Vec<lsp::CodeActionKind>,
 3058        buffer: &Entity<Buffer>,
 3059        cx: &mut AsyncApp,
 3060    ) -> Result<Vec<CodeAction>> {
 3061        let actions = lsp_store
 3062            .update(cx, move |this, cx| {
 3063                let request = GetCodeActions {
 3064                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3065                    kinds: Some(code_action_kinds),
 3066                };
 3067                let server = LanguageServerToQuery::Other(language_server_id);
 3068                this.request_lsp(buffer.clone(), server, request, cx)
 3069            })?
 3070            .await?;
 3071        Ok(actions)
 3072    }
 3073
 3074    pub async fn execute_code_actions_on_server(
 3075        lsp_store: &WeakEntity<LspStore>,
 3076        language_server: &Arc<LanguageServer>,
 3077        actions: Vec<CodeAction>,
 3078        push_to_history: bool,
 3079        project_transaction: &mut ProjectTransaction,
 3080        cx: &mut AsyncApp,
 3081    ) -> anyhow::Result<()> {
 3082        let request_timeout = cx.update(|app| {
 3083            ProjectSettings::get_global(app)
 3084                .global_lsp_settings
 3085                .get_request_timeout()
 3086        });
 3087
 3088        for mut action in actions {
 3089            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3090                .await
 3091                .context("resolving a formatting code action")?;
 3092
 3093            if let Some(edit) = action.lsp_action.edit() {
 3094                if edit.changes.is_none() && edit.document_changes.is_none() {
 3095                    continue;
 3096                }
 3097
 3098                let new = Self::deserialize_workspace_edit(
 3099                    lsp_store.upgrade().context("project dropped")?,
 3100                    edit.clone(),
 3101                    push_to_history,
 3102                    language_server.clone(),
 3103                    cx,
 3104                )
 3105                .await?;
 3106                project_transaction.0.extend(new.0);
 3107            }
 3108
 3109            let Some(command) = action.lsp_action.command() else {
 3110                continue;
 3111            };
 3112
 3113            let server_capabilities = language_server.capabilities();
 3114            let available_commands = server_capabilities
 3115                .execute_command_provider
 3116                .as_ref()
 3117                .map(|options| options.commands.as_slice())
 3118                .unwrap_or_default();
 3119            if !available_commands.contains(&command.command) {
 3120                log::warn!(
 3121                    "Cannot execute a command {} not listed in the language server capabilities",
 3122                    command.command
 3123                );
 3124                continue;
 3125            }
 3126
 3127            lsp_store.update(cx, |lsp_store, _| {
 3128                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3129                    mode.last_workspace_edits_by_language_server
 3130                        .remove(&language_server.server_id());
 3131                }
 3132            })?;
 3133
 3134            language_server
 3135                .request::<lsp::request::ExecuteCommand>(
 3136                    lsp::ExecuteCommandParams {
 3137                        command: command.command.clone(),
 3138                        arguments: command.arguments.clone().unwrap_or_default(),
 3139                        ..Default::default()
 3140                    },
 3141                    request_timeout,
 3142                )
 3143                .await
 3144                .into_response()
 3145                .context("execute command")?;
 3146
 3147            lsp_store.update(cx, |this, _| {
 3148                if let LspStoreMode::Local(mode) = &mut this.mode {
 3149                    project_transaction.0.extend(
 3150                        mode.last_workspace_edits_by_language_server
 3151                            .remove(&language_server.server_id())
 3152                            .unwrap_or_default()
 3153                            .0,
 3154                    )
 3155                }
 3156            })?;
 3157        }
 3158        Ok(())
 3159    }
 3160
 3161    pub async fn deserialize_text_edits(
 3162        this: Entity<LspStore>,
 3163        buffer_to_edit: Entity<Buffer>,
 3164        edits: Vec<lsp::TextEdit>,
 3165        push_to_history: bool,
 3166        _: Arc<CachedLspAdapter>,
 3167        language_server: Arc<LanguageServer>,
 3168        cx: &mut AsyncApp,
 3169    ) -> Result<Option<Transaction>> {
 3170        let edits = this
 3171            .update(cx, |this, cx| {
 3172                this.as_local_mut().unwrap().edits_from_lsp(
 3173                    &buffer_to_edit,
 3174                    edits,
 3175                    language_server.server_id(),
 3176                    None,
 3177                    cx,
 3178                )
 3179            })
 3180            .await?;
 3181
 3182        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3183            buffer.finalize_last_transaction();
 3184            buffer.start_transaction();
 3185            for (range, text) in edits {
 3186                buffer.edit([(range, text)], None, cx);
 3187            }
 3188
 3189            if buffer.end_transaction(cx).is_some() {
 3190                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3191                if !push_to_history {
 3192                    buffer.forget_transaction(transaction.id);
 3193                }
 3194                Some(transaction)
 3195            } else {
 3196                None
 3197            }
 3198        });
 3199
 3200        Ok(transaction)
 3201    }
 3202
 3203    #[allow(clippy::type_complexity)]
 3204    pub fn edits_from_lsp(
 3205        &mut self,
 3206        buffer: &Entity<Buffer>,
 3207        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3208        server_id: LanguageServerId,
 3209        version: Option<i32>,
 3210        cx: &mut Context<LspStore>,
 3211    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3212        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3213        cx.background_spawn(async move {
 3214            let snapshot = snapshot?;
 3215            let mut lsp_edits = lsp_edits
 3216                .into_iter()
 3217                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3218                .collect::<Vec<_>>();
 3219
 3220            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3221
 3222            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3223            let mut edits = Vec::new();
 3224            while let Some((range, mut new_text)) = lsp_edits.next() {
 3225                // Clip invalid ranges provided by the language server.
 3226                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3227                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3228
 3229                // Combine any LSP edits that are adjacent.
 3230                //
 3231                // Also, combine LSP edits that are separated from each other by only
 3232                // a newline. This is important because for some code actions,
 3233                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3234                // are separated by unchanged newline characters.
 3235                //
 3236                // In order for the diffing logic below to work properly, any edits that
 3237                // cancel each other out must be combined into one.
 3238                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3239                    if next_range.start.0 > range.end {
 3240                        if next_range.start.0.row > range.end.row + 1
 3241                            || next_range.start.0.column > 0
 3242                            || snapshot.clip_point_utf16(
 3243                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3244                                Bias::Left,
 3245                            ) > range.end
 3246                        {
 3247                            break;
 3248                        }
 3249                        new_text.push('\n');
 3250                    }
 3251                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3252                    new_text.push_str(next_text);
 3253                    lsp_edits.next();
 3254                }
 3255
 3256                // For multiline edits, perform a diff of the old and new text so that
 3257                // we can identify the changes more precisely, preserving the locations
 3258                // of any anchors positioned in the unchanged regions.
 3259                if range.end.row > range.start.row {
 3260                    let offset = range.start.to_offset(&snapshot);
 3261                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3262                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3263                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3264                        (
 3265                            snapshot.anchor_after(offset + range.start)
 3266                                ..snapshot.anchor_before(offset + range.end),
 3267                            replacement,
 3268                        )
 3269                    }));
 3270                } else if range.end == range.start {
 3271                    let anchor = snapshot.anchor_after(range.start);
 3272                    edits.push((anchor..anchor, new_text.into()));
 3273                } else {
 3274                    let edit_start = snapshot.anchor_after(range.start);
 3275                    let edit_end = snapshot.anchor_before(range.end);
 3276                    edits.push((edit_start..edit_end, new_text.into()));
 3277                }
 3278            }
 3279
 3280            Ok(edits)
 3281        })
 3282    }
 3283
 3284    pub(crate) async fn deserialize_workspace_edit(
 3285        this: Entity<LspStore>,
 3286        edit: lsp::WorkspaceEdit,
 3287        push_to_history: bool,
 3288        language_server: Arc<LanguageServer>,
 3289        cx: &mut AsyncApp,
 3290    ) -> Result<ProjectTransaction> {
 3291        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3292
 3293        let mut operations = Vec::new();
 3294        if let Some(document_changes) = edit.document_changes {
 3295            match document_changes {
 3296                lsp::DocumentChanges::Edits(edits) => {
 3297                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3298                }
 3299                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3300            }
 3301        } else if let Some(changes) = edit.changes {
 3302            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3303                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3304                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3305                        uri,
 3306                        version: None,
 3307                    },
 3308                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3309                })
 3310            }));
 3311        }
 3312
 3313        let mut project_transaction = ProjectTransaction::default();
 3314        for operation in operations {
 3315            match operation {
 3316                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3317                    let abs_path = op
 3318                        .uri
 3319                        .to_file_path()
 3320                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3321
 3322                    if let Some(parent_path) = abs_path.parent() {
 3323                        fs.create_dir(parent_path).await?;
 3324                    }
 3325                    if abs_path.ends_with("/") {
 3326                        fs.create_dir(&abs_path).await?;
 3327                    } else {
 3328                        fs.create_file(
 3329                            &abs_path,
 3330                            op.options
 3331                                .map(|options| fs::CreateOptions {
 3332                                    overwrite: options.overwrite.unwrap_or(false),
 3333                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3334                                })
 3335                                .unwrap_or_default(),
 3336                        )
 3337                        .await?;
 3338                    }
 3339                }
 3340
 3341                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3342                    let source_abs_path = op
 3343                        .old_uri
 3344                        .to_file_path()
 3345                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3346                    let target_abs_path = op
 3347                        .new_uri
 3348                        .to_file_path()
 3349                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3350
 3351                    let options = fs::RenameOptions {
 3352                        overwrite: op
 3353                            .options
 3354                            .as_ref()
 3355                            .and_then(|options| options.overwrite)
 3356                            .unwrap_or(false),
 3357                        ignore_if_exists: op
 3358                            .options
 3359                            .as_ref()
 3360                            .and_then(|options| options.ignore_if_exists)
 3361                            .unwrap_or(false),
 3362                        create_parents: true,
 3363                    };
 3364
 3365                    fs.rename(&source_abs_path, &target_abs_path, options)
 3366                        .await?;
 3367                }
 3368
 3369                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3370                    let abs_path = op
 3371                        .uri
 3372                        .to_file_path()
 3373                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3374                    let options = op
 3375                        .options
 3376                        .map(|options| fs::RemoveOptions {
 3377                            recursive: options.recursive.unwrap_or(false),
 3378                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3379                        })
 3380                        .unwrap_or_default();
 3381                    if abs_path.ends_with("/") {
 3382                        fs.remove_dir(&abs_path, options).await?;
 3383                    } else {
 3384                        fs.remove_file(&abs_path, options).await?;
 3385                    }
 3386                }
 3387
 3388                lsp::DocumentChangeOperation::Edit(op) => {
 3389                    let buffer_to_edit = this
 3390                        .update(cx, |this, cx| {
 3391                            this.open_local_buffer_via_lsp(
 3392                                op.text_document.uri.clone(),
 3393                                language_server.server_id(),
 3394                                cx,
 3395                            )
 3396                        })
 3397                        .await?;
 3398
 3399                    let edits = this
 3400                        .update(cx, |this, cx| {
 3401                            let path = buffer_to_edit.read(cx).project_path(cx);
 3402                            let active_entry = this.active_entry;
 3403                            let is_active_entry = path.is_some_and(|project_path| {
 3404                                this.worktree_store
 3405                                    .read(cx)
 3406                                    .entry_for_path(&project_path, cx)
 3407                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3408                            });
 3409                            let local = this.as_local_mut().unwrap();
 3410
 3411                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3412                            for edit in op.edits {
 3413                                match edit {
 3414                                    Edit::Plain(edit) => {
 3415                                        if !edits.contains(&edit) {
 3416                                            edits.push(edit)
 3417                                        }
 3418                                    }
 3419                                    Edit::Annotated(edit) => {
 3420                                        if !edits.contains(&edit.text_edit) {
 3421                                            edits.push(edit.text_edit)
 3422                                        }
 3423                                    }
 3424                                    Edit::Snippet(edit) => {
 3425                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3426                                        else {
 3427                                            continue;
 3428                                        };
 3429
 3430                                        if is_active_entry {
 3431                                            snippet_edits.push((edit.range, snippet));
 3432                                        } else {
 3433                                            // Since this buffer is not focused, apply a normal edit.
 3434                                            let new_edit = TextEdit {
 3435                                                range: edit.range,
 3436                                                new_text: snippet.text,
 3437                                            };
 3438                                            if !edits.contains(&new_edit) {
 3439                                                edits.push(new_edit);
 3440                                            }
 3441                                        }
 3442                                    }
 3443                                }
 3444                            }
 3445                            if !snippet_edits.is_empty() {
 3446                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3447                                let version = if let Some(buffer_version) = op.text_document.version
 3448                                {
 3449                                    local
 3450                                        .buffer_snapshot_for_lsp_version(
 3451                                            &buffer_to_edit,
 3452                                            language_server.server_id(),
 3453                                            Some(buffer_version),
 3454                                            cx,
 3455                                        )
 3456                                        .ok()
 3457                                        .map(|snapshot| snapshot.version)
 3458                                } else {
 3459                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3460                                };
 3461
 3462                                let most_recent_edit =
 3463                                    version.and_then(|version| version.most_recent());
 3464                                // Check if the edit that triggered that edit has been made by this participant.
 3465
 3466                                if let Some(most_recent_edit) = most_recent_edit {
 3467                                    cx.emit(LspStoreEvent::SnippetEdit {
 3468                                        buffer_id,
 3469                                        edits: snippet_edits,
 3470                                        most_recent_edit,
 3471                                    });
 3472                                }
 3473                            }
 3474
 3475                            local.edits_from_lsp(
 3476                                &buffer_to_edit,
 3477                                edits,
 3478                                language_server.server_id(),
 3479                                op.text_document.version,
 3480                                cx,
 3481                            )
 3482                        })
 3483                        .await?;
 3484
 3485                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3486                        buffer.finalize_last_transaction();
 3487                        buffer.start_transaction();
 3488                        for (range, text) in edits {
 3489                            buffer.edit([(range, text)], None, cx);
 3490                        }
 3491
 3492                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3493                            if push_to_history {
 3494                                buffer.finalize_last_transaction();
 3495                                buffer.get_transaction(transaction_id).cloned()
 3496                            } else {
 3497                                buffer.forget_transaction(transaction_id)
 3498                            }
 3499                        })
 3500                    });
 3501                    if let Some(transaction) = transaction {
 3502                        project_transaction.0.insert(buffer_to_edit, transaction);
 3503                    }
 3504                }
 3505            }
 3506        }
 3507
 3508        Ok(project_transaction)
 3509    }
 3510
 3511    async fn on_lsp_workspace_edit(
 3512        this: WeakEntity<LspStore>,
 3513        params: lsp::ApplyWorkspaceEditParams,
 3514        server_id: LanguageServerId,
 3515        cx: &mut AsyncApp,
 3516    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3517        let this = this.upgrade().context("project project closed")?;
 3518        let language_server = this
 3519            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3520            .context("language server not found")?;
 3521        let transaction = Self::deserialize_workspace_edit(
 3522            this.clone(),
 3523            params.edit,
 3524            true,
 3525            language_server.clone(),
 3526            cx,
 3527        )
 3528        .await
 3529        .log_err();
 3530        this.update(cx, |this, cx| {
 3531            if let Some(transaction) = transaction {
 3532                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3533
 3534                this.as_local_mut()
 3535                    .unwrap()
 3536                    .last_workspace_edits_by_language_server
 3537                    .insert(server_id, transaction);
 3538            }
 3539        });
 3540        Ok(lsp::ApplyWorkspaceEditResponse {
 3541            applied: true,
 3542            failed_change: None,
 3543            failure_reason: None,
 3544        })
 3545    }
 3546
 3547    fn remove_worktree(
 3548        &mut self,
 3549        id_to_remove: WorktreeId,
 3550        cx: &mut Context<LspStore>,
 3551    ) -> Vec<LanguageServerId> {
 3552        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3553        self.diagnostics.remove(&id_to_remove);
 3554        self.prettier_store.update(cx, |prettier_store, cx| {
 3555            prettier_store.remove_worktree(id_to_remove, cx);
 3556        });
 3557
 3558        let mut servers_to_remove = BTreeSet::default();
 3559        let mut servers_to_preserve = HashSet::default();
 3560        for (seed, state) in &self.language_server_ids {
 3561            if seed.worktree_id == id_to_remove {
 3562                servers_to_remove.insert(state.id);
 3563            } else {
 3564                servers_to_preserve.insert(state.id);
 3565            }
 3566        }
 3567        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3568        self.language_server_ids
 3569            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3570        for server_id_to_remove in &servers_to_remove {
 3571            self.language_server_watched_paths
 3572                .remove(server_id_to_remove);
 3573            self.language_server_paths_watched_for_rename
 3574                .remove(server_id_to_remove);
 3575            self.last_workspace_edits_by_language_server
 3576                .remove(server_id_to_remove);
 3577            self.language_servers.remove(server_id_to_remove);
 3578            self.buffer_pull_diagnostics_result_ids
 3579                .remove(server_id_to_remove);
 3580            self.workspace_pull_diagnostics_result_ids
 3581                .remove(server_id_to_remove);
 3582            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3583                buffer_servers.remove(server_id_to_remove);
 3584            }
 3585            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3586        }
 3587        servers_to_remove.into_iter().collect()
 3588    }
 3589
 3590    fn rebuild_watched_paths_inner<'a>(
 3591        &'a self,
 3592        language_server_id: LanguageServerId,
 3593        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3594        cx: &mut Context<LspStore>,
 3595    ) -> LanguageServerWatchedPathsBuilder {
 3596        let worktrees = self
 3597            .worktree_store
 3598            .read(cx)
 3599            .worktrees()
 3600            .filter_map(|worktree| {
 3601                self.language_servers_for_worktree(worktree.read(cx).id())
 3602                    .find(|server| server.server_id() == language_server_id)
 3603                    .map(|_| worktree)
 3604            })
 3605            .collect::<Vec<_>>();
 3606
 3607        let mut worktree_globs = HashMap::default();
 3608        let mut abs_globs = HashMap::default();
 3609        log::trace!(
 3610            "Processing new watcher paths for language server with id {}",
 3611            language_server_id
 3612        );
 3613
 3614        for watcher in watchers {
 3615            if let Some((worktree, literal_prefix, pattern)) =
 3616                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3617            {
 3618                worktree.update(cx, |worktree, _| {
 3619                    if let Some((tree, glob)) =
 3620                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3621                    {
 3622                        tree.add_path_prefix_to_scan(literal_prefix);
 3623                        worktree_globs
 3624                            .entry(tree.id())
 3625                            .or_insert_with(GlobSetBuilder::new)
 3626                            .add(glob);
 3627                    }
 3628                });
 3629            } else {
 3630                let (path, pattern) = match &watcher.glob_pattern {
 3631                    lsp::GlobPattern::String(s) => {
 3632                        let watcher_path = SanitizedPath::new(s);
 3633                        let path = glob_literal_prefix(watcher_path.as_path());
 3634                        let pattern = watcher_path
 3635                            .as_path()
 3636                            .strip_prefix(&path)
 3637                            .map(|p| p.to_string_lossy().into_owned())
 3638                            .unwrap_or_else(|e| {
 3639                                debug_panic!(
 3640                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3641                                    s,
 3642                                    path.display(),
 3643                                    e
 3644                                );
 3645                                watcher_path.as_path().to_string_lossy().into_owned()
 3646                            });
 3647                        (path, pattern)
 3648                    }
 3649                    lsp::GlobPattern::Relative(rp) => {
 3650                        let Ok(mut base_uri) = match &rp.base_uri {
 3651                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3652                            lsp::OneOf::Right(base_uri) => base_uri,
 3653                        }
 3654                        .to_file_path() else {
 3655                            continue;
 3656                        };
 3657
 3658                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3659                        let pattern = Path::new(&rp.pattern)
 3660                            .strip_prefix(&path)
 3661                            .map(|p| p.to_string_lossy().into_owned())
 3662                            .unwrap_or_else(|e| {
 3663                                debug_panic!(
 3664                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3665                                    rp.pattern,
 3666                                    path.display(),
 3667                                    e
 3668                                );
 3669                                rp.pattern.clone()
 3670                            });
 3671                        base_uri.push(path);
 3672                        (base_uri, pattern)
 3673                    }
 3674                };
 3675
 3676                if let Some(glob) = Glob::new(&pattern).log_err() {
 3677                    if !path
 3678                        .components()
 3679                        .any(|c| matches!(c, path::Component::Normal(_)))
 3680                    {
 3681                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3682                        // rather than adding a new watcher for `/`.
 3683                        for worktree in &worktrees {
 3684                            worktree_globs
 3685                                .entry(worktree.read(cx).id())
 3686                                .or_insert_with(GlobSetBuilder::new)
 3687                                .add(glob.clone());
 3688                        }
 3689                    } else {
 3690                        abs_globs
 3691                            .entry(path.into())
 3692                            .or_insert_with(GlobSetBuilder::new)
 3693                            .add(glob);
 3694                    }
 3695                }
 3696            }
 3697        }
 3698
 3699        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3700        for (worktree_id, builder) in worktree_globs {
 3701            if let Ok(globset) = builder.build() {
 3702                watch_builder.watch_worktree(worktree_id, globset);
 3703            }
 3704        }
 3705        for (abs_path, builder) in abs_globs {
 3706            if let Ok(globset) = builder.build() {
 3707                watch_builder.watch_abs_path(abs_path, globset);
 3708            }
 3709        }
 3710        watch_builder
 3711    }
 3712
 3713    fn worktree_and_path_for_file_watcher(
 3714        worktrees: &[Entity<Worktree>],
 3715        watcher: &FileSystemWatcher,
 3716        cx: &App,
 3717    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3718        worktrees.iter().find_map(|worktree| {
 3719            let tree = worktree.read(cx);
 3720            let worktree_root_path = tree.abs_path();
 3721            let path_style = tree.path_style();
 3722            match &watcher.glob_pattern {
 3723                lsp::GlobPattern::String(s) => {
 3724                    let watcher_path = SanitizedPath::new(s);
 3725                    let relative = watcher_path
 3726                        .as_path()
 3727                        .strip_prefix(&worktree_root_path)
 3728                        .ok()?;
 3729                    let literal_prefix = glob_literal_prefix(relative);
 3730                    Some((
 3731                        worktree.clone(),
 3732                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3733                        relative.to_string_lossy().into_owned(),
 3734                    ))
 3735                }
 3736                lsp::GlobPattern::Relative(rp) => {
 3737                    let base_uri = match &rp.base_uri {
 3738                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3739                        lsp::OneOf::Right(base_uri) => base_uri,
 3740                    }
 3741                    .to_file_path()
 3742                    .ok()?;
 3743                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3744                    let mut literal_prefix = relative.to_owned();
 3745                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3746                    Some((
 3747                        worktree.clone(),
 3748                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3749                        rp.pattern.clone(),
 3750                    ))
 3751                }
 3752            }
 3753        })
 3754    }
 3755
 3756    fn rebuild_watched_paths(
 3757        &mut self,
 3758        language_server_id: LanguageServerId,
 3759        cx: &mut Context<LspStore>,
 3760    ) {
 3761        let Some(registrations) = self
 3762            .language_server_dynamic_registrations
 3763            .get(&language_server_id)
 3764        else {
 3765            return;
 3766        };
 3767
 3768        let watch_builder = self.rebuild_watched_paths_inner(
 3769            language_server_id,
 3770            registrations.did_change_watched_files.values().flatten(),
 3771            cx,
 3772        );
 3773        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3774        self.language_server_watched_paths
 3775            .insert(language_server_id, watcher);
 3776
 3777        cx.notify();
 3778    }
 3779
 3780    fn on_lsp_did_change_watched_files(
 3781        &mut self,
 3782        language_server_id: LanguageServerId,
 3783        registration_id: &str,
 3784        params: DidChangeWatchedFilesRegistrationOptions,
 3785        cx: &mut Context<LspStore>,
 3786    ) {
 3787        let registrations = self
 3788            .language_server_dynamic_registrations
 3789            .entry(language_server_id)
 3790            .or_default();
 3791
 3792        registrations
 3793            .did_change_watched_files
 3794            .insert(registration_id.to_string(), params.watchers);
 3795
 3796        self.rebuild_watched_paths(language_server_id, cx);
 3797    }
 3798
 3799    fn on_lsp_unregister_did_change_watched_files(
 3800        &mut self,
 3801        language_server_id: LanguageServerId,
 3802        registration_id: &str,
 3803        cx: &mut Context<LspStore>,
 3804    ) {
 3805        let registrations = self
 3806            .language_server_dynamic_registrations
 3807            .entry(language_server_id)
 3808            .or_default();
 3809
 3810        if registrations
 3811            .did_change_watched_files
 3812            .remove(registration_id)
 3813            .is_some()
 3814        {
 3815            log::info!(
 3816                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3817                language_server_id,
 3818                registration_id
 3819            );
 3820        } else {
 3821            log::warn!(
 3822                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3823                language_server_id,
 3824                registration_id
 3825            );
 3826        }
 3827
 3828        self.rebuild_watched_paths(language_server_id, cx);
 3829    }
 3830
 3831    async fn initialization_options_for_adapter(
 3832        adapter: Arc<dyn LspAdapter>,
 3833        delegate: &Arc<dyn LspAdapterDelegate>,
 3834        cx: &mut AsyncApp,
 3835    ) -> Result<Option<serde_json::Value>> {
 3836        let Some(mut initialization_config) =
 3837            adapter.clone().initialization_options(delegate, cx).await?
 3838        else {
 3839            return Ok(None);
 3840        };
 3841
 3842        for other_adapter in delegate.registered_lsp_adapters() {
 3843            if other_adapter.name() == adapter.name() {
 3844                continue;
 3845            }
 3846            if let Ok(Some(target_config)) = other_adapter
 3847                .clone()
 3848                .additional_initialization_options(adapter.name(), delegate)
 3849                .await
 3850            {
 3851                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3852            }
 3853        }
 3854
 3855        Ok(Some(initialization_config))
 3856    }
 3857
 3858    async fn workspace_configuration_for_adapter(
 3859        adapter: Arc<dyn LspAdapter>,
 3860        delegate: &Arc<dyn LspAdapterDelegate>,
 3861        toolchain: Option<Toolchain>,
 3862        requested_uri: Option<Uri>,
 3863        cx: &mut AsyncApp,
 3864    ) -> Result<serde_json::Value> {
 3865        let mut workspace_config = adapter
 3866            .clone()
 3867            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3868            .await?;
 3869
 3870        for other_adapter in delegate.registered_lsp_adapters() {
 3871            if other_adapter.name() == adapter.name() {
 3872                continue;
 3873            }
 3874            if let Ok(Some(target_config)) = other_adapter
 3875                .clone()
 3876                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3877                .await
 3878            {
 3879                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3880            }
 3881        }
 3882
 3883        Ok(workspace_config)
 3884    }
 3885
 3886    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3887        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3888            Some(server.clone())
 3889        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3890            Some(Arc::clone(server))
 3891        } else {
 3892            None
 3893        }
 3894    }
 3895}
 3896
 3897fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3898    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3899        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3900            language_server_id: server.server_id(),
 3901            name: Some(server.name()),
 3902            message: proto::update_language_server::Variant::MetadataUpdated(
 3903                proto::ServerMetadataUpdated {
 3904                    capabilities: Some(capabilities),
 3905                    binary: Some(proto::LanguageServerBinaryInfo {
 3906                        path: server.binary().path.to_string_lossy().into_owned(),
 3907                        arguments: server
 3908                            .binary()
 3909                            .arguments
 3910                            .iter()
 3911                            .map(|arg| arg.to_string_lossy().into_owned())
 3912                            .collect(),
 3913                    }),
 3914                    configuration: serde_json::to_string(server.configuration()).ok(),
 3915                    workspace_folders: server
 3916                        .workspace_folders()
 3917                        .iter()
 3918                        .map(|uri| uri.to_string())
 3919                        .collect(),
 3920                },
 3921            ),
 3922        });
 3923    }
 3924}
 3925
 3926#[derive(Debug)]
 3927pub struct FormattableBuffer {
 3928    handle: Entity<Buffer>,
 3929    abs_path: Option<PathBuf>,
 3930    env: Option<HashMap<String, String>>,
 3931    ranges: Option<Vec<Range<Anchor>>>,
 3932}
 3933
 3934pub struct RemoteLspStore {
 3935    upstream_client: Option<AnyProtoClient>,
 3936    upstream_project_id: u64,
 3937}
 3938
 3939pub(crate) enum LspStoreMode {
 3940    Local(LocalLspStore),   // ssh host and collab host
 3941    Remote(RemoteLspStore), // collab guest
 3942}
 3943
 3944impl LspStoreMode {
 3945    fn is_local(&self) -> bool {
 3946        matches!(self, LspStoreMode::Local(_))
 3947    }
 3948}
 3949
 3950pub struct LspStore {
 3951    mode: LspStoreMode,
 3952    last_formatting_failure: Option<String>,
 3953    downstream_client: Option<(AnyProtoClient, u64)>,
 3954    nonce: u128,
 3955    buffer_store: Entity<BufferStore>,
 3956    worktree_store: Entity<WorktreeStore>,
 3957    pub languages: Arc<LanguageRegistry>,
 3958    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3959    active_entry: Option<ProjectEntryId>,
 3960    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3961    _maintain_buffer_languages: Task<()>,
 3962    diagnostic_summaries:
 3963        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3964    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3965    semantic_token_config: SemanticTokenConfig,
 3966    lsp_data: HashMap<BufferId, BufferLspData>,
 3967    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3968    next_hint_id: Arc<AtomicUsize>,
 3969}
 3970
 3971#[derive(Debug)]
 3972pub struct BufferLspData {
 3973    buffer_version: Global,
 3974    document_colors: Option<DocumentColorData>,
 3975    code_lens: Option<CodeLensData>,
 3976    semantic_tokens: Option<SemanticTokensData>,
 3977    folding_ranges: Option<FoldingRangeData>,
 3978    document_symbols: Option<DocumentSymbolsData>,
 3979    inlay_hints: BufferInlayHints,
 3980    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3981    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3982}
 3983
 3984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3985struct LspKey {
 3986    request_type: TypeId,
 3987    server_queried: Option<LanguageServerId>,
 3988}
 3989
 3990impl BufferLspData {
 3991    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3992        Self {
 3993            buffer_version: buffer.read(cx).version(),
 3994            document_colors: None,
 3995            code_lens: None,
 3996            semantic_tokens: None,
 3997            folding_ranges: None,
 3998            document_symbols: None,
 3999            inlay_hints: BufferInlayHints::new(buffer, cx),
 4000            lsp_requests: HashMap::default(),
 4001            chunk_lsp_requests: HashMap::default(),
 4002        }
 4003    }
 4004
 4005    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4006        if let Some(document_colors) = &mut self.document_colors {
 4007            document_colors.remove_server_data(for_server);
 4008        }
 4009
 4010        if let Some(code_lens) = &mut self.code_lens {
 4011            code_lens.remove_server_data(for_server);
 4012        }
 4013
 4014        self.inlay_hints.remove_server_data(for_server);
 4015
 4016        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4017            semantic_tokens.remove_server_data(for_server);
 4018        }
 4019
 4020        if let Some(folding_ranges) = &mut self.folding_ranges {
 4021            folding_ranges.ranges.remove(&for_server);
 4022        }
 4023
 4024        if let Some(document_symbols) = &mut self.document_symbols {
 4025            document_symbols.remove_server_data(for_server);
 4026        }
 4027    }
 4028
 4029    #[cfg(any(test, feature = "test-support"))]
 4030    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4031        &self.inlay_hints
 4032    }
 4033}
 4034
 4035#[derive(Debug)]
 4036pub enum LspStoreEvent {
 4037    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4038    LanguageServerRemoved(LanguageServerId),
 4039    LanguageServerUpdate {
 4040        language_server_id: LanguageServerId,
 4041        name: Option<LanguageServerName>,
 4042        message: proto::update_language_server::Variant,
 4043    },
 4044    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4045    LanguageServerPrompt(LanguageServerPromptRequest),
 4046    LanguageDetected {
 4047        buffer: Entity<Buffer>,
 4048        new_language: Option<Arc<Language>>,
 4049    },
 4050    Notification(String),
 4051    RefreshInlayHints {
 4052        server_id: LanguageServerId,
 4053        request_id: Option<usize>,
 4054    },
 4055    RefreshSemanticTokens {
 4056        server_id: LanguageServerId,
 4057        request_id: Option<usize>,
 4058    },
 4059    RefreshCodeLens,
 4060    DiagnosticsUpdated {
 4061        server_id: LanguageServerId,
 4062        paths: Vec<ProjectPath>,
 4063    },
 4064    DiskBasedDiagnosticsStarted {
 4065        language_server_id: LanguageServerId,
 4066    },
 4067    DiskBasedDiagnosticsFinished {
 4068        language_server_id: LanguageServerId,
 4069    },
 4070    SnippetEdit {
 4071        buffer_id: BufferId,
 4072        edits: Vec<(lsp::Range, Snippet)>,
 4073        most_recent_edit: clock::Lamport,
 4074    },
 4075    WorkspaceEditApplied(ProjectTransaction),
 4076}
 4077
 4078#[derive(Clone, Debug, Serialize)]
 4079pub struct LanguageServerStatus {
 4080    pub name: LanguageServerName,
 4081    pub server_version: Option<SharedString>,
 4082    pub server_readable_version: Option<SharedString>,
 4083    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4084    pub has_pending_diagnostic_updates: bool,
 4085    pub progress_tokens: HashSet<ProgressToken>,
 4086    pub worktree: Option<WorktreeId>,
 4087    pub binary: Option<LanguageServerBinary>,
 4088    pub configuration: Option<Value>,
 4089    pub workspace_folders: BTreeSet<Uri>,
 4090    pub process_id: Option<u32>,
 4091}
 4092
 4093#[derive(Clone, Debug)]
 4094struct CoreSymbol {
 4095    pub language_server_name: LanguageServerName,
 4096    pub source_worktree_id: WorktreeId,
 4097    pub source_language_server_id: LanguageServerId,
 4098    pub path: SymbolLocation,
 4099    pub name: String,
 4100    pub kind: lsp::SymbolKind,
 4101    pub range: Range<Unclipped<PointUtf16>>,
 4102    pub container_name: Option<String>,
 4103}
 4104
 4105#[derive(Clone, Debug, PartialEq, Eq)]
 4106pub enum SymbolLocation {
 4107    InProject(ProjectPath),
 4108    OutsideProject {
 4109        abs_path: Arc<Path>,
 4110        signature: [u8; 32],
 4111    },
 4112}
 4113
 4114impl SymbolLocation {
 4115    fn file_name(&self) -> Option<&str> {
 4116        match self {
 4117            Self::InProject(path) => path.path.file_name(),
 4118            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4119        }
 4120    }
 4121}
 4122
 4123impl LspStore {
 4124    pub fn init(client: &AnyProtoClient) {
 4125        client.add_entity_request_handler(Self::handle_lsp_query);
 4126        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4127        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4128        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4129        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4130        client.add_entity_message_handler(Self::handle_start_language_server);
 4131        client.add_entity_message_handler(Self::handle_update_language_server);
 4132        client.add_entity_message_handler(Self::handle_language_server_log);
 4133        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4134        client.add_entity_request_handler(Self::handle_format_buffers);
 4135        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4136        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4137        client.add_entity_request_handler(Self::handle_apply_code_action);
 4138        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4139        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4140        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4141        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4142        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4143        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4144        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4145        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4146        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4147        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4148        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4149        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4150        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4151        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4152        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4153        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4154        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4155        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4156
 4157        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4158        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4159        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4160        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4161        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4162        client.add_entity_request_handler(
 4163            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4164        );
 4165        client.add_entity_request_handler(
 4166            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4167        );
 4168        client.add_entity_request_handler(
 4169            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4170        );
 4171    }
 4172
 4173    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4174        match &self.mode {
 4175            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4176            _ => None,
 4177        }
 4178    }
 4179
 4180    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4181        match &self.mode {
 4182            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4183            _ => None,
 4184        }
 4185    }
 4186
 4187    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4188        match &mut self.mode {
 4189            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4190            _ => None,
 4191        }
 4192    }
 4193
 4194    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4195        match &self.mode {
 4196            LspStoreMode::Remote(RemoteLspStore {
 4197                upstream_client: Some(upstream_client),
 4198                upstream_project_id,
 4199                ..
 4200            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4201
 4202            LspStoreMode::Remote(RemoteLspStore {
 4203                upstream_client: None,
 4204                ..
 4205            }) => None,
 4206            LspStoreMode::Local(_) => None,
 4207        }
 4208    }
 4209
 4210    pub fn new_local(
 4211        buffer_store: Entity<BufferStore>,
 4212        worktree_store: Entity<WorktreeStore>,
 4213        prettier_store: Entity<PrettierStore>,
 4214        toolchain_store: Entity<LocalToolchainStore>,
 4215        environment: Entity<ProjectEnvironment>,
 4216        manifest_tree: Entity<ManifestTree>,
 4217        languages: Arc<LanguageRegistry>,
 4218        http_client: Arc<dyn HttpClient>,
 4219        fs: Arc<dyn Fs>,
 4220        cx: &mut Context<Self>,
 4221    ) -> Self {
 4222        let yarn = YarnPathStore::new(fs.clone(), cx);
 4223        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4224            .detach();
 4225        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4226            .detach();
 4227        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4228            .detach();
 4229        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4230            .detach();
 4231        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4232            .detach();
 4233        subscribe_to_binary_statuses(&languages, cx).detach();
 4234
 4235        let _maintain_workspace_config = {
 4236            let (sender, receiver) = watch::channel();
 4237            (Self::maintain_workspace_config(receiver, cx), sender)
 4238        };
 4239
 4240        Self {
 4241            mode: LspStoreMode::Local(LocalLspStore {
 4242                weak: cx.weak_entity(),
 4243                worktree_store: worktree_store.clone(),
 4244
 4245                supplementary_language_servers: Default::default(),
 4246                languages: languages.clone(),
 4247                language_server_ids: Default::default(),
 4248                language_servers: Default::default(),
 4249                last_workspace_edits_by_language_server: Default::default(),
 4250                language_server_watched_paths: Default::default(),
 4251                language_server_paths_watched_for_rename: Default::default(),
 4252                language_server_dynamic_registrations: Default::default(),
 4253                buffers_being_formatted: Default::default(),
 4254                buffers_to_refresh_hash_set: HashSet::default(),
 4255                buffers_to_refresh_queue: VecDeque::new(),
 4256                _background_diagnostics_worker: Task::ready(()).shared(),
 4257                buffer_snapshots: Default::default(),
 4258                prettier_store,
 4259                environment,
 4260                http_client,
 4261                fs,
 4262                yarn,
 4263                next_diagnostic_group_id: Default::default(),
 4264                diagnostics: Default::default(),
 4265                _subscription: cx.on_app_quit(|this, _| {
 4266                    this.as_local_mut()
 4267                        .unwrap()
 4268                        .shutdown_language_servers_on_quit()
 4269                }),
 4270                lsp_tree: LanguageServerTree::new(
 4271                    manifest_tree,
 4272                    languages.clone(),
 4273                    toolchain_store.clone(),
 4274                ),
 4275                toolchain_store,
 4276                registered_buffers: HashMap::default(),
 4277                buffers_opened_in_servers: HashMap::default(),
 4278                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4279                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4280                restricted_worktrees_tasks: HashMap::default(),
 4281                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4282                    .manifest_file_names(),
 4283            }),
 4284            last_formatting_failure: None,
 4285            downstream_client: None,
 4286            buffer_store,
 4287            worktree_store,
 4288            languages: languages.clone(),
 4289            language_server_statuses: Default::default(),
 4290            nonce: StdRng::from_os_rng().random(),
 4291            diagnostic_summaries: HashMap::default(),
 4292            lsp_server_capabilities: HashMap::default(),
 4293            semantic_token_config: SemanticTokenConfig::new(cx),
 4294            lsp_data: HashMap::default(),
 4295            buffer_reload_tasks: HashMap::default(),
 4296            next_hint_id: Arc::default(),
 4297            active_entry: None,
 4298            _maintain_workspace_config,
 4299            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4300        }
 4301    }
 4302
 4303    fn send_lsp_proto_request<R: LspCommand>(
 4304        &self,
 4305        buffer: Entity<Buffer>,
 4306        client: AnyProtoClient,
 4307        upstream_project_id: u64,
 4308        request: R,
 4309        cx: &mut Context<LspStore>,
 4310    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4311        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4312            return Task::ready(Ok(R::Response::default()));
 4313        }
 4314        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4315        cx.spawn(async move |this, cx| {
 4316            let response = client.request(message).await?;
 4317            let this = this.upgrade().context("project dropped")?;
 4318            request
 4319                .response_from_proto(response, this, buffer, cx.clone())
 4320                .await
 4321        })
 4322    }
 4323
 4324    pub(super) fn new_remote(
 4325        buffer_store: Entity<BufferStore>,
 4326        worktree_store: Entity<WorktreeStore>,
 4327        languages: Arc<LanguageRegistry>,
 4328        upstream_client: AnyProtoClient,
 4329        project_id: u64,
 4330        cx: &mut Context<Self>,
 4331    ) -> Self {
 4332        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4333            .detach();
 4334        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4335            .detach();
 4336        subscribe_to_binary_statuses(&languages, cx).detach();
 4337        let _maintain_workspace_config = {
 4338            let (sender, receiver) = watch::channel();
 4339            (Self::maintain_workspace_config(receiver, cx), sender)
 4340        };
 4341        Self {
 4342            mode: LspStoreMode::Remote(RemoteLspStore {
 4343                upstream_client: Some(upstream_client),
 4344                upstream_project_id: project_id,
 4345            }),
 4346            downstream_client: None,
 4347            last_formatting_failure: None,
 4348            buffer_store,
 4349            worktree_store,
 4350            languages: languages.clone(),
 4351            language_server_statuses: Default::default(),
 4352            nonce: StdRng::from_os_rng().random(),
 4353            diagnostic_summaries: HashMap::default(),
 4354            lsp_server_capabilities: HashMap::default(),
 4355            semantic_token_config: SemanticTokenConfig::new(cx),
 4356            next_hint_id: Arc::default(),
 4357            lsp_data: HashMap::default(),
 4358            buffer_reload_tasks: HashMap::default(),
 4359            active_entry: None,
 4360
 4361            _maintain_workspace_config,
 4362            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4363        }
 4364    }
 4365
 4366    fn on_buffer_store_event(
 4367        &mut self,
 4368        _: Entity<BufferStore>,
 4369        event: &BufferStoreEvent,
 4370        cx: &mut Context<Self>,
 4371    ) {
 4372        match event {
 4373            BufferStoreEvent::BufferAdded(buffer) => {
 4374                self.on_buffer_added(buffer, cx).log_err();
 4375            }
 4376            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4377                let buffer_id = buffer.read(cx).remote_id();
 4378                if let Some(local) = self.as_local_mut()
 4379                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4380                {
 4381                    local.reset_buffer(buffer, old_file, cx);
 4382
 4383                    if local.registered_buffers.contains_key(&buffer_id) {
 4384                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4385                    }
 4386                }
 4387
 4388                self.detect_language_for_buffer(buffer, cx);
 4389                if let Some(local) = self.as_local_mut() {
 4390                    local.initialize_buffer(buffer, cx);
 4391                    if local.registered_buffers.contains_key(&buffer_id) {
 4392                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4393                    }
 4394                }
 4395            }
 4396            _ => {}
 4397        }
 4398    }
 4399
 4400    fn on_worktree_store_event(
 4401        &mut self,
 4402        _: Entity<WorktreeStore>,
 4403        event: &WorktreeStoreEvent,
 4404        cx: &mut Context<Self>,
 4405    ) {
 4406        match event {
 4407            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4408                if !worktree.read(cx).is_local() {
 4409                    return;
 4410                }
 4411                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4412                    worktree::Event::UpdatedEntries(changes) => {
 4413                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4414                    }
 4415                    worktree::Event::UpdatedGitRepositories(_)
 4416                    | worktree::Event::DeletedEntry(_)
 4417                    | worktree::Event::Deleted
 4418                    | worktree::Event::UpdatedRootRepoCommonDir => {}
 4419                })
 4420                .detach()
 4421            }
 4422            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4423            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4424                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4425            }
 4426            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4427                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4428            }
 4429            WorktreeStoreEvent::WorktreeReleased(..)
 4430            | WorktreeStoreEvent::WorktreeOrderChanged
 4431            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4432            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4433        }
 4434    }
 4435
 4436    fn on_prettier_store_event(
 4437        &mut self,
 4438        _: Entity<PrettierStore>,
 4439        event: &PrettierStoreEvent,
 4440        cx: &mut Context<Self>,
 4441    ) {
 4442        match event {
 4443            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4444                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4445            }
 4446            PrettierStoreEvent::LanguageServerAdded {
 4447                new_server_id,
 4448                name,
 4449                prettier_server,
 4450            } => {
 4451                self.register_supplementary_language_server(
 4452                    *new_server_id,
 4453                    name.clone(),
 4454                    prettier_server.clone(),
 4455                    cx,
 4456                );
 4457            }
 4458        }
 4459    }
 4460
 4461    fn on_toolchain_store_event(
 4462        &mut self,
 4463        _: Entity<LocalToolchainStore>,
 4464        event: &ToolchainStoreEvent,
 4465        _: &mut Context<Self>,
 4466    ) {
 4467        if let ToolchainStoreEvent::ToolchainActivated = event {
 4468            self.request_workspace_config_refresh()
 4469        }
 4470    }
 4471
 4472    fn request_workspace_config_refresh(&mut self) {
 4473        *self._maintain_workspace_config.1.borrow_mut() = ();
 4474    }
 4475
 4476    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4477        self.as_local().map(|local| local.prettier_store.clone())
 4478    }
 4479
 4480    fn on_buffer_event(
 4481        &mut self,
 4482        buffer: Entity<Buffer>,
 4483        event: &language::BufferEvent,
 4484        cx: &mut Context<Self>,
 4485    ) {
 4486        match event {
 4487            language::BufferEvent::Edited { .. } => {
 4488                self.on_buffer_edited(buffer, cx);
 4489            }
 4490
 4491            language::BufferEvent::Saved => {
 4492                self.on_buffer_saved(buffer, cx);
 4493            }
 4494
 4495            language::BufferEvent::Reloaded => {
 4496                self.on_buffer_reloaded(buffer, cx);
 4497            }
 4498
 4499            _ => {}
 4500        }
 4501    }
 4502
 4503    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4504        buffer
 4505            .read(cx)
 4506            .set_language_registry(self.languages.clone());
 4507
 4508        cx.subscribe(buffer, |this, buffer, event, cx| {
 4509            this.on_buffer_event(buffer, event, cx);
 4510        })
 4511        .detach();
 4512
 4513        self.parse_modeline(buffer, cx);
 4514        self.detect_language_for_buffer(buffer, cx);
 4515        if let Some(local) = self.as_local_mut() {
 4516            local.initialize_buffer(buffer, cx);
 4517        }
 4518
 4519        Ok(())
 4520    }
 4521
 4522    pub fn refresh_background_diagnostics_for_buffers(
 4523        &mut self,
 4524        buffers: HashSet<BufferId>,
 4525        cx: &mut Context<Self>,
 4526    ) -> Shared<Task<()>> {
 4527        let Some(local) = self.as_local_mut() else {
 4528            return Task::ready(()).shared();
 4529        };
 4530        for buffer in buffers {
 4531            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4532                local.buffers_to_refresh_queue.push_back(buffer);
 4533                if local.buffers_to_refresh_queue.len() == 1 {
 4534                    local._background_diagnostics_worker =
 4535                        Self::background_diagnostics_worker(cx).shared();
 4536                }
 4537            }
 4538        }
 4539
 4540        local._background_diagnostics_worker.clone()
 4541    }
 4542
 4543    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4544        let buffer_store = self.buffer_store.clone();
 4545        let local = self.as_local_mut()?;
 4546        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4547            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4548            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4549                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4550            }
 4551        }
 4552        None
 4553    }
 4554
 4555    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4556        cx.spawn(async move |this, cx| {
 4557            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4558                task.await.log_err();
 4559            }
 4560        })
 4561    }
 4562
 4563    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4564        if self.parse_modeline(&buffer, cx) {
 4565            self.detect_language_for_buffer(&buffer, cx);
 4566        }
 4567
 4568        let buffer_id = buffer.read(cx).remote_id();
 4569        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4570        self.buffer_reload_tasks.insert(buffer_id, task);
 4571    }
 4572
 4573    pub(crate) fn register_buffer_with_language_servers(
 4574        &mut self,
 4575        buffer: &Entity<Buffer>,
 4576        only_register_servers: HashSet<LanguageServerSelector>,
 4577        ignore_refcounts: bool,
 4578        cx: &mut Context<Self>,
 4579    ) -> OpenLspBufferHandle {
 4580        let buffer_id = buffer.read(cx).remote_id();
 4581        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4582        if let Some(local) = self.as_local_mut() {
 4583            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4584            if !ignore_refcounts {
 4585                *refcount += 1;
 4586            }
 4587
 4588            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4589            // 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
 4590            // 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
 4591            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4592            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4593                return handle;
 4594            };
 4595            if !file.is_local() {
 4596                return handle;
 4597            }
 4598
 4599            if ignore_refcounts || *refcount == 1 {
 4600                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4601            }
 4602            if !ignore_refcounts {
 4603                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4604                    let refcount = {
 4605                        let local = lsp_store.as_local_mut().unwrap();
 4606                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4607                            debug_panic!("bad refcounting");
 4608                            return;
 4609                        };
 4610
 4611                        *refcount -= 1;
 4612                        *refcount
 4613                    };
 4614                    if refcount == 0 {
 4615                        lsp_store.lsp_data.remove(&buffer_id);
 4616                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4617                        let local = lsp_store.as_local_mut().unwrap();
 4618                        local.registered_buffers.remove(&buffer_id);
 4619
 4620                        local.buffers_opened_in_servers.remove(&buffer_id);
 4621                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4622                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4623
 4624                            let buffer_abs_path = file.abs_path(cx);
 4625                            for (_, buffer_pull_diagnostics_result_ids) in
 4626                                &mut local.buffer_pull_diagnostics_result_ids
 4627                            {
 4628                                buffer_pull_diagnostics_result_ids.retain(
 4629                                    |_, buffer_result_ids| {
 4630                                        buffer_result_ids.remove(&buffer_abs_path);
 4631                                        !buffer_result_ids.is_empty()
 4632                                    },
 4633                                );
 4634                            }
 4635
 4636                            let diagnostic_updates = local
 4637                                .language_servers
 4638                                .keys()
 4639                                .cloned()
 4640                                .map(|server_id| DocumentDiagnosticsUpdate {
 4641                                    diagnostics: DocumentDiagnostics {
 4642                                        document_abs_path: buffer_abs_path.clone(),
 4643                                        version: None,
 4644                                        diagnostics: Vec::new(),
 4645                                    },
 4646                                    result_id: None,
 4647                                    registration_id: None,
 4648                                    server_id,
 4649                                    disk_based_sources: Cow::Borrowed(&[]),
 4650                                })
 4651                                .collect::<Vec<_>>();
 4652
 4653                            lsp_store
 4654                                .merge_diagnostic_entries(
 4655                                    diagnostic_updates,
 4656                                    |_, diagnostic, _| {
 4657                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4658                                    },
 4659                                    cx,
 4660                                )
 4661                                .context("Clearing diagnostics for the closed buffer")
 4662                                .log_err();
 4663                        }
 4664                    }
 4665                })
 4666                .detach();
 4667            }
 4668        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4669            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4670            cx.background_spawn(async move {
 4671                upstream_client
 4672                    .request(proto::RegisterBufferWithLanguageServers {
 4673                        project_id: upstream_project_id,
 4674                        buffer_id,
 4675                        only_servers: only_register_servers
 4676                            .into_iter()
 4677                            .map(|selector| {
 4678                                let selector = match selector {
 4679                                    LanguageServerSelector::Id(language_server_id) => {
 4680                                        proto::language_server_selector::Selector::ServerId(
 4681                                            language_server_id.to_proto(),
 4682                                        )
 4683                                    }
 4684                                    LanguageServerSelector::Name(language_server_name) => {
 4685                                        proto::language_server_selector::Selector::Name(
 4686                                            language_server_name.to_string(),
 4687                                        )
 4688                                    }
 4689                                };
 4690                                proto::LanguageServerSelector {
 4691                                    selector: Some(selector),
 4692                                }
 4693                            })
 4694                            .collect(),
 4695                    })
 4696                    .await
 4697            })
 4698            .detach();
 4699        } else {
 4700            // Our remote connection got closed
 4701        }
 4702        handle
 4703    }
 4704
 4705    fn maintain_buffer_languages(
 4706        languages: Arc<LanguageRegistry>,
 4707        cx: &mut Context<Self>,
 4708    ) -> Task<()> {
 4709        let mut subscription = languages.subscribe();
 4710        let mut prev_reload_count = languages.reload_count();
 4711        cx.spawn(async move |this, cx| {
 4712            while let Some(()) = subscription.next().await {
 4713                if let Some(this) = this.upgrade() {
 4714                    // If the language registry has been reloaded, then remove and
 4715                    // re-assign the languages on all open buffers.
 4716                    let reload_count = languages.reload_count();
 4717                    if reload_count > prev_reload_count {
 4718                        prev_reload_count = reload_count;
 4719                        this.update(cx, |this, cx| {
 4720                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4721                                for buffer in buffer_store.buffers() {
 4722                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4723                                    {
 4724                                        buffer.update(cx, |buffer, cx| {
 4725                                            buffer.set_language_async(None, cx)
 4726                                        });
 4727                                        if let Some(local) = this.as_local_mut() {
 4728                                            local.reset_buffer(&buffer, &f, cx);
 4729
 4730                                            if local
 4731                                                .registered_buffers
 4732                                                .contains_key(&buffer.read(cx).remote_id())
 4733                                                && let Some(file_url) =
 4734                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4735                                            {
 4736                                                local.unregister_buffer_from_language_servers(
 4737                                                    &buffer, &file_url, cx,
 4738                                                );
 4739                                            }
 4740                                        }
 4741                                    }
 4742                                }
 4743                            });
 4744                        });
 4745                    }
 4746
 4747                    this.update(cx, |this, cx| {
 4748                        let mut plain_text_buffers = Vec::new();
 4749                        let mut buffers_with_unknown_injections = Vec::new();
 4750                        for handle in this.buffer_store.read(cx).buffers() {
 4751                            let buffer = handle.read(cx);
 4752                            if buffer.language().is_none()
 4753                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4754                            {
 4755                                plain_text_buffers.push(handle);
 4756                            } else if buffer.contains_unknown_injections() {
 4757                                buffers_with_unknown_injections.push(handle);
 4758                            }
 4759                        }
 4760
 4761                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4762                        // and reused later in the invisible worktrees.
 4763                        plain_text_buffers.sort_by_key(|buffer| {
 4764                            Reverse(
 4765                                File::from_dyn(buffer.read(cx).file())
 4766                                    .map(|file| file.worktree.read(cx).is_visible()),
 4767                            )
 4768                        });
 4769
 4770                        for buffer in plain_text_buffers {
 4771                            this.detect_language_for_buffer(&buffer, cx);
 4772                            if let Some(local) = this.as_local_mut() {
 4773                                local.initialize_buffer(&buffer, cx);
 4774                                if local
 4775                                    .registered_buffers
 4776                                    .contains_key(&buffer.read(cx).remote_id())
 4777                                {
 4778                                    local.register_buffer_with_language_servers(
 4779                                        &buffer,
 4780                                        HashSet::default(),
 4781                                        cx,
 4782                                    );
 4783                                }
 4784                            }
 4785                        }
 4786
 4787                        for buffer in buffers_with_unknown_injections {
 4788                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4789                        }
 4790                    });
 4791                }
 4792            }
 4793        })
 4794    }
 4795
 4796    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4797        let buffer = buffer_handle.read(cx);
 4798        let content = buffer.as_rope();
 4799
 4800        let modeline_settings = {
 4801            let settings_store = cx.global::<SettingsStore>();
 4802            let modeline_lines = settings_store
 4803                .raw_user_settings()
 4804                .and_then(|s| s.content.modeline_lines)
 4805                .or(settings_store.raw_default_settings().modeline_lines)
 4806                .unwrap_or(5);
 4807
 4808            const MAX_MODELINE_BYTES: usize = 1024;
 4809
 4810            let first_bytes =
 4811                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4812            let mut first_lines = Vec::new();
 4813            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4814            for _ in 0..modeline_lines {
 4815                if let Some(line) = lines.next() {
 4816                    first_lines.push(line.to_string());
 4817                } else {
 4818                    break;
 4819                }
 4820            }
 4821            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4822
 4823            let last_start =
 4824                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4825            let mut last_lines = Vec::new();
 4826            let mut lines = content
 4827                .reversed_chunks_in_range(last_start..content.len())
 4828                .lines();
 4829            for _ in 0..modeline_lines {
 4830                if let Some(line) = lines.next() {
 4831                    last_lines.push(line.to_string());
 4832                } else {
 4833                    break;
 4834                }
 4835            }
 4836            let last_lines_ref: Vec<_> =
 4837                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4838            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4839        };
 4840
 4841        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4842
 4843        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4844    }
 4845
 4846    fn detect_language_for_buffer(
 4847        &mut self,
 4848        buffer_handle: &Entity<Buffer>,
 4849        cx: &mut Context<Self>,
 4850    ) -> Option<language::AvailableLanguage> {
 4851        // If the buffer has a language, set it and start the language server if we haven't already.
 4852        let buffer = buffer_handle.read(cx);
 4853        let file = buffer.file()?;
 4854        let content = buffer.as_rope();
 4855        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4856
 4857        let available_language = if let Some(ModelineSettings {
 4858            mode: Some(mode_name),
 4859            ..
 4860        }) = modeline_settings
 4861        {
 4862            self.languages
 4863                .available_language_for_modeline_name(mode_name)
 4864        } else {
 4865            self.languages.language_for_file(file, Some(content), cx)
 4866        };
 4867        if let Some(available_language) = &available_language {
 4868            if let Some(Ok(Ok(new_language))) = self
 4869                .languages
 4870                .load_language(available_language)
 4871                .now_or_never()
 4872            {
 4873                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4874            }
 4875        } else {
 4876            cx.emit(LspStoreEvent::LanguageDetected {
 4877                buffer: buffer_handle.clone(),
 4878                new_language: None,
 4879            });
 4880        }
 4881
 4882        available_language
 4883    }
 4884
 4885    pub(crate) fn set_language_for_buffer(
 4886        &mut self,
 4887        buffer_entity: &Entity<Buffer>,
 4888        new_language: Arc<Language>,
 4889        cx: &mut Context<Self>,
 4890    ) {
 4891        let buffer = buffer_entity.read(cx);
 4892        let buffer_file = buffer.file().cloned();
 4893        let buffer_id = buffer.remote_id();
 4894        if let Some(local_store) = self.as_local_mut()
 4895            && local_store.registered_buffers.contains_key(&buffer_id)
 4896            && let Some(abs_path) =
 4897                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4898            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4899        {
 4900            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4901        }
 4902        buffer_entity.update(cx, |buffer, cx| {
 4903            if buffer
 4904                .language()
 4905                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4906            {
 4907                buffer.set_language_async(Some(new_language.clone()), cx);
 4908            }
 4909        });
 4910
 4911        let settings = LanguageSettings::resolve(
 4912            Some(&buffer_entity.read(cx)),
 4913            Some(&new_language.name()),
 4914            cx,
 4915        )
 4916        .into_owned();
 4917        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4918
 4919        let worktree_id = if let Some(file) = buffer_file {
 4920            let worktree = file.worktree.clone();
 4921
 4922            if let Some(local) = self.as_local_mut()
 4923                && local.registered_buffers.contains_key(&buffer_id)
 4924            {
 4925                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4926            }
 4927            Some(worktree.read(cx).id())
 4928        } else {
 4929            None
 4930        };
 4931
 4932        if settings.prettier.allowed
 4933            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4934        {
 4935            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4936            if let Some(prettier_store) = prettier_store {
 4937                prettier_store.update(cx, |prettier_store, cx| {
 4938                    prettier_store.install_default_prettier(
 4939                        worktree_id,
 4940                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4941                        cx,
 4942                    )
 4943                })
 4944            }
 4945        }
 4946
 4947        cx.emit(LspStoreEvent::LanguageDetected {
 4948            buffer: buffer_entity.clone(),
 4949            new_language: Some(new_language),
 4950        })
 4951    }
 4952
 4953    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4954        self.buffer_store.clone()
 4955    }
 4956
 4957    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4958        self.active_entry = active_entry;
 4959    }
 4960
 4961    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4962        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4963            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4964        {
 4965            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4966                summaries
 4967                    .iter()
 4968                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4969            });
 4970            if let Some(summary) = summaries.next() {
 4971                client
 4972                    .send(proto::UpdateDiagnosticSummary {
 4973                        project_id: downstream_project_id,
 4974                        worktree_id: worktree.id().to_proto(),
 4975                        summary: Some(summary),
 4976                        more_summaries: summaries.collect(),
 4977                    })
 4978                    .log_err();
 4979            }
 4980        }
 4981    }
 4982
 4983    fn is_capable_for_proto_request<R>(
 4984        &self,
 4985        buffer: &Entity<Buffer>,
 4986        request: &R,
 4987        cx: &App,
 4988    ) -> bool
 4989    where
 4990        R: LspCommand,
 4991    {
 4992        self.check_if_capable_for_proto_request(
 4993            buffer,
 4994            |capabilities| {
 4995                request.check_capabilities(AdapterServerCapabilities {
 4996                    server_capabilities: capabilities.clone(),
 4997                    code_action_kinds: None,
 4998                })
 4999            },
 5000            cx,
 5001        )
 5002    }
 5003
 5004    fn check_if_capable_for_proto_request<F>(
 5005        &self,
 5006        buffer: &Entity<Buffer>,
 5007        check: F,
 5008        cx: &App,
 5009    ) -> bool
 5010    where
 5011        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5012    {
 5013        let Some(language) = buffer.read(cx).language().cloned() else {
 5014            return false;
 5015        };
 5016        let registered_language_servers = self
 5017            .languages
 5018            .lsp_adapters(&language.name())
 5019            .into_iter()
 5020            .map(|lsp_adapter| lsp_adapter.name())
 5021            .collect::<HashSet<_>>();
 5022        self.language_server_statuses
 5023            .iter()
 5024            .filter_map(|(server_id, server_status)| {
 5025                // Include servers that are either registered for this language OR
 5026                // available to be loaded (for SSH remote mode where adapters like
 5027                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5028                // but only loaded on the server side)
 5029                let is_relevant = registered_language_servers.contains(&server_status.name)
 5030                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5031                is_relevant.then_some(server_id)
 5032            })
 5033            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5034            .any(check)
 5035    }
 5036
 5037    fn all_capable_for_proto_request<F>(
 5038        &self,
 5039        buffer: &Entity<Buffer>,
 5040        mut check: F,
 5041        cx: &App,
 5042    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5043    where
 5044        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5045    {
 5046        let Some(language) = buffer.read(cx).language().cloned() else {
 5047            return Vec::default();
 5048        };
 5049        let registered_language_servers = self
 5050            .languages
 5051            .lsp_adapters(&language.name())
 5052            .into_iter()
 5053            .map(|lsp_adapter| lsp_adapter.name())
 5054            .collect::<HashSet<_>>();
 5055        self.language_server_statuses
 5056            .iter()
 5057            .filter_map(|(server_id, server_status)| {
 5058                // Include servers that are either registered for this language OR
 5059                // available to be loaded (for SSH remote mode where adapters like
 5060                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5061                // but only loaded on the server side)
 5062                let is_relevant = registered_language_servers.contains(&server_status.name)
 5063                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5064                is_relevant.then_some((server_id, &server_status.name))
 5065            })
 5066            .filter_map(|(server_id, server_name)| {
 5067                self.lsp_server_capabilities
 5068                    .get(server_id)
 5069                    .map(|c| (server_id, server_name, c))
 5070            })
 5071            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5072            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5073            .collect()
 5074    }
 5075
 5076    pub fn request_lsp<R>(
 5077        &mut self,
 5078        buffer: Entity<Buffer>,
 5079        server: LanguageServerToQuery,
 5080        request: R,
 5081        cx: &mut Context<Self>,
 5082    ) -> Task<Result<R::Response>>
 5083    where
 5084        R: LspCommand,
 5085        <R::LspRequest as lsp::request::Request>::Result: Send,
 5086        <R::LspRequest as lsp::request::Request>::Params: Send,
 5087    {
 5088        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5089            return self.send_lsp_proto_request(
 5090                buffer,
 5091                upstream_client,
 5092                upstream_project_id,
 5093                request,
 5094                cx,
 5095            );
 5096        }
 5097
 5098        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5099            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5100                local
 5101                    .language_servers_for_buffer(buffer, cx)
 5102                    .find(|(_, server)| {
 5103                        request.check_capabilities(server.adapter_server_capabilities())
 5104                    })
 5105                    .map(|(_, server)| server.clone())
 5106            }),
 5107            LanguageServerToQuery::Other(id) => self
 5108                .language_server_for_local_buffer(buffer, id, cx)
 5109                .and_then(|(_, server)| {
 5110                    request
 5111                        .check_capabilities(server.adapter_server_capabilities())
 5112                        .then(|| Arc::clone(server))
 5113                }),
 5114        }) else {
 5115            return Task::ready(Ok(Default::default()));
 5116        };
 5117
 5118        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5119
 5120        let Some(file) = file else {
 5121            return Task::ready(Ok(Default::default()));
 5122        };
 5123
 5124        let lsp_params = match request.to_lsp_params_or_response(
 5125            &file.abs_path(cx),
 5126            buffer.read(cx),
 5127            &language_server,
 5128            cx,
 5129        ) {
 5130            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5131            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5132            Err(err) => {
 5133                let message = format!(
 5134                    "{} via {} failed: {}",
 5135                    request.display_name(),
 5136                    language_server.name(),
 5137                    err
 5138                );
 5139                // rust-analyzer likes to error with this when its still loading up
 5140                if !message.ends_with("content modified") {
 5141                    log::warn!("{message}");
 5142                }
 5143                return Task::ready(Err(anyhow!(message)));
 5144            }
 5145        };
 5146
 5147        let status = request.status();
 5148        let request_timeout = ProjectSettings::get_global(cx)
 5149            .global_lsp_settings
 5150            .get_request_timeout();
 5151
 5152        cx.spawn(async move |this, cx| {
 5153            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5154
 5155            let id = lsp_request.id();
 5156            let _cleanup = if status.is_some() {
 5157                cx.update(|cx| {
 5158                    this.update(cx, |this, cx| {
 5159                        this.on_lsp_work_start(
 5160                            language_server.server_id(),
 5161                            ProgressToken::Number(id),
 5162                            LanguageServerProgress {
 5163                                is_disk_based_diagnostics_progress: false,
 5164                                is_cancellable: false,
 5165                                title: None,
 5166                                message: status.clone(),
 5167                                percentage: None,
 5168                                last_update_at: cx.background_executor().now(),
 5169                            },
 5170                            cx,
 5171                        );
 5172                    })
 5173                })
 5174                .log_err();
 5175
 5176                Some(defer(|| {
 5177                    cx.update(|cx| {
 5178                        this.update(cx, |this, cx| {
 5179                            this.on_lsp_work_end(
 5180                                language_server.server_id(),
 5181                                ProgressToken::Number(id),
 5182                                cx,
 5183                            );
 5184                        })
 5185                    })
 5186                    .log_err();
 5187                }))
 5188            } else {
 5189                None
 5190            };
 5191
 5192            let result = lsp_request.await.into_response();
 5193
 5194            let response = result.map_err(|err| {
 5195                let message = format!(
 5196                    "{} via {} failed: {}",
 5197                    request.display_name(),
 5198                    language_server.name(),
 5199                    err
 5200                );
 5201                // rust-analyzer likes to error with this when its still loading up
 5202                if !message.ends_with("content modified") {
 5203                    log::warn!("{message}");
 5204                }
 5205                anyhow::anyhow!(message)
 5206            })?;
 5207
 5208            request
 5209                .response_from_lsp(
 5210                    response,
 5211                    this.upgrade().context("no app context")?,
 5212                    buffer,
 5213                    language_server.server_id(),
 5214                    cx.clone(),
 5215                )
 5216                .await
 5217        })
 5218    }
 5219
 5220    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5221        let mut language_formatters_to_check = Vec::new();
 5222        for buffer in self.buffer_store.read(cx).buffers() {
 5223            let buffer = buffer.read(cx);
 5224            let settings = LanguageSettings::for_buffer(buffer, cx);
 5225            if buffer.language().is_some() {
 5226                let buffer_file = File::from_dyn(buffer.file());
 5227                language_formatters_to_check.push((
 5228                    buffer_file.map(|f| f.worktree_id(cx)),
 5229                    settings.into_owned(),
 5230                ));
 5231            }
 5232        }
 5233
 5234        self.request_workspace_config_refresh();
 5235
 5236        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5237            prettier_store.update(cx, |prettier_store, cx| {
 5238                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5239            })
 5240        }
 5241
 5242        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5243            .global_lsp_settings
 5244            .semantic_token_rules
 5245            .clone();
 5246        self.semantic_token_config
 5247            .update_rules(new_semantic_token_rules);
 5248        // Always clear cached stylizers so that changes to language-specific
 5249        // semantic token rules (e.g. from extension install/uninstall) are
 5250        // picked up. Stylizers are recreated lazily, so this is cheap.
 5251        self.semantic_token_config.clear_stylizers();
 5252
 5253        let new_global_semantic_tokens_mode =
 5254            all_language_settings(None, cx).defaults.semantic_tokens;
 5255        if self
 5256            .semantic_token_config
 5257            .update_global_mode(new_global_semantic_tokens_mode)
 5258        {
 5259            self.restart_all_language_servers(cx);
 5260        }
 5261
 5262        cx.notify();
 5263    }
 5264
 5265    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5266        let buffer_store = self.buffer_store.clone();
 5267        let Some(local) = self.as_local_mut() else {
 5268            return;
 5269        };
 5270        let mut adapters = BTreeMap::default();
 5271        let get_adapter = {
 5272            let languages = local.languages.clone();
 5273            let environment = local.environment.clone();
 5274            let weak = local.weak.clone();
 5275            let worktree_store = local.worktree_store.clone();
 5276            let http_client = local.http_client.clone();
 5277            let fs = local.fs.clone();
 5278            move |worktree_id, cx: &mut App| {
 5279                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5280                Some(LocalLspAdapterDelegate::new(
 5281                    languages.clone(),
 5282                    &environment,
 5283                    weak.clone(),
 5284                    &worktree,
 5285                    http_client.clone(),
 5286                    fs.clone(),
 5287                    cx,
 5288                ))
 5289            }
 5290        };
 5291
 5292        let mut messages_to_report = Vec::new();
 5293        let (new_tree, to_stop) = {
 5294            let mut rebase = local.lsp_tree.rebase();
 5295            let buffers = buffer_store
 5296                .read(cx)
 5297                .buffers()
 5298                .filter_map(|buffer| {
 5299                    let raw_buffer = buffer.read(cx);
 5300                    if !local
 5301                        .registered_buffers
 5302                        .contains_key(&raw_buffer.remote_id())
 5303                    {
 5304                        return None;
 5305                    }
 5306                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5307                    let language = raw_buffer.language().cloned()?;
 5308                    Some((file, language, raw_buffer.remote_id()))
 5309                })
 5310                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5311            for (file, language, buffer_id) in buffers {
 5312                let worktree_id = file.worktree_id(cx);
 5313                let Some(worktree) = local
 5314                    .worktree_store
 5315                    .read(cx)
 5316                    .worktree_for_id(worktree_id, cx)
 5317                else {
 5318                    continue;
 5319                };
 5320
 5321                if let Some((_, apply)) = local.reuse_existing_language_server(
 5322                    rebase.server_tree(),
 5323                    &worktree,
 5324                    &language.name(),
 5325                    cx,
 5326                ) {
 5327                    (apply)(rebase.server_tree());
 5328                } else if let Some(lsp_delegate) = adapters
 5329                    .entry(worktree_id)
 5330                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5331                    .clone()
 5332                {
 5333                    let delegate =
 5334                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5335                    let path = file
 5336                        .path()
 5337                        .parent()
 5338                        .map(Arc::from)
 5339                        .unwrap_or_else(|| file.path().clone());
 5340                    let worktree_path = ProjectPath { worktree_id, path };
 5341                    let abs_path = file.abs_path(cx);
 5342                    let nodes = rebase
 5343                        .walk(
 5344                            worktree_path,
 5345                            language.name(),
 5346                            language.manifest(),
 5347                            delegate.clone(),
 5348                            cx,
 5349                        )
 5350                        .collect::<Vec<_>>();
 5351                    for node in nodes {
 5352                        let server_id = node.server_id_or_init(|disposition| {
 5353                            let path = &disposition.path;
 5354                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5355                            let key = LanguageServerSeed {
 5356                                worktree_id,
 5357                                name: disposition.server_name.clone(),
 5358                                settings: LanguageServerSeedSettings {
 5359                                    binary: disposition.settings.binary.clone(),
 5360                                    initialization_options: disposition
 5361                                        .settings
 5362                                        .initialization_options
 5363                                        .clone(),
 5364                                },
 5365                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5366                                    path.worktree_id,
 5367                                    &path.path,
 5368                                    language.name(),
 5369                                ),
 5370                            };
 5371                            local.language_server_ids.remove(&key);
 5372
 5373                            let server_id = local.get_or_insert_language_server(
 5374                                &worktree,
 5375                                lsp_delegate.clone(),
 5376                                disposition,
 5377                                &language.name(),
 5378                                cx,
 5379                            );
 5380                            if let Some(state) = local.language_servers.get(&server_id)
 5381                                && let Ok(uri) = uri
 5382                            {
 5383                                state.add_workspace_folder(uri);
 5384                            };
 5385                            server_id
 5386                        });
 5387
 5388                        if let Some(language_server_id) = server_id {
 5389                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5390                                language_server_id,
 5391                                name: node.name(),
 5392                                message:
 5393                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5394                                        proto::RegisteredForBuffer {
 5395                                            buffer_abs_path: abs_path
 5396                                                .to_string_lossy()
 5397                                                .into_owned(),
 5398                                            buffer_id: buffer_id.to_proto(),
 5399                                        },
 5400                                    ),
 5401                            });
 5402                        }
 5403                    }
 5404                } else {
 5405                    continue;
 5406                }
 5407            }
 5408            rebase.finish()
 5409        };
 5410        for message in messages_to_report {
 5411            cx.emit(message);
 5412        }
 5413        local.lsp_tree = new_tree;
 5414        for (id, _) in to_stop {
 5415            self.stop_local_language_server(id, cx).detach();
 5416        }
 5417    }
 5418
 5419    pub fn apply_code_action(
 5420        &self,
 5421        buffer_handle: Entity<Buffer>,
 5422        mut action: CodeAction,
 5423        push_to_history: bool,
 5424        cx: &mut Context<Self>,
 5425    ) -> Task<Result<ProjectTransaction>> {
 5426        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5427            let request = proto::ApplyCodeAction {
 5428                project_id,
 5429                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5430                action: Some(Self::serialize_code_action(&action)),
 5431            };
 5432            let buffer_store = self.buffer_store();
 5433            cx.spawn(async move |_, cx| {
 5434                let response = upstream_client
 5435                    .request(request)
 5436                    .await?
 5437                    .transaction
 5438                    .context("missing transaction")?;
 5439
 5440                buffer_store
 5441                    .update(cx, |buffer_store, cx| {
 5442                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5443                    })
 5444                    .await
 5445            })
 5446        } else if self.mode.is_local() {
 5447            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5448                let request_timeout = ProjectSettings::get_global(cx)
 5449                    .global_lsp_settings
 5450                    .get_request_timeout();
 5451                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5452                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5453            }) else {
 5454                return Task::ready(Ok(ProjectTransaction::default()));
 5455            };
 5456
 5457            cx.spawn(async move |this, cx| {
 5458                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5459                    .await
 5460                    .context("resolving a code action")?;
 5461                if let Some(edit) = action.lsp_action.edit()
 5462                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5463                        return LocalLspStore::deserialize_workspace_edit(
 5464                            this.upgrade().context("no app present")?,
 5465                            edit.clone(),
 5466                            push_to_history,
 5467
 5468                            lang_server.clone(),
 5469                            cx,
 5470                        )
 5471                        .await;
 5472                    }
 5473
 5474                let Some(command) = action.lsp_action.command() else {
 5475                    return Ok(ProjectTransaction::default())
 5476                };
 5477
 5478                let server_capabilities = lang_server.capabilities();
 5479                let available_commands = server_capabilities
 5480                    .execute_command_provider
 5481                    .as_ref()
 5482                    .map(|options| options.commands.as_slice())
 5483                    .unwrap_or_default();
 5484
 5485                if !available_commands.contains(&command.command) {
 5486                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5487                    return Ok(ProjectTransaction::default())
 5488                }
 5489
 5490                let request_timeout = cx.update(|app|
 5491                    ProjectSettings::get_global(app)
 5492                    .global_lsp_settings
 5493                    .get_request_timeout()
 5494                );
 5495
 5496                this.update(cx, |this, _| {
 5497                    this.as_local_mut()
 5498                        .unwrap()
 5499                        .last_workspace_edits_by_language_server
 5500                        .remove(&lang_server.server_id());
 5501                })?;
 5502
 5503                let _result = lang_server
 5504                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5505                        command: command.command.clone(),
 5506                        arguments: command.arguments.clone().unwrap_or_default(),
 5507                        ..lsp::ExecuteCommandParams::default()
 5508                    }, request_timeout)
 5509                    .await.into_response()
 5510                    .context("execute command")?;
 5511
 5512                return this.update(cx, |this, _| {
 5513                    this.as_local_mut()
 5514                        .unwrap()
 5515                        .last_workspace_edits_by_language_server
 5516                        .remove(&lang_server.server_id())
 5517                        .unwrap_or_default()
 5518                });
 5519            })
 5520        } else {
 5521            Task::ready(Err(anyhow!("no upstream client and not local")))
 5522        }
 5523    }
 5524
 5525    pub fn apply_code_action_kind(
 5526        &mut self,
 5527        buffers: HashSet<Entity<Buffer>>,
 5528        kind: CodeActionKind,
 5529        push_to_history: bool,
 5530        cx: &mut Context<Self>,
 5531    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5532        if self.as_local().is_some() {
 5533            cx.spawn(async move |lsp_store, cx| {
 5534                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5535                let result = LocalLspStore::execute_code_action_kind_locally(
 5536                    lsp_store.clone(),
 5537                    buffers,
 5538                    kind,
 5539                    push_to_history,
 5540                    cx,
 5541                )
 5542                .await;
 5543                lsp_store.update(cx, |lsp_store, _| {
 5544                    lsp_store.update_last_formatting_failure(&result);
 5545                })?;
 5546                result
 5547            })
 5548        } else if let Some((client, project_id)) = self.upstream_client() {
 5549            let buffer_store = self.buffer_store();
 5550            cx.spawn(async move |lsp_store, cx| {
 5551                let result = client
 5552                    .request(proto::ApplyCodeActionKind {
 5553                        project_id,
 5554                        kind: kind.as_str().to_owned(),
 5555                        buffer_ids: buffers
 5556                            .iter()
 5557                            .map(|buffer| {
 5558                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5559                            })
 5560                            .collect(),
 5561                    })
 5562                    .await
 5563                    .and_then(|result| result.transaction.context("missing transaction"));
 5564                lsp_store.update(cx, |lsp_store, _| {
 5565                    lsp_store.update_last_formatting_failure(&result);
 5566                })?;
 5567
 5568                let transaction_response = result?;
 5569                buffer_store
 5570                    .update(cx, |buffer_store, cx| {
 5571                        buffer_store.deserialize_project_transaction(
 5572                            transaction_response,
 5573                            push_to_history,
 5574                            cx,
 5575                        )
 5576                    })
 5577                    .await
 5578            })
 5579        } else {
 5580            Task::ready(Ok(ProjectTransaction::default()))
 5581        }
 5582    }
 5583
 5584    pub fn resolved_hint(
 5585        &mut self,
 5586        buffer_id: BufferId,
 5587        id: InlayId,
 5588        cx: &mut Context<Self>,
 5589    ) -> Option<ResolvedHint> {
 5590        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5591
 5592        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5593        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5594        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5595        let (server_id, resolve_data) = match &hint.resolve_state {
 5596            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5597            ResolveState::Resolving => {
 5598                return Some(ResolvedHint::Resolving(
 5599                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5600                ));
 5601            }
 5602            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5603        };
 5604
 5605        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5606        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5607        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5608            id,
 5609            cx.spawn(async move |lsp_store, cx| {
 5610                let resolved_hint = resolve_task.await;
 5611                lsp_store
 5612                    .update(cx, |lsp_store, _| {
 5613                        if let Some(old_inlay_hint) = lsp_store
 5614                            .lsp_data
 5615                            .get_mut(&buffer_id)
 5616                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5617                        {
 5618                            match resolved_hint {
 5619                                Ok(resolved_hint) => {
 5620                                    *old_inlay_hint = resolved_hint;
 5621                                }
 5622                                Err(e) => {
 5623                                    old_inlay_hint.resolve_state =
 5624                                        ResolveState::CanResolve(server_id, resolve_data);
 5625                                    log::error!("Inlay hint resolve failed: {e:#}");
 5626                                }
 5627                            }
 5628                        }
 5629                    })
 5630                    .ok();
 5631            })
 5632            .shared(),
 5633        );
 5634        debug_assert!(
 5635            previous_task.is_none(),
 5636            "Did not change hint's resolve state after spawning its resolve"
 5637        );
 5638        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5639        None
 5640    }
 5641
 5642    pub(crate) fn linked_edits(
 5643        &mut self,
 5644        buffer: &Entity<Buffer>,
 5645        position: Anchor,
 5646        cx: &mut Context<Self>,
 5647    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5648        let snapshot = buffer.read(cx).snapshot();
 5649        let scope = snapshot.language_scope_at(position);
 5650        let Some(server_id) = self
 5651            .as_local()
 5652            .and_then(|local| {
 5653                buffer.update(cx, |buffer, cx| {
 5654                    local
 5655                        .language_servers_for_buffer(buffer, cx)
 5656                        .filter(|(_, server)| {
 5657                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5658                        })
 5659                        .filter(|(adapter, _)| {
 5660                            scope
 5661                                .as_ref()
 5662                                .map(|scope| scope.language_allowed(&adapter.name))
 5663                                .unwrap_or(true)
 5664                        })
 5665                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5666                        .next()
 5667                })
 5668            })
 5669            .or_else(|| {
 5670                self.upstream_client()
 5671                    .is_some()
 5672                    .then_some(LanguageServerToQuery::FirstCapable)
 5673            })
 5674            .filter(|_| {
 5675                maybe!({
 5676                    buffer.read(cx).language_at(position)?;
 5677                    Some(
 5678                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5679                            .linked_edits,
 5680                    )
 5681                }) == Some(true)
 5682            })
 5683        else {
 5684            return Task::ready(Ok(Vec::new()));
 5685        };
 5686
 5687        self.request_lsp(
 5688            buffer.clone(),
 5689            server_id,
 5690            LinkedEditingRange { position },
 5691            cx,
 5692        )
 5693    }
 5694
 5695    fn apply_on_type_formatting(
 5696        &mut self,
 5697        buffer: Entity<Buffer>,
 5698        position: Anchor,
 5699        trigger: String,
 5700        cx: &mut Context<Self>,
 5701    ) -> Task<Result<Option<Transaction>>> {
 5702        if let Some((client, project_id)) = self.upstream_client() {
 5703            if !self.check_if_capable_for_proto_request(
 5704                &buffer,
 5705                |capabilities| {
 5706                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5707                },
 5708                cx,
 5709            ) {
 5710                return Task::ready(Ok(None));
 5711            }
 5712            let request = proto::OnTypeFormatting {
 5713                project_id,
 5714                buffer_id: buffer.read(cx).remote_id().into(),
 5715                position: Some(serialize_anchor(&position)),
 5716                trigger,
 5717                version: serialize_version(&buffer.read(cx).version()),
 5718            };
 5719            cx.background_spawn(async move {
 5720                client
 5721                    .request(request)
 5722                    .await?
 5723                    .transaction
 5724                    .map(language::proto::deserialize_transaction)
 5725                    .transpose()
 5726            })
 5727        } else if let Some(local) = self.as_local_mut() {
 5728            let buffer_id = buffer.read(cx).remote_id();
 5729            local.buffers_being_formatted.insert(buffer_id);
 5730            cx.spawn(async move |this, cx| {
 5731                let _cleanup = defer({
 5732                    let this = this.clone();
 5733                    let mut cx = cx.clone();
 5734                    move || {
 5735                        this.update(&mut cx, |this, _| {
 5736                            if let Some(local) = this.as_local_mut() {
 5737                                local.buffers_being_formatted.remove(&buffer_id);
 5738                            }
 5739                        })
 5740                        .ok();
 5741                    }
 5742                });
 5743
 5744                buffer
 5745                    .update(cx, |buffer, _| {
 5746                        buffer.wait_for_edits(Some(position.timestamp()))
 5747                    })
 5748                    .await?;
 5749                this.update(cx, |this, cx| {
 5750                    let position = position.to_point_utf16(buffer.read(cx));
 5751                    this.on_type_format(buffer, position, trigger, false, cx)
 5752                })?
 5753                .await
 5754            })
 5755        } else {
 5756            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5757        }
 5758    }
 5759
 5760    pub fn on_type_format<T: ToPointUtf16>(
 5761        &mut self,
 5762        buffer: Entity<Buffer>,
 5763        position: T,
 5764        trigger: String,
 5765        push_to_history: bool,
 5766        cx: &mut Context<Self>,
 5767    ) -> Task<Result<Option<Transaction>>> {
 5768        let position = position.to_point_utf16(buffer.read(cx));
 5769        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5770    }
 5771
 5772    fn on_type_format_impl(
 5773        &mut self,
 5774        buffer: Entity<Buffer>,
 5775        position: PointUtf16,
 5776        trigger: String,
 5777        push_to_history: bool,
 5778        cx: &mut Context<Self>,
 5779    ) -> Task<Result<Option<Transaction>>> {
 5780        let options = buffer.update(cx, |buffer, cx| {
 5781            lsp_command::lsp_formatting_options(
 5782                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5783            )
 5784        });
 5785
 5786        cx.spawn(async move |this, cx| {
 5787            if let Some(waiter) =
 5788                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5789            {
 5790                waiter.await?;
 5791            }
 5792            cx.update(|cx| {
 5793                this.update(cx, |this, cx| {
 5794                    this.request_lsp(
 5795                        buffer.clone(),
 5796                        LanguageServerToQuery::FirstCapable,
 5797                        OnTypeFormatting {
 5798                            position,
 5799                            trigger,
 5800                            options,
 5801                            push_to_history,
 5802                        },
 5803                        cx,
 5804                    )
 5805                })
 5806            })?
 5807            .await
 5808        })
 5809    }
 5810
 5811    pub fn definitions(
 5812        &mut self,
 5813        buffer: &Entity<Buffer>,
 5814        position: PointUtf16,
 5815        cx: &mut Context<Self>,
 5816    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5817        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5818            let request = GetDefinitions { position };
 5819            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5820                return Task::ready(Ok(None));
 5821            }
 5822
 5823            let request_timeout = ProjectSettings::get_global(cx)
 5824                .global_lsp_settings
 5825                .get_request_timeout();
 5826
 5827            let request_task = upstream_client.request_lsp(
 5828                project_id,
 5829                None,
 5830                request_timeout,
 5831                cx.background_executor().clone(),
 5832                request.to_proto(project_id, buffer.read(cx)),
 5833            );
 5834            let buffer = buffer.clone();
 5835            cx.spawn(async move |weak_lsp_store, cx| {
 5836                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5837                    return Ok(None);
 5838                };
 5839                let Some(responses) = request_task.await? else {
 5840                    return Ok(None);
 5841                };
 5842                let actions = join_all(responses.payload.into_iter().map(|response| {
 5843                    GetDefinitions { position }.response_from_proto(
 5844                        response.response,
 5845                        lsp_store.clone(),
 5846                        buffer.clone(),
 5847                        cx.clone(),
 5848                    )
 5849                }))
 5850                .await;
 5851
 5852                Ok(Some(
 5853                    actions
 5854                        .into_iter()
 5855                        .collect::<Result<Vec<Vec<_>>>>()?
 5856                        .into_iter()
 5857                        .flatten()
 5858                        .dedup()
 5859                        .collect(),
 5860                ))
 5861            })
 5862        } else {
 5863            let definitions_task = self.request_multiple_lsp_locally(
 5864                buffer,
 5865                Some(position),
 5866                GetDefinitions { position },
 5867                cx,
 5868            );
 5869            cx.background_spawn(async move {
 5870                Ok(Some(
 5871                    definitions_task
 5872                        .await
 5873                        .into_iter()
 5874                        .flat_map(|(_, definitions)| definitions)
 5875                        .dedup()
 5876                        .collect(),
 5877                ))
 5878            })
 5879        }
 5880    }
 5881
 5882    pub fn declarations(
 5883        &mut self,
 5884        buffer: &Entity<Buffer>,
 5885        position: PointUtf16,
 5886        cx: &mut Context<Self>,
 5887    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5888        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5889            let request = GetDeclarations { position };
 5890            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5891                return Task::ready(Ok(None));
 5892            }
 5893            let request_timeout = ProjectSettings::get_global(cx)
 5894                .global_lsp_settings
 5895                .get_request_timeout();
 5896            let request_task = upstream_client.request_lsp(
 5897                project_id,
 5898                None,
 5899                request_timeout,
 5900                cx.background_executor().clone(),
 5901                request.to_proto(project_id, buffer.read(cx)),
 5902            );
 5903            let buffer = buffer.clone();
 5904            cx.spawn(async move |weak_lsp_store, cx| {
 5905                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5906                    return Ok(None);
 5907                };
 5908                let Some(responses) = request_task.await? else {
 5909                    return Ok(None);
 5910                };
 5911                let actions = join_all(responses.payload.into_iter().map(|response| {
 5912                    GetDeclarations { position }.response_from_proto(
 5913                        response.response,
 5914                        lsp_store.clone(),
 5915                        buffer.clone(),
 5916                        cx.clone(),
 5917                    )
 5918                }))
 5919                .await;
 5920
 5921                Ok(Some(
 5922                    actions
 5923                        .into_iter()
 5924                        .collect::<Result<Vec<Vec<_>>>>()?
 5925                        .into_iter()
 5926                        .flatten()
 5927                        .dedup()
 5928                        .collect(),
 5929                ))
 5930            })
 5931        } else {
 5932            let declarations_task = self.request_multiple_lsp_locally(
 5933                buffer,
 5934                Some(position),
 5935                GetDeclarations { position },
 5936                cx,
 5937            );
 5938            cx.background_spawn(async move {
 5939                Ok(Some(
 5940                    declarations_task
 5941                        .await
 5942                        .into_iter()
 5943                        .flat_map(|(_, declarations)| declarations)
 5944                        .dedup()
 5945                        .collect(),
 5946                ))
 5947            })
 5948        }
 5949    }
 5950
 5951    pub fn type_definitions(
 5952        &mut self,
 5953        buffer: &Entity<Buffer>,
 5954        position: PointUtf16,
 5955        cx: &mut Context<Self>,
 5956    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5957        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5958            let request = GetTypeDefinitions { position };
 5959            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5960                return Task::ready(Ok(None));
 5961            }
 5962            let request_timeout = ProjectSettings::get_global(cx)
 5963                .global_lsp_settings
 5964                .get_request_timeout();
 5965            let request_task = upstream_client.request_lsp(
 5966                project_id,
 5967                None,
 5968                request_timeout,
 5969                cx.background_executor().clone(),
 5970                request.to_proto(project_id, buffer.read(cx)),
 5971            );
 5972            let buffer = buffer.clone();
 5973            cx.spawn(async move |weak_lsp_store, cx| {
 5974                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5975                    return Ok(None);
 5976                };
 5977                let Some(responses) = request_task.await? else {
 5978                    return Ok(None);
 5979                };
 5980                let actions = join_all(responses.payload.into_iter().map(|response| {
 5981                    GetTypeDefinitions { position }.response_from_proto(
 5982                        response.response,
 5983                        lsp_store.clone(),
 5984                        buffer.clone(),
 5985                        cx.clone(),
 5986                    )
 5987                }))
 5988                .await;
 5989
 5990                Ok(Some(
 5991                    actions
 5992                        .into_iter()
 5993                        .collect::<Result<Vec<Vec<_>>>>()?
 5994                        .into_iter()
 5995                        .flatten()
 5996                        .dedup()
 5997                        .collect(),
 5998                ))
 5999            })
 6000        } else {
 6001            let type_definitions_task = self.request_multiple_lsp_locally(
 6002                buffer,
 6003                Some(position),
 6004                GetTypeDefinitions { position },
 6005                cx,
 6006            );
 6007            cx.background_spawn(async move {
 6008                Ok(Some(
 6009                    type_definitions_task
 6010                        .await
 6011                        .into_iter()
 6012                        .flat_map(|(_, type_definitions)| type_definitions)
 6013                        .dedup()
 6014                        .collect(),
 6015                ))
 6016            })
 6017        }
 6018    }
 6019
 6020    pub fn implementations(
 6021        &mut self,
 6022        buffer: &Entity<Buffer>,
 6023        position: PointUtf16,
 6024        cx: &mut Context<Self>,
 6025    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6026        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6027            let request = GetImplementations { position };
 6028            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6029                return Task::ready(Ok(None));
 6030            }
 6031
 6032            let request_timeout = ProjectSettings::get_global(cx)
 6033                .global_lsp_settings
 6034                .get_request_timeout();
 6035            let request_task = upstream_client.request_lsp(
 6036                project_id,
 6037                None,
 6038                request_timeout,
 6039                cx.background_executor().clone(),
 6040                request.to_proto(project_id, buffer.read(cx)),
 6041            );
 6042            let buffer = buffer.clone();
 6043            cx.spawn(async move |weak_lsp_store, cx| {
 6044                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6045                    return Ok(None);
 6046                };
 6047                let Some(responses) = request_task.await? else {
 6048                    return Ok(None);
 6049                };
 6050                let actions = join_all(responses.payload.into_iter().map(|response| {
 6051                    GetImplementations { position }.response_from_proto(
 6052                        response.response,
 6053                        lsp_store.clone(),
 6054                        buffer.clone(),
 6055                        cx.clone(),
 6056                    )
 6057                }))
 6058                .await;
 6059
 6060                Ok(Some(
 6061                    actions
 6062                        .into_iter()
 6063                        .collect::<Result<Vec<Vec<_>>>>()?
 6064                        .into_iter()
 6065                        .flatten()
 6066                        .dedup()
 6067                        .collect(),
 6068                ))
 6069            })
 6070        } else {
 6071            let implementations_task = self.request_multiple_lsp_locally(
 6072                buffer,
 6073                Some(position),
 6074                GetImplementations { position },
 6075                cx,
 6076            );
 6077            cx.background_spawn(async move {
 6078                Ok(Some(
 6079                    implementations_task
 6080                        .await
 6081                        .into_iter()
 6082                        .flat_map(|(_, implementations)| implementations)
 6083                        .dedup()
 6084                        .collect(),
 6085                ))
 6086            })
 6087        }
 6088    }
 6089
 6090    pub fn references(
 6091        &mut self,
 6092        buffer: &Entity<Buffer>,
 6093        position: PointUtf16,
 6094        cx: &mut Context<Self>,
 6095    ) -> Task<Result<Option<Vec<Location>>>> {
 6096        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6097            let request = GetReferences { position };
 6098            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6099                return Task::ready(Ok(None));
 6100            }
 6101
 6102            let request_timeout = ProjectSettings::get_global(cx)
 6103                .global_lsp_settings
 6104                .get_request_timeout();
 6105            let request_task = upstream_client.request_lsp(
 6106                project_id,
 6107                None,
 6108                request_timeout,
 6109                cx.background_executor().clone(),
 6110                request.to_proto(project_id, buffer.read(cx)),
 6111            );
 6112            let buffer = buffer.clone();
 6113            cx.spawn(async move |weak_lsp_store, cx| {
 6114                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6115                    return Ok(None);
 6116                };
 6117                let Some(responses) = request_task.await? else {
 6118                    return Ok(None);
 6119                };
 6120
 6121                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6122                    GetReferences { position }.response_from_proto(
 6123                        lsp_response.response,
 6124                        lsp_store.clone(),
 6125                        buffer.clone(),
 6126                        cx.clone(),
 6127                    )
 6128                }))
 6129                .await
 6130                .into_iter()
 6131                .collect::<Result<Vec<Vec<_>>>>()?
 6132                .into_iter()
 6133                .flatten()
 6134                .dedup()
 6135                .collect();
 6136                Ok(Some(locations))
 6137            })
 6138        } else {
 6139            let references_task = self.request_multiple_lsp_locally(
 6140                buffer,
 6141                Some(position),
 6142                GetReferences { position },
 6143                cx,
 6144            );
 6145            cx.background_spawn(async move {
 6146                Ok(Some(
 6147                    references_task
 6148                        .await
 6149                        .into_iter()
 6150                        .flat_map(|(_, references)| references)
 6151                        .dedup()
 6152                        .collect(),
 6153                ))
 6154            })
 6155        }
 6156    }
 6157
 6158    pub fn code_actions(
 6159        &mut self,
 6160        buffer: &Entity<Buffer>,
 6161        range: Range<Anchor>,
 6162        kinds: Option<Vec<CodeActionKind>>,
 6163        cx: &mut Context<Self>,
 6164    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6165        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6166            let request = GetCodeActions {
 6167                range: range.clone(),
 6168                kinds: kinds.clone(),
 6169            };
 6170            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6171                return Task::ready(Ok(None));
 6172            }
 6173            let request_timeout = ProjectSettings::get_global(cx)
 6174                .global_lsp_settings
 6175                .get_request_timeout();
 6176            let request_task = upstream_client.request_lsp(
 6177                project_id,
 6178                None,
 6179                request_timeout,
 6180                cx.background_executor().clone(),
 6181                request.to_proto(project_id, buffer.read(cx)),
 6182            );
 6183            let buffer = buffer.clone();
 6184            cx.spawn(async move |weak_lsp_store, cx| {
 6185                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6186                    return Ok(None);
 6187                };
 6188                let Some(responses) = request_task.await? else {
 6189                    return Ok(None);
 6190                };
 6191                let actions = join_all(responses.payload.into_iter().map(|response| {
 6192                    GetCodeActions {
 6193                        range: range.clone(),
 6194                        kinds: kinds.clone(),
 6195                    }
 6196                    .response_from_proto(
 6197                        response.response,
 6198                        lsp_store.clone(),
 6199                        buffer.clone(),
 6200                        cx.clone(),
 6201                    )
 6202                }))
 6203                .await;
 6204
 6205                Ok(Some(
 6206                    actions
 6207                        .into_iter()
 6208                        .collect::<Result<Vec<Vec<_>>>>()?
 6209                        .into_iter()
 6210                        .flatten()
 6211                        .collect(),
 6212                ))
 6213            })
 6214        } else {
 6215            let all_actions_task = self.request_multiple_lsp_locally(
 6216                buffer,
 6217                Some(range.start),
 6218                GetCodeActions { range, kinds },
 6219                cx,
 6220            );
 6221            cx.background_spawn(async move {
 6222                Ok(Some(
 6223                    all_actions_task
 6224                        .await
 6225                        .into_iter()
 6226                        .flat_map(|(_, actions)| actions)
 6227                        .collect(),
 6228                ))
 6229            })
 6230        }
 6231    }
 6232
 6233    #[inline(never)]
 6234    pub fn completions(
 6235        &self,
 6236        buffer: &Entity<Buffer>,
 6237        position: PointUtf16,
 6238        context: CompletionContext,
 6239        cx: &mut Context<Self>,
 6240    ) -> Task<Result<Vec<CompletionResponse>>> {
 6241        let language_registry = self.languages.clone();
 6242
 6243        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6244            let snapshot = buffer.read(cx).snapshot();
 6245            let offset = position.to_offset(&snapshot);
 6246            let scope = snapshot.language_scope_at(offset);
 6247            let capable_lsps = self.all_capable_for_proto_request(
 6248                buffer,
 6249                |server_name, capabilities| {
 6250                    capabilities.completion_provider.is_some()
 6251                        && scope
 6252                            .as_ref()
 6253                            .map(|scope| scope.language_allowed(server_name))
 6254                            .unwrap_or(true)
 6255                },
 6256                cx,
 6257            );
 6258            if capable_lsps.is_empty() {
 6259                return Task::ready(Ok(Vec::new()));
 6260            }
 6261
 6262            let language = buffer.read(cx).language().cloned();
 6263
 6264            let buffer = buffer.clone();
 6265
 6266            cx.spawn(async move |this, cx| {
 6267                let requests = join_all(
 6268                    capable_lsps
 6269                        .into_iter()
 6270                        .map(|(id, server_name)| {
 6271                            let request = GetCompletions {
 6272                                position,
 6273                                context: context.clone(),
 6274                                server_id: Some(id),
 6275                            };
 6276                            let buffer = buffer.clone();
 6277                            let language = language.clone();
 6278                            let lsp_adapter = language.as_ref().and_then(|language| {
 6279                                let adapters = language_registry.lsp_adapters(&language.name());
 6280                                adapters
 6281                                    .iter()
 6282                                    .find(|adapter| adapter.name() == server_name)
 6283                                    .or_else(|| adapters.first())
 6284                                    .cloned()
 6285                            });
 6286                            let upstream_client = upstream_client.clone();
 6287                            let response = this
 6288                                .update(cx, |this, cx| {
 6289                                    this.send_lsp_proto_request(
 6290                                        buffer,
 6291                                        upstream_client,
 6292                                        project_id,
 6293                                        request,
 6294                                        cx,
 6295                                    )
 6296                                })
 6297                                .log_err();
 6298                            async move {
 6299                                let response = response?.await.log_err()?;
 6300
 6301                                let completions = populate_labels_for_completions(
 6302                                    response.completions,
 6303                                    language,
 6304                                    lsp_adapter,
 6305                                )
 6306                                .await;
 6307
 6308                                Some(CompletionResponse {
 6309                                    completions,
 6310                                    display_options: CompletionDisplayOptions::default(),
 6311                                    is_incomplete: response.is_incomplete,
 6312                                })
 6313                            }
 6314                        })
 6315                        .collect::<Vec<_>>(),
 6316                );
 6317                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6318            })
 6319        } else if let Some(local) = self.as_local() {
 6320            let snapshot = buffer.read(cx).snapshot();
 6321            let offset = position.to_offset(&snapshot);
 6322            let scope = snapshot.language_scope_at(offset);
 6323            let language = snapshot.language().cloned();
 6324            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6325                .completions
 6326                .clone();
 6327            if !completion_settings.lsp {
 6328                return Task::ready(Ok(Vec::new()));
 6329            }
 6330
 6331            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6332                local
 6333                    .language_servers_for_buffer(buffer, cx)
 6334                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6335                    .filter(|(adapter, _)| {
 6336                        scope
 6337                            .as_ref()
 6338                            .map(|scope| scope.language_allowed(&adapter.name))
 6339                            .unwrap_or(true)
 6340                    })
 6341                    .map(|(_, server)| server.server_id())
 6342                    .collect()
 6343            });
 6344
 6345            let buffer = buffer.clone();
 6346            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6347            let lsp_timeout = if lsp_timeout > 0 {
 6348                Some(Duration::from_millis(lsp_timeout))
 6349            } else {
 6350                None
 6351            };
 6352            cx.spawn(async move |this,  cx| {
 6353                let mut tasks = Vec::with_capacity(server_ids.len());
 6354                this.update(cx, |lsp_store, cx| {
 6355                    for server_id in server_ids {
 6356                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6357                        let lsp_timeout = lsp_timeout
 6358                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6359                        let mut timeout = cx.background_spawn(async move {
 6360                            match lsp_timeout {
 6361                                Some(lsp_timeout) => {
 6362                                    lsp_timeout.await;
 6363                                    true
 6364                                },
 6365                                None => false,
 6366                            }
 6367                        }).fuse();
 6368                        let mut lsp_request = lsp_store.request_lsp(
 6369                            buffer.clone(),
 6370                            LanguageServerToQuery::Other(server_id),
 6371                            GetCompletions {
 6372                                position,
 6373                                context: context.clone(),
 6374                                server_id: Some(server_id),
 6375                            },
 6376                            cx,
 6377                        ).fuse();
 6378                        let new_task = cx.background_spawn(async move {
 6379                            select_biased! {
 6380                                response = lsp_request => anyhow::Ok(Some(response?)),
 6381                                timeout_happened = timeout => {
 6382                                    if timeout_happened {
 6383                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6384                                        Ok(None)
 6385                                    } else {
 6386                                        let completions = lsp_request.await?;
 6387                                        Ok(Some(completions))
 6388                                    }
 6389                                },
 6390                            }
 6391                        });
 6392                        tasks.push((lsp_adapter, new_task));
 6393                    }
 6394                })?;
 6395
 6396                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6397                    let completion_response = task.await.ok()??;
 6398                    let completions = populate_labels_for_completions(
 6399                            completion_response.completions,
 6400                            language.clone(),
 6401                            lsp_adapter,
 6402                        )
 6403                        .await;
 6404                    Some(CompletionResponse {
 6405                        completions,
 6406                        display_options: CompletionDisplayOptions::default(),
 6407                        is_incomplete: completion_response.is_incomplete,
 6408                    })
 6409                });
 6410
 6411                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6412
 6413                Ok(responses.into_iter().flatten().collect())
 6414            })
 6415        } else {
 6416            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6417        }
 6418    }
 6419
 6420    pub fn resolve_completions(
 6421        &self,
 6422        buffer: Entity<Buffer>,
 6423        completion_indices: Vec<usize>,
 6424        completions: Rc<RefCell<Box<[Completion]>>>,
 6425        cx: &mut Context<Self>,
 6426    ) -> Task<Result<bool>> {
 6427        let client = self.upstream_client();
 6428        let buffer_id = buffer.read(cx).remote_id();
 6429        let buffer_snapshot = buffer.read(cx).snapshot();
 6430
 6431        if !self.check_if_capable_for_proto_request(
 6432            &buffer,
 6433            GetCompletions::can_resolve_completions,
 6434            cx,
 6435        ) {
 6436            return Task::ready(Ok(false));
 6437        }
 6438        cx.spawn(async move |lsp_store, cx| {
 6439            let request_timeout = cx.update(|app| {
 6440                ProjectSettings::get_global(app)
 6441                    .global_lsp_settings
 6442                    .get_request_timeout()
 6443            });
 6444
 6445            let mut did_resolve = false;
 6446            if let Some((client, project_id)) = client {
 6447                for completion_index in completion_indices {
 6448                    let server_id = {
 6449                        let completion = &completions.borrow()[completion_index];
 6450                        completion.source.server_id()
 6451                    };
 6452                    if let Some(server_id) = server_id {
 6453                        if Self::resolve_completion_remote(
 6454                            project_id,
 6455                            server_id,
 6456                            buffer_id,
 6457                            completions.clone(),
 6458                            completion_index,
 6459                            client.clone(),
 6460                        )
 6461                        .await
 6462                        .log_err()
 6463                        .is_some()
 6464                        {
 6465                            did_resolve = true;
 6466                        }
 6467                    } else {
 6468                        resolve_word_completion(
 6469                            &buffer_snapshot,
 6470                            &mut completions.borrow_mut()[completion_index],
 6471                        );
 6472                    }
 6473                }
 6474            } else {
 6475                for completion_index in completion_indices {
 6476                    let server_id = {
 6477                        let completion = &completions.borrow()[completion_index];
 6478                        completion.source.server_id()
 6479                    };
 6480                    if let Some(server_id) = server_id {
 6481                        let server_and_adapter = lsp_store
 6482                            .read_with(cx, |lsp_store, _| {
 6483                                let server = lsp_store.language_server_for_id(server_id)?;
 6484                                let adapter =
 6485                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6486                                Some((server, adapter))
 6487                            })
 6488                            .ok()
 6489                            .flatten();
 6490                        let Some((server, adapter)) = server_and_adapter else {
 6491                            continue;
 6492                        };
 6493
 6494                        let resolved = Self::resolve_completion_local(
 6495                            server,
 6496                            completions.clone(),
 6497                            completion_index,
 6498                            request_timeout,
 6499                        )
 6500                        .await
 6501                        .log_err()
 6502                        .is_some();
 6503                        if resolved {
 6504                            Self::regenerate_completion_labels(
 6505                                adapter,
 6506                                &buffer_snapshot,
 6507                                completions.clone(),
 6508                                completion_index,
 6509                            )
 6510                            .await
 6511                            .log_err();
 6512                            did_resolve = true;
 6513                        }
 6514                    } else {
 6515                        resolve_word_completion(
 6516                            &buffer_snapshot,
 6517                            &mut completions.borrow_mut()[completion_index],
 6518                        );
 6519                    }
 6520                }
 6521            }
 6522
 6523            Ok(did_resolve)
 6524        })
 6525    }
 6526
 6527    async fn resolve_completion_local(
 6528        server: Arc<lsp::LanguageServer>,
 6529        completions: Rc<RefCell<Box<[Completion]>>>,
 6530        completion_index: usize,
 6531        request_timeout: Duration,
 6532    ) -> Result<()> {
 6533        let server_id = server.server_id();
 6534        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6535            return Ok(());
 6536        }
 6537
 6538        let request = {
 6539            let completion = &completions.borrow()[completion_index];
 6540            match &completion.source {
 6541                CompletionSource::Lsp {
 6542                    lsp_completion,
 6543                    resolved,
 6544                    server_id: completion_server_id,
 6545                    ..
 6546                } => {
 6547                    if *resolved {
 6548                        return Ok(());
 6549                    }
 6550                    anyhow::ensure!(
 6551                        server_id == *completion_server_id,
 6552                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6553                    );
 6554                    server.request::<lsp::request::ResolveCompletionItem>(
 6555                        *lsp_completion.clone(),
 6556                        request_timeout,
 6557                    )
 6558                }
 6559                CompletionSource::BufferWord { .. }
 6560                | CompletionSource::Dap { .. }
 6561                | CompletionSource::Custom => {
 6562                    return Ok(());
 6563                }
 6564            }
 6565        };
 6566        let resolved_completion = request
 6567            .await
 6568            .into_response()
 6569            .context("resolve completion")?;
 6570
 6571        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6572        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6573
 6574        let mut completions = completions.borrow_mut();
 6575        let completion = &mut completions[completion_index];
 6576        if let CompletionSource::Lsp {
 6577            lsp_completion,
 6578            resolved,
 6579            server_id: completion_server_id,
 6580            ..
 6581        } = &mut completion.source
 6582        {
 6583            if *resolved {
 6584                return Ok(());
 6585            }
 6586            anyhow::ensure!(
 6587                server_id == *completion_server_id,
 6588                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6589            );
 6590            **lsp_completion = resolved_completion;
 6591            *resolved = true;
 6592        }
 6593        Ok(())
 6594    }
 6595
 6596    async fn regenerate_completion_labels(
 6597        adapter: Arc<CachedLspAdapter>,
 6598        snapshot: &BufferSnapshot,
 6599        completions: Rc<RefCell<Box<[Completion]>>>,
 6600        completion_index: usize,
 6601    ) -> Result<()> {
 6602        let completion_item = completions.borrow()[completion_index]
 6603            .source
 6604            .lsp_completion(true)
 6605            .map(Cow::into_owned);
 6606        if let Some(lsp_documentation) = completion_item
 6607            .as_ref()
 6608            .and_then(|completion_item| completion_item.documentation.clone())
 6609        {
 6610            let mut completions = completions.borrow_mut();
 6611            let completion = &mut completions[completion_index];
 6612            completion.documentation = Some(lsp_documentation.into());
 6613        } else {
 6614            let mut completions = completions.borrow_mut();
 6615            let completion = &mut completions[completion_index];
 6616            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6617        }
 6618
 6619        let mut new_label = match completion_item {
 6620            Some(completion_item) => {
 6621                // Some language servers always return `detail` lazily via resolve, regardless of
 6622                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6623                // See: https://github.com/yioneko/vtsls/issues/213
 6624                let language = snapshot.language();
 6625                match language {
 6626                    Some(language) => {
 6627                        adapter
 6628                            .labels_for_completions(
 6629                                std::slice::from_ref(&completion_item),
 6630                                language,
 6631                            )
 6632                            .await?
 6633                    }
 6634                    None => Vec::new(),
 6635                }
 6636                .pop()
 6637                .flatten()
 6638                .unwrap_or_else(|| {
 6639                    CodeLabel::fallback_for_completion(
 6640                        &completion_item,
 6641                        language.map(|language| language.as_ref()),
 6642                    )
 6643                })
 6644            }
 6645            None => CodeLabel::plain(
 6646                completions.borrow()[completion_index].new_text.clone(),
 6647                None,
 6648            ),
 6649        };
 6650        ensure_uniform_list_compatible_label(&mut new_label);
 6651
 6652        let mut completions = completions.borrow_mut();
 6653        let completion = &mut completions[completion_index];
 6654        if completion.label.filter_text() == new_label.filter_text() {
 6655            completion.label = new_label;
 6656        } else {
 6657            log::error!(
 6658                "Resolved completion changed display label from {} to {}. \
 6659                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6660                completion.label.text(),
 6661                new_label.text(),
 6662                completion.label.filter_text(),
 6663                new_label.filter_text()
 6664            );
 6665        }
 6666
 6667        Ok(())
 6668    }
 6669
 6670    async fn resolve_completion_remote(
 6671        project_id: u64,
 6672        server_id: LanguageServerId,
 6673        buffer_id: BufferId,
 6674        completions: Rc<RefCell<Box<[Completion]>>>,
 6675        completion_index: usize,
 6676        client: AnyProtoClient,
 6677    ) -> Result<()> {
 6678        let lsp_completion = {
 6679            let completion = &completions.borrow()[completion_index];
 6680            match &completion.source {
 6681                CompletionSource::Lsp {
 6682                    lsp_completion,
 6683                    resolved,
 6684                    server_id: completion_server_id,
 6685                    ..
 6686                } => {
 6687                    anyhow::ensure!(
 6688                        server_id == *completion_server_id,
 6689                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6690                    );
 6691                    if *resolved {
 6692                        return Ok(());
 6693                    }
 6694                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6695                }
 6696                CompletionSource::Custom
 6697                | CompletionSource::Dap { .. }
 6698                | CompletionSource::BufferWord { .. } => {
 6699                    return Ok(());
 6700                }
 6701            }
 6702        };
 6703        let request = proto::ResolveCompletionDocumentation {
 6704            project_id,
 6705            language_server_id: server_id.0 as u64,
 6706            lsp_completion,
 6707            buffer_id: buffer_id.into(),
 6708        };
 6709
 6710        let response = client
 6711            .request(request)
 6712            .await
 6713            .context("completion documentation resolve proto request")?;
 6714        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6715
 6716        let documentation = if response.documentation.is_empty() {
 6717            CompletionDocumentation::Undocumented
 6718        } else if response.documentation_is_markdown {
 6719            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6720        } else if response.documentation.lines().count() <= 1 {
 6721            CompletionDocumentation::SingleLine(response.documentation.into())
 6722        } else {
 6723            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6724        };
 6725
 6726        let mut completions = completions.borrow_mut();
 6727        let completion = &mut completions[completion_index];
 6728        completion.documentation = Some(documentation);
 6729        if let CompletionSource::Lsp {
 6730            insert_range,
 6731            lsp_completion,
 6732            resolved,
 6733            server_id: completion_server_id,
 6734            lsp_defaults: _,
 6735        } = &mut completion.source
 6736        {
 6737            let completion_insert_range = response
 6738                .old_insert_start
 6739                .and_then(deserialize_anchor)
 6740                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6741            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6742
 6743            if *resolved {
 6744                return Ok(());
 6745            }
 6746            anyhow::ensure!(
 6747                server_id == *completion_server_id,
 6748                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6749            );
 6750            **lsp_completion = resolved_lsp_completion;
 6751            *resolved = true;
 6752        }
 6753
 6754        let replace_range = response
 6755            .old_replace_start
 6756            .and_then(deserialize_anchor)
 6757            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6758        if let Some((old_replace_start, old_replace_end)) = replace_range
 6759            && !response.new_text.is_empty()
 6760        {
 6761            completion.new_text = response.new_text;
 6762            completion.replace_range = old_replace_start..old_replace_end;
 6763        }
 6764
 6765        Ok(())
 6766    }
 6767
 6768    pub fn apply_additional_edits_for_completion(
 6769        &self,
 6770        buffer_handle: Entity<Buffer>,
 6771        completions: Rc<RefCell<Box<[Completion]>>>,
 6772        completion_index: usize,
 6773        push_to_history: bool,
 6774        all_commit_ranges: Vec<Range<language::Anchor>>,
 6775        cx: &mut Context<Self>,
 6776    ) -> Task<Result<Option<Transaction>>> {
 6777        if let Some((client, project_id)) = self.upstream_client() {
 6778            let buffer = buffer_handle.read(cx);
 6779            let buffer_id = buffer.remote_id();
 6780            cx.spawn(async move |_, cx| {
 6781                let request = {
 6782                    let completion = completions.borrow()[completion_index].clone();
 6783                    proto::ApplyCompletionAdditionalEdits {
 6784                        project_id,
 6785                        buffer_id: buffer_id.into(),
 6786                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6787                            replace_range: completion.replace_range,
 6788                            new_text: completion.new_text,
 6789                            source: completion.source,
 6790                        })),
 6791                        all_commit_ranges: all_commit_ranges
 6792                            .iter()
 6793                            .cloned()
 6794                            .map(language::proto::serialize_anchor_range)
 6795                            .collect(),
 6796                    }
 6797                };
 6798
 6799                let Some(transaction) = client.request(request).await?.transaction else {
 6800                    return Ok(None);
 6801                };
 6802
 6803                let transaction = language::proto::deserialize_transaction(transaction)?;
 6804                buffer_handle
 6805                    .update(cx, |buffer, _| {
 6806                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6807                    })
 6808                    .await?;
 6809                if push_to_history {
 6810                    buffer_handle.update(cx, |buffer, _| {
 6811                        buffer.push_transaction(transaction.clone(), Instant::now());
 6812                        buffer.finalize_last_transaction();
 6813                    });
 6814                }
 6815                Ok(Some(transaction))
 6816            })
 6817        } else {
 6818            let request_timeout = ProjectSettings::get_global(cx)
 6819                .global_lsp_settings
 6820                .get_request_timeout();
 6821
 6822            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6823                let completion = &completions.borrow()[completion_index];
 6824                let server_id = completion.source.server_id()?;
 6825                Some(
 6826                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6827                        .1
 6828                        .clone(),
 6829                )
 6830            }) else {
 6831                return Task::ready(Ok(None));
 6832            };
 6833
 6834            cx.spawn(async move |this, cx| {
 6835                Self::resolve_completion_local(
 6836                    server.clone(),
 6837                    completions.clone(),
 6838                    completion_index,
 6839                    request_timeout,
 6840                )
 6841                .await
 6842                .context("resolving completion")?;
 6843                let completion = completions.borrow()[completion_index].clone();
 6844                let additional_text_edits = completion
 6845                    .source
 6846                    .lsp_completion(true)
 6847                    .as_ref()
 6848                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6849                if let Some(edits) = additional_text_edits {
 6850                    let edits = this
 6851                        .update(cx, |this, cx| {
 6852                            this.as_local_mut().unwrap().edits_from_lsp(
 6853                                &buffer_handle,
 6854                                edits,
 6855                                server.server_id(),
 6856                                None,
 6857                                cx,
 6858                            )
 6859                        })?
 6860                        .await?;
 6861
 6862                    buffer_handle.update(cx, |buffer, cx| {
 6863                        buffer.finalize_last_transaction();
 6864                        buffer.start_transaction();
 6865
 6866                        for (range, text) in edits {
 6867                            let primary = &completion.replace_range;
 6868
 6869                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6870                            // and the primary completion is just an insertion (empty range), then this is likely
 6871                            // an auto-import scenario and should not be considered overlapping
 6872                            // https://github.com/zed-industries/zed/issues/26136
 6873                            let is_file_start_auto_import = {
 6874                                let snapshot = buffer.snapshot();
 6875                                let primary_start_point = primary.start.to_point(&snapshot);
 6876                                let range_start_point = range.start.to_point(&snapshot);
 6877
 6878                                let result = primary_start_point.row == 0
 6879                                    && primary_start_point.column == 0
 6880                                    && range_start_point.row == 0
 6881                                    && range_start_point.column == 0;
 6882
 6883                                result
 6884                            };
 6885
 6886                            let has_overlap = if is_file_start_auto_import {
 6887                                false
 6888                            } else {
 6889                                all_commit_ranges.iter().any(|commit_range| {
 6890                                    let start_within =
 6891                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6892                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6893                                    let end_within =
 6894                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6895                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6896                                    start_within || end_within
 6897                                })
 6898                            };
 6899
 6900                            //Skip additional edits which overlap with the primary completion edit
 6901                            //https://github.com/zed-industries/zed/pull/1871
 6902                            if !has_overlap {
 6903                                buffer.edit([(range, text)], None, cx);
 6904                            }
 6905                        }
 6906
 6907                        let transaction = if buffer.end_transaction(cx).is_some() {
 6908                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6909                            if !push_to_history {
 6910                                buffer.forget_transaction(transaction.id);
 6911                            }
 6912                            Some(transaction)
 6913                        } else {
 6914                            None
 6915                        };
 6916                        Ok(transaction)
 6917                    })
 6918                } else {
 6919                    Ok(None)
 6920                }
 6921            })
 6922        }
 6923    }
 6924
 6925    pub fn pull_diagnostics(
 6926        &mut self,
 6927        buffer: Entity<Buffer>,
 6928        cx: &mut Context<Self>,
 6929    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6930        let buffer_id = buffer.read(cx).remote_id();
 6931
 6932        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6933            let mut suitable_capabilities = None;
 6934            // Are we capable for proto request?
 6935            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6936                &buffer,
 6937                |capabilities| {
 6938                    if let Some(caps) = &capabilities.diagnostic_provider {
 6939                        suitable_capabilities = Some(caps.clone());
 6940                        true
 6941                    } else {
 6942                        false
 6943                    }
 6944                },
 6945                cx,
 6946            );
 6947            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6948            let Some(dynamic_caps) = suitable_capabilities else {
 6949                return Task::ready(Ok(None));
 6950            };
 6951            assert!(any_server_has_diagnostics_provider);
 6952
 6953            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6954            let request = GetDocumentDiagnostics {
 6955                previous_result_id: None,
 6956                identifier,
 6957                registration_id: None,
 6958            };
 6959            let request_timeout = ProjectSettings::get_global(cx)
 6960                .global_lsp_settings
 6961                .get_request_timeout();
 6962            let request_task = client.request_lsp(
 6963                upstream_project_id,
 6964                None,
 6965                request_timeout,
 6966                cx.background_executor().clone(),
 6967                request.to_proto(upstream_project_id, buffer.read(cx)),
 6968            );
 6969            cx.background_spawn(async move {
 6970                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6971                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6972                // Do not attempt to further process the dummy responses here.
 6973                let _response = request_task.await?;
 6974                Ok(None)
 6975            })
 6976        } else {
 6977            let servers = buffer.update(cx, |buffer, cx| {
 6978                self.running_language_servers_for_local_buffer(buffer, cx)
 6979                    .map(|(_, server)| server.clone())
 6980                    .collect::<Vec<_>>()
 6981            });
 6982
 6983            let pull_diagnostics = servers
 6984                .into_iter()
 6985                .flat_map(|server| {
 6986                    let result = maybe!({
 6987                        let local = self.as_local()?;
 6988                        let server_id = server.server_id();
 6989                        let providers_with_identifiers = local
 6990                            .language_server_dynamic_registrations
 6991                            .get(&server_id)
 6992                            .into_iter()
 6993                            .flat_map(|registrations| registrations.diagnostics.clone())
 6994                            .collect::<Vec<_>>();
 6995                        Some(
 6996                            providers_with_identifiers
 6997                                .into_iter()
 6998                                .map(|(registration_id, dynamic_caps)| {
 6999                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7000                                    let registration_id = registration_id.map(SharedString::from);
 7001                                    let result_id = self.result_id_for_buffer_pull(
 7002                                        server_id,
 7003                                        buffer_id,
 7004                                        &registration_id,
 7005                                        cx,
 7006                                    );
 7007                                    self.request_lsp(
 7008                                        buffer.clone(),
 7009                                        LanguageServerToQuery::Other(server_id),
 7010                                        GetDocumentDiagnostics {
 7011                                            previous_result_id: result_id,
 7012                                            registration_id,
 7013                                            identifier,
 7014                                        },
 7015                                        cx,
 7016                                    )
 7017                                })
 7018                                .collect::<Vec<_>>(),
 7019                        )
 7020                    });
 7021
 7022                    result.unwrap_or_default()
 7023                })
 7024                .collect::<Vec<_>>();
 7025
 7026            cx.background_spawn(async move {
 7027                let mut responses = Vec::new();
 7028                for diagnostics in join_all(pull_diagnostics).await {
 7029                    responses.extend(diagnostics?);
 7030                }
 7031                Ok(Some(responses))
 7032            })
 7033        }
 7034    }
 7035
 7036    pub fn applicable_inlay_chunks(
 7037        &mut self,
 7038        buffer: &Entity<Buffer>,
 7039        ranges: &[Range<text::Anchor>],
 7040        cx: &mut Context<Self>,
 7041    ) -> Vec<Range<BufferRow>> {
 7042        let buffer_snapshot = buffer.read(cx).snapshot();
 7043        let ranges = ranges
 7044            .iter()
 7045            .map(|range| range.to_point(&buffer_snapshot))
 7046            .collect::<Vec<_>>();
 7047
 7048        self.latest_lsp_data(buffer, cx)
 7049            .inlay_hints
 7050            .applicable_chunks(ranges.as_slice())
 7051            .map(|chunk| chunk.row_range())
 7052            .collect()
 7053    }
 7054
 7055    pub fn invalidate_inlay_hints<'a>(
 7056        &'a mut self,
 7057        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7058    ) {
 7059        for buffer_id in for_buffers {
 7060            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7061                lsp_data.inlay_hints.clear();
 7062            }
 7063        }
 7064    }
 7065
 7066    pub fn inlay_hints(
 7067        &mut self,
 7068        invalidate: InvalidationStrategy,
 7069        buffer: Entity<Buffer>,
 7070        ranges: Vec<Range<text::Anchor>>,
 7071        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7072        cx: &mut Context<Self>,
 7073    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7074        let next_hint_id = self.next_hint_id.clone();
 7075        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7076        let query_version = lsp_data.buffer_version.clone();
 7077        let mut lsp_refresh_requested = false;
 7078        let for_server = if let InvalidationStrategy::RefreshRequested {
 7079            server_id,
 7080            request_id,
 7081        } = invalidate
 7082        {
 7083            let invalidated = lsp_data
 7084                .inlay_hints
 7085                .invalidate_for_server_refresh(server_id, request_id);
 7086            lsp_refresh_requested = invalidated;
 7087            Some(server_id)
 7088        } else {
 7089            None
 7090        };
 7091        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7092        let known_chunks = known_chunks
 7093            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7094            .map(|(_, known_chunks)| known_chunks)
 7095            .unwrap_or_default();
 7096
 7097        let buffer_snapshot = buffer.read(cx).snapshot();
 7098        let ranges = ranges
 7099            .iter()
 7100            .map(|range| range.to_point(&buffer_snapshot))
 7101            .collect::<Vec<_>>();
 7102
 7103        let mut hint_fetch_tasks = Vec::new();
 7104        let mut cached_inlay_hints = None;
 7105        let mut ranges_to_query = None;
 7106        let applicable_chunks = existing_inlay_hints
 7107            .applicable_chunks(ranges.as_slice())
 7108            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7109            .collect::<Vec<_>>();
 7110        if applicable_chunks.is_empty() {
 7111            return HashMap::default();
 7112        }
 7113
 7114        for row_chunk in applicable_chunks {
 7115            match (
 7116                existing_inlay_hints
 7117                    .cached_hints(&row_chunk)
 7118                    .filter(|_| !lsp_refresh_requested)
 7119                    .cloned(),
 7120                existing_inlay_hints
 7121                    .fetched_hints(&row_chunk)
 7122                    .as_ref()
 7123                    .filter(|_| !lsp_refresh_requested)
 7124                    .cloned(),
 7125            ) {
 7126                (None, None) => {
 7127                    let chunk_range = row_chunk.anchor_range();
 7128                    ranges_to_query
 7129                        .get_or_insert_with(Vec::new)
 7130                        .push((row_chunk, chunk_range));
 7131                }
 7132                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7133                (Some(cached_hints), None) => {
 7134                    for (server_id, cached_hints) in cached_hints {
 7135                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7136                            cached_inlay_hints
 7137                                .get_or_insert_with(HashMap::default)
 7138                                .entry(row_chunk.row_range())
 7139                                .or_insert_with(HashMap::default)
 7140                                .entry(server_id)
 7141                                .or_insert_with(Vec::new)
 7142                                .extend(cached_hints);
 7143                        }
 7144                    }
 7145                }
 7146                (Some(cached_hints), Some(fetched_hints)) => {
 7147                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7148                    for (server_id, cached_hints) in cached_hints {
 7149                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7150                            cached_inlay_hints
 7151                                .get_or_insert_with(HashMap::default)
 7152                                .entry(row_chunk.row_range())
 7153                                .or_insert_with(HashMap::default)
 7154                                .entry(server_id)
 7155                                .or_insert_with(Vec::new)
 7156                                .extend(cached_hints);
 7157                        }
 7158                    }
 7159                }
 7160            }
 7161        }
 7162
 7163        if hint_fetch_tasks.is_empty()
 7164            && ranges_to_query
 7165                .as_ref()
 7166                .is_none_or(|ranges| ranges.is_empty())
 7167            && let Some(cached_inlay_hints) = cached_inlay_hints
 7168        {
 7169            cached_inlay_hints
 7170                .into_iter()
 7171                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7172                .collect()
 7173        } else {
 7174            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7175                // When a server refresh was requested, other servers' cached hints
 7176                // are unaffected by the refresh and must be included in the result.
 7177                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7178                // removes all visible hints but only adds back the requesting
 7179                // server's new hints, permanently losing other servers' hints.
 7180                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7181                    lsp_data
 7182                        .inlay_hints
 7183                        .cached_hints(&chunk)
 7184                        .cloned()
 7185                        .unwrap_or_default()
 7186                } else {
 7187                    HashMap::default()
 7188                };
 7189
 7190                let next_hint_id = next_hint_id.clone();
 7191                let buffer = buffer.clone();
 7192                let query_version = query_version.clone();
 7193                let new_inlay_hints = cx
 7194                    .spawn(async move |lsp_store, cx| {
 7195                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7196                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7197                        })?;
 7198                        new_fetch_task
 7199                            .await
 7200                            .and_then(|new_hints_by_server| {
 7201                                lsp_store.update(cx, |lsp_store, cx| {
 7202                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7203                                    let update_cache = lsp_data.buffer_version == query_version;
 7204                                    if new_hints_by_server.is_empty() {
 7205                                        if update_cache {
 7206                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7207                                        }
 7208                                        other_servers_cached
 7209                                    } else {
 7210                                        let mut result = other_servers_cached;
 7211                                        for (server_id, new_hints) in new_hints_by_server {
 7212                                            let new_hints = new_hints
 7213                                                .into_iter()
 7214                                                .map(|new_hint| {
 7215                                                    (
 7216                                                        InlayId::Hint(next_hint_id.fetch_add(
 7217                                                            1,
 7218                                                            atomic::Ordering::AcqRel,
 7219                                                        )),
 7220                                                        new_hint,
 7221                                                    )
 7222                                                })
 7223                                                .collect::<Vec<_>>();
 7224                                            if update_cache {
 7225                                                lsp_data.inlay_hints.insert_new_hints(
 7226                                                    chunk,
 7227                                                    server_id,
 7228                                                    new_hints.clone(),
 7229                                                );
 7230                                            }
 7231                                            result.insert(server_id, new_hints);
 7232                                        }
 7233                                        result
 7234                                    }
 7235                                })
 7236                            })
 7237                            .map_err(Arc::new)
 7238                    })
 7239                    .shared();
 7240
 7241                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7242                *fetch_task = Some(new_inlay_hints.clone());
 7243                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7244            }
 7245
 7246            cached_inlay_hints
 7247                .unwrap_or_default()
 7248                .into_iter()
 7249                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7250                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7251                    (
 7252                        chunk.row_range(),
 7253                        cx.spawn(async move |_, _| {
 7254                            hints_fetch.await.map_err(|e| {
 7255                                if e.error_code() != ErrorCode::Internal {
 7256                                    anyhow!(e.error_code())
 7257                                } else {
 7258                                    anyhow!("{e:#}")
 7259                                }
 7260                            })
 7261                        }),
 7262                    )
 7263                }))
 7264                .collect()
 7265        }
 7266    }
 7267
 7268    fn fetch_inlay_hints(
 7269        &mut self,
 7270        for_server: Option<LanguageServerId>,
 7271        buffer: &Entity<Buffer>,
 7272        range: Range<Anchor>,
 7273        cx: &mut Context<Self>,
 7274    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7275        let request = InlayHints {
 7276            range: range.clone(),
 7277        };
 7278        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7279            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7280                return Task::ready(Ok(HashMap::default()));
 7281            }
 7282            let request_timeout = ProjectSettings::get_global(cx)
 7283                .global_lsp_settings
 7284                .get_request_timeout();
 7285            let request_task = upstream_client.request_lsp(
 7286                project_id,
 7287                for_server.map(|id| id.to_proto()),
 7288                request_timeout,
 7289                cx.background_executor().clone(),
 7290                request.to_proto(project_id, buffer.read(cx)),
 7291            );
 7292            let buffer = buffer.clone();
 7293            cx.spawn(async move |weak_lsp_store, cx| {
 7294                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7295                    return Ok(HashMap::default());
 7296                };
 7297                let Some(responses) = request_task.await? else {
 7298                    return Ok(HashMap::default());
 7299                };
 7300
 7301                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7302                    let lsp_store = lsp_store.clone();
 7303                    let buffer = buffer.clone();
 7304                    let cx = cx.clone();
 7305                    let request = request.clone();
 7306                    async move {
 7307                        (
 7308                            LanguageServerId::from_proto(response.server_id),
 7309                            request
 7310                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7311                                .await,
 7312                        )
 7313                    }
 7314                }))
 7315                .await;
 7316
 7317                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7318                let mut has_errors = false;
 7319                let inlay_hints = inlay_hints
 7320                    .into_iter()
 7321                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7322                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7323                        Err(e) => {
 7324                            has_errors = true;
 7325                            log::error!("{e:#}");
 7326                            None
 7327                        }
 7328                    })
 7329                    .map(|(server_id, mut new_hints)| {
 7330                        new_hints.retain(|hint| {
 7331                            hint.position.is_valid(&buffer_snapshot)
 7332                                && range.start.is_valid(&buffer_snapshot)
 7333                                && range.end.is_valid(&buffer_snapshot)
 7334                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7335                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7336                        });
 7337                        (server_id, new_hints)
 7338                    })
 7339                    .collect::<HashMap<_, _>>();
 7340                anyhow::ensure!(
 7341                    !has_errors || !inlay_hints.is_empty(),
 7342                    "Failed to fetch inlay hints"
 7343                );
 7344                Ok(inlay_hints)
 7345            })
 7346        } else {
 7347            let inlay_hints_task = match for_server {
 7348                Some(server_id) => {
 7349                    let server_task = self.request_lsp(
 7350                        buffer.clone(),
 7351                        LanguageServerToQuery::Other(server_id),
 7352                        request,
 7353                        cx,
 7354                    );
 7355                    cx.background_spawn(async move {
 7356                        let mut responses = Vec::new();
 7357                        match server_task.await {
 7358                            Ok(response) => responses.push((server_id, response)),
 7359                            // rust-analyzer likes to error with this when its still loading up
 7360                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7361                            Err(e) => log::error!(
 7362                                "Error handling response for inlay hints request: {e:#}"
 7363                            ),
 7364                        }
 7365                        responses
 7366                    })
 7367                }
 7368                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7369            };
 7370            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7371            cx.background_spawn(async move {
 7372                Ok(inlay_hints_task
 7373                    .await
 7374                    .into_iter()
 7375                    .map(|(server_id, mut new_hints)| {
 7376                        new_hints.retain(|hint| {
 7377                            hint.position.is_valid(&buffer_snapshot)
 7378                                && range.start.is_valid(&buffer_snapshot)
 7379                                && range.end.is_valid(&buffer_snapshot)
 7380                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7381                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7382                        });
 7383                        (server_id, new_hints)
 7384                    })
 7385                    .collect())
 7386            })
 7387        }
 7388    }
 7389
 7390    fn diagnostic_registration_exists(
 7391        &self,
 7392        server_id: LanguageServerId,
 7393        registration_id: &Option<SharedString>,
 7394    ) -> bool {
 7395        let Some(local) = self.as_local() else {
 7396            return false;
 7397        };
 7398        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7399        else {
 7400            return false;
 7401        };
 7402        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7403        registrations.diagnostics.contains_key(&registration_key)
 7404    }
 7405
 7406    pub fn pull_diagnostics_for_buffer(
 7407        &mut self,
 7408        buffer: Entity<Buffer>,
 7409        cx: &mut Context<Self>,
 7410    ) -> Task<anyhow::Result<()>> {
 7411        let diagnostics = self.pull_diagnostics(buffer, cx);
 7412        cx.spawn(async move |lsp_store, cx| {
 7413            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7414                return Ok(());
 7415            };
 7416            lsp_store.update(cx, |lsp_store, cx| {
 7417                if lsp_store.as_local().is_none() {
 7418                    return;
 7419                }
 7420
 7421                let mut unchanged_buffers = HashMap::default();
 7422                let server_diagnostics_updates = diagnostics
 7423                    .into_iter()
 7424                    .filter_map(|diagnostics_set| match diagnostics_set {
 7425                        LspPullDiagnostics::Response {
 7426                            server_id,
 7427                            uri,
 7428                            diagnostics,
 7429                            registration_id,
 7430                        } => Some((server_id, uri, diagnostics, registration_id)),
 7431                        LspPullDiagnostics::Default => None,
 7432                    })
 7433                    .filter(|(server_id, _, _, registration_id)| {
 7434                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7435                    })
 7436                    .fold(
 7437                        HashMap::default(),
 7438                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7439                            let (result_id, diagnostics) = match diagnostics {
 7440                                PulledDiagnostics::Unchanged { result_id } => {
 7441                                    unchanged_buffers
 7442                                        .entry(new_registration_id.clone())
 7443                                        .or_insert_with(HashSet::default)
 7444                                        .insert(uri.clone());
 7445                                    (Some(result_id), Vec::new())
 7446                                }
 7447                                PulledDiagnostics::Changed {
 7448                                    result_id,
 7449                                    diagnostics,
 7450                                } => (result_id, diagnostics),
 7451                            };
 7452                            let disk_based_sources = Cow::Owned(
 7453                                lsp_store
 7454                                    .language_server_adapter_for_id(server_id)
 7455                                    .as_ref()
 7456                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7457                                    .unwrap_or(&[])
 7458                                    .to_vec(),
 7459                            );
 7460                            acc.entry(server_id)
 7461                                .or_insert_with(HashMap::default)
 7462                                .entry(new_registration_id.clone())
 7463                                .or_insert_with(Vec::new)
 7464                                .push(DocumentDiagnosticsUpdate {
 7465                                    server_id,
 7466                                    diagnostics: lsp::PublishDiagnosticsParams {
 7467                                        uri,
 7468                                        diagnostics,
 7469                                        version: None,
 7470                                    },
 7471                                    result_id: result_id.map(SharedString::new),
 7472                                    disk_based_sources,
 7473                                    registration_id: new_registration_id,
 7474                                });
 7475                            acc
 7476                        },
 7477                    );
 7478
 7479                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7480                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7481                        lsp_store
 7482                            .merge_lsp_diagnostics(
 7483                                DiagnosticSourceKind::Pulled,
 7484                                diagnostic_updates,
 7485                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7486                                    DiagnosticSourceKind::Pulled => {
 7487                                        old_diagnostic.registration_id != registration_id
 7488                                            || unchanged_buffers
 7489                                                .get(&old_diagnostic.registration_id)
 7490                                                .is_some_and(|unchanged_buffers| {
 7491                                                    unchanged_buffers.contains(&document_uri)
 7492                                                })
 7493                                    }
 7494                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7495                                        true
 7496                                    }
 7497                                },
 7498                                cx,
 7499                            )
 7500                            .log_err();
 7501                    }
 7502                }
 7503            })
 7504        })
 7505    }
 7506
 7507    pub fn signature_help<T: ToPointUtf16>(
 7508        &mut self,
 7509        buffer: &Entity<Buffer>,
 7510        position: T,
 7511        cx: &mut Context<Self>,
 7512    ) -> Task<Option<Vec<SignatureHelp>>> {
 7513        let position = position.to_point_utf16(buffer.read(cx));
 7514
 7515        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7516            let request = GetSignatureHelp { position };
 7517            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7518                return Task::ready(None);
 7519            }
 7520            let request_timeout = ProjectSettings::get_global(cx)
 7521                .global_lsp_settings
 7522                .get_request_timeout();
 7523            let request_task = client.request_lsp(
 7524                upstream_project_id,
 7525                None,
 7526                request_timeout,
 7527                cx.background_executor().clone(),
 7528                request.to_proto(upstream_project_id, buffer.read(cx)),
 7529            );
 7530            let buffer = buffer.clone();
 7531            cx.spawn(async move |weak_lsp_store, cx| {
 7532                let lsp_store = weak_lsp_store.upgrade()?;
 7533                let signatures = join_all(
 7534                    request_task
 7535                        .await
 7536                        .log_err()
 7537                        .flatten()
 7538                        .map(|response| response.payload)
 7539                        .unwrap_or_default()
 7540                        .into_iter()
 7541                        .map(|response| {
 7542                            let response = GetSignatureHelp { position }.response_from_proto(
 7543                                response.response,
 7544                                lsp_store.clone(),
 7545                                buffer.clone(),
 7546                                cx.clone(),
 7547                            );
 7548                            async move { response.await.log_err().flatten() }
 7549                        }),
 7550                )
 7551                .await
 7552                .into_iter()
 7553                .flatten()
 7554                .collect();
 7555                Some(signatures)
 7556            })
 7557        } else {
 7558            let all_actions_task = self.request_multiple_lsp_locally(
 7559                buffer,
 7560                Some(position),
 7561                GetSignatureHelp { position },
 7562                cx,
 7563            );
 7564            cx.background_spawn(async move {
 7565                Some(
 7566                    all_actions_task
 7567                        .await
 7568                        .into_iter()
 7569                        .flat_map(|(_, actions)| actions)
 7570                        .collect::<Vec<_>>(),
 7571                )
 7572            })
 7573        }
 7574    }
 7575
 7576    pub fn hover(
 7577        &mut self,
 7578        buffer: &Entity<Buffer>,
 7579        position: PointUtf16,
 7580        cx: &mut Context<Self>,
 7581    ) -> Task<Option<Vec<Hover>>> {
 7582        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7583            let request = GetHover { position };
 7584            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7585                return Task::ready(None);
 7586            }
 7587            let request_timeout = ProjectSettings::get_global(cx)
 7588                .global_lsp_settings
 7589                .get_request_timeout();
 7590            let request_task = client.request_lsp(
 7591                upstream_project_id,
 7592                None,
 7593                request_timeout,
 7594                cx.background_executor().clone(),
 7595                request.to_proto(upstream_project_id, buffer.read(cx)),
 7596            );
 7597            let buffer = buffer.clone();
 7598            cx.spawn(async move |weak_lsp_store, cx| {
 7599                let lsp_store = weak_lsp_store.upgrade()?;
 7600                let hovers = join_all(
 7601                    request_task
 7602                        .await
 7603                        .log_err()
 7604                        .flatten()
 7605                        .map(|response| response.payload)
 7606                        .unwrap_or_default()
 7607                        .into_iter()
 7608                        .map(|response| {
 7609                            let response = GetHover { position }.response_from_proto(
 7610                                response.response,
 7611                                lsp_store.clone(),
 7612                                buffer.clone(),
 7613                                cx.clone(),
 7614                            );
 7615                            async move {
 7616                                response
 7617                                    .await
 7618                                    .log_err()
 7619                                    .flatten()
 7620                                    .and_then(remove_empty_hover_blocks)
 7621                            }
 7622                        }),
 7623                )
 7624                .await
 7625                .into_iter()
 7626                .flatten()
 7627                .collect();
 7628                Some(hovers)
 7629            })
 7630        } else {
 7631            let all_actions_task = self.request_multiple_lsp_locally(
 7632                buffer,
 7633                Some(position),
 7634                GetHover { position },
 7635                cx,
 7636            );
 7637            cx.background_spawn(async move {
 7638                Some(
 7639                    all_actions_task
 7640                        .await
 7641                        .into_iter()
 7642                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7643                        .collect::<Vec<Hover>>(),
 7644                )
 7645            })
 7646        }
 7647    }
 7648
 7649    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7650        let language_registry = self.languages.clone();
 7651
 7652        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7653            let request = upstream_client.request(proto::GetProjectSymbols {
 7654                project_id: *project_id,
 7655                query: query.to_string(),
 7656            });
 7657            cx.foreground_executor().spawn(async move {
 7658                let response = request.await?;
 7659                let mut symbols = Vec::new();
 7660                let core_symbols = response
 7661                    .symbols
 7662                    .into_iter()
 7663                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7664                    .collect::<Vec<_>>();
 7665                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7666                    .await;
 7667                Ok(symbols)
 7668            })
 7669        } else if let Some(local) = self.as_local() {
 7670            struct WorkspaceSymbolsResult {
 7671                server_id: LanguageServerId,
 7672                lsp_adapter: Arc<CachedLspAdapter>,
 7673                worktree: WeakEntity<Worktree>,
 7674                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7675            }
 7676
 7677            let mut requests = Vec::new();
 7678            let mut requested_servers = BTreeSet::new();
 7679            let request_timeout = ProjectSettings::get_global(cx)
 7680                .global_lsp_settings
 7681                .get_request_timeout();
 7682
 7683            for (seed, state) in local.language_server_ids.iter() {
 7684                let Some(worktree_handle) = self
 7685                    .worktree_store
 7686                    .read(cx)
 7687                    .worktree_for_id(seed.worktree_id, cx)
 7688                else {
 7689                    continue;
 7690                };
 7691
 7692                let worktree = worktree_handle.read(cx);
 7693                if !worktree.is_visible() {
 7694                    continue;
 7695                }
 7696
 7697                if !requested_servers.insert(state.id) {
 7698                    continue;
 7699                }
 7700
 7701                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7702                    Some(LanguageServerState::Running {
 7703                        adapter, server, ..
 7704                    }) => (adapter.clone(), server),
 7705
 7706                    _ => continue,
 7707                };
 7708
 7709                let supports_workspace_symbol_request =
 7710                    match server.capabilities().workspace_symbol_provider {
 7711                        Some(OneOf::Left(supported)) => supported,
 7712                        Some(OneOf::Right(_)) => true,
 7713                        None => false,
 7714                    };
 7715
 7716                if !supports_workspace_symbol_request {
 7717                    continue;
 7718                }
 7719
 7720                let worktree_handle = worktree_handle.clone();
 7721                let server_id = server.server_id();
 7722                requests.push(
 7723                    server
 7724                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7725                            lsp::WorkspaceSymbolParams {
 7726                                query: query.to_string(),
 7727                                ..Default::default()
 7728                            },
 7729                            request_timeout,
 7730                        )
 7731                        .map(move |response| {
 7732                            let lsp_symbols = response
 7733                                .into_response()
 7734                                .context("workspace symbols request")
 7735                                .log_err()
 7736                                .flatten()
 7737                                .map(|symbol_response| match symbol_response {
 7738                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7739                                        flat_responses
 7740                                            .into_iter()
 7741                                            .map(|lsp_symbol| {
 7742                                                (
 7743                                                    lsp_symbol.name,
 7744                                                    lsp_symbol.kind,
 7745                                                    lsp_symbol.location,
 7746                                                    lsp_symbol.container_name,
 7747                                                )
 7748                                            })
 7749                                            .collect::<Vec<_>>()
 7750                                    }
 7751                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7752                                        nested_responses
 7753                                            .into_iter()
 7754                                            .filter_map(|lsp_symbol| {
 7755                                                let location = match lsp_symbol.location {
 7756                                                    OneOf::Left(location) => location,
 7757                                                    OneOf::Right(_) => {
 7758                                                        log::error!(
 7759                                                            "Unexpected: client capabilities \
 7760                                                            forbid symbol resolutions in \
 7761                                                            workspace.symbol.resolveSupport"
 7762                                                        );
 7763                                                        return None;
 7764                                                    }
 7765                                                };
 7766                                                Some((
 7767                                                    lsp_symbol.name,
 7768                                                    lsp_symbol.kind,
 7769                                                    location,
 7770                                                    lsp_symbol.container_name,
 7771                                                ))
 7772                                            })
 7773                                            .collect::<Vec<_>>()
 7774                                    }
 7775                                })
 7776                                .unwrap_or_default();
 7777
 7778                            WorkspaceSymbolsResult {
 7779                                server_id,
 7780                                lsp_adapter,
 7781                                worktree: worktree_handle.downgrade(),
 7782                                lsp_symbols,
 7783                            }
 7784                        }),
 7785                );
 7786            }
 7787
 7788            cx.spawn(async move |this, cx| {
 7789                let responses = futures::future::join_all(requests).await;
 7790                let this = match this.upgrade() {
 7791                    Some(this) => this,
 7792                    None => return Ok(Vec::new()),
 7793                };
 7794
 7795                let mut symbols = Vec::new();
 7796                for result in responses {
 7797                    let core_symbols = this.update(cx, |this, cx| {
 7798                        result
 7799                            .lsp_symbols
 7800                            .into_iter()
 7801                            .filter_map(
 7802                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7803                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7804                                    let source_worktree = result.worktree.upgrade()?;
 7805                                    let source_worktree_id = source_worktree.read(cx).id();
 7806
 7807                                    let path = if let Some((tree, rel_path)) =
 7808                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7809                                    {
 7810                                        let worktree_id = tree.read(cx).id();
 7811                                        SymbolLocation::InProject(ProjectPath {
 7812                                            worktree_id,
 7813                                            path: rel_path,
 7814                                        })
 7815                                    } else {
 7816                                        SymbolLocation::OutsideProject {
 7817                                            signature: this.symbol_signature(&abs_path),
 7818                                            abs_path: abs_path.into(),
 7819                                        }
 7820                                    };
 7821
 7822                                    Some(CoreSymbol {
 7823                                        source_language_server_id: result.server_id,
 7824                                        language_server_name: result.lsp_adapter.name.clone(),
 7825                                        source_worktree_id,
 7826                                        path,
 7827                                        kind: symbol_kind,
 7828                                        name: collapse_newlines(&symbol_name, ""),
 7829                                        range: range_from_lsp(symbol_location.range),
 7830                                        container_name: container_name
 7831                                            .map(|c| collapse_newlines(&c, "")),
 7832                                    })
 7833                                },
 7834                            )
 7835                            .collect::<Vec<_>>()
 7836                    });
 7837
 7838                    populate_labels_for_symbols(
 7839                        core_symbols,
 7840                        &language_registry,
 7841                        Some(result.lsp_adapter),
 7842                        &mut symbols,
 7843                    )
 7844                    .await;
 7845                }
 7846
 7847                Ok(symbols)
 7848            })
 7849        } else {
 7850            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7851        }
 7852    }
 7853
 7854    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7855        let mut summary = DiagnosticSummary::default();
 7856        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7857            summary.error_count += path_summary.error_count;
 7858            summary.warning_count += path_summary.warning_count;
 7859        }
 7860        summary
 7861    }
 7862
 7863    /// Returns the diagnostic summary for a specific project path.
 7864    pub fn diagnostic_summary_for_path(
 7865        &self,
 7866        project_path: &ProjectPath,
 7867        _: &App,
 7868    ) -> DiagnosticSummary {
 7869        if let Some(summaries) = self
 7870            .diagnostic_summaries
 7871            .get(&project_path.worktree_id)
 7872            .and_then(|map| map.get(&project_path.path))
 7873        {
 7874            let (error_count, warning_count) = summaries.iter().fold(
 7875                (0, 0),
 7876                |(error_count, warning_count), (_language_server_id, summary)| {
 7877                    (
 7878                        error_count + summary.error_count,
 7879                        warning_count + summary.warning_count,
 7880                    )
 7881                },
 7882            );
 7883
 7884            DiagnosticSummary {
 7885                error_count,
 7886                warning_count,
 7887            }
 7888        } else {
 7889            DiagnosticSummary::default()
 7890        }
 7891    }
 7892
 7893    pub fn diagnostic_summaries<'a>(
 7894        &'a self,
 7895        include_ignored: bool,
 7896        cx: &'a App,
 7897    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7898        self.worktree_store
 7899            .read(cx)
 7900            .visible_worktrees(cx)
 7901            .filter_map(|worktree| {
 7902                let worktree = worktree.read(cx);
 7903                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7904            })
 7905            .flat_map(move |(worktree, summaries)| {
 7906                let worktree_id = worktree.id();
 7907                summaries
 7908                    .iter()
 7909                    .filter(move |(path, _)| {
 7910                        include_ignored
 7911                            || worktree
 7912                                .entry_for_path(path.as_ref())
 7913                                .is_some_and(|entry| !entry.is_ignored)
 7914                    })
 7915                    .flat_map(move |(path, summaries)| {
 7916                        summaries.iter().map(move |(server_id, summary)| {
 7917                            (
 7918                                ProjectPath {
 7919                                    worktree_id,
 7920                                    path: path.clone(),
 7921                                },
 7922                                *server_id,
 7923                                *summary,
 7924                            )
 7925                        })
 7926                    })
 7927            })
 7928    }
 7929
 7930    pub fn on_buffer_edited(
 7931        &mut self,
 7932        buffer: Entity<Buffer>,
 7933        cx: &mut Context<Self>,
 7934    ) -> Option<()> {
 7935        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7936            Some(
 7937                self.as_local()?
 7938                    .language_servers_for_buffer(buffer, cx)
 7939                    .map(|i| i.1.clone())
 7940                    .collect(),
 7941            )
 7942        })?;
 7943
 7944        let buffer = buffer.read(cx);
 7945        let file = File::from_dyn(buffer.file())?;
 7946        let abs_path = file.as_local()?.abs_path(cx);
 7947        let uri = lsp::Uri::from_file_path(&abs_path)
 7948            .ok()
 7949            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7950            .log_err()?;
 7951        let next_snapshot = buffer.text_snapshot();
 7952        for language_server in language_servers {
 7953            let language_server = language_server.clone();
 7954
 7955            let buffer_snapshots = self
 7956                .as_local_mut()?
 7957                .buffer_snapshots
 7958                .get_mut(&buffer.remote_id())
 7959                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7960            let previous_snapshot = buffer_snapshots.last()?;
 7961
 7962            let build_incremental_change = || {
 7963                buffer
 7964                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7965                        previous_snapshot.snapshot.version(),
 7966                    )
 7967                    .map(|edit| {
 7968                        let edit_start = edit.new.start.0;
 7969                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7970                        let new_text = next_snapshot
 7971                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7972                            .collect();
 7973                        lsp::TextDocumentContentChangeEvent {
 7974                            range: Some(lsp::Range::new(
 7975                                point_to_lsp(edit_start),
 7976                                point_to_lsp(edit_end),
 7977                            )),
 7978                            range_length: None,
 7979                            text: new_text,
 7980                        }
 7981                    })
 7982                    .collect()
 7983            };
 7984
 7985            let document_sync_kind = language_server
 7986                .capabilities()
 7987                .text_document_sync
 7988                .as_ref()
 7989                .and_then(|sync| match sync {
 7990                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7991                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7992                });
 7993
 7994            let content_changes: Vec<_> = match document_sync_kind {
 7995                Some(lsp::TextDocumentSyncKind::FULL) => {
 7996                    vec![lsp::TextDocumentContentChangeEvent {
 7997                        range: None,
 7998                        range_length: None,
 7999                        text: next_snapshot.text(),
 8000                    }]
 8001                }
 8002                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8003                _ => {
 8004                    #[cfg(any(test, feature = "test-support"))]
 8005                    {
 8006                        build_incremental_change()
 8007                    }
 8008
 8009                    #[cfg(not(any(test, feature = "test-support")))]
 8010                    {
 8011                        continue;
 8012                    }
 8013                }
 8014            };
 8015
 8016            let next_version = previous_snapshot.version + 1;
 8017            buffer_snapshots.push(LspBufferSnapshot {
 8018                version: next_version,
 8019                snapshot: next_snapshot.clone(),
 8020            });
 8021
 8022            language_server
 8023                .notify::<lsp::notification::DidChangeTextDocument>(
 8024                    lsp::DidChangeTextDocumentParams {
 8025                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8026                            uri.clone(),
 8027                            next_version,
 8028                        ),
 8029                        content_changes,
 8030                    },
 8031                )
 8032                .ok();
 8033            self.pull_workspace_diagnostics(language_server.server_id());
 8034        }
 8035
 8036        None
 8037    }
 8038
 8039    pub fn on_buffer_saved(
 8040        &mut self,
 8041        buffer: Entity<Buffer>,
 8042        cx: &mut Context<Self>,
 8043    ) -> Option<()> {
 8044        let file = File::from_dyn(buffer.read(cx).file())?;
 8045        let worktree_id = file.worktree_id(cx);
 8046        let abs_path = file.as_local()?.abs_path(cx);
 8047        let text_document = lsp::TextDocumentIdentifier {
 8048            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8049        };
 8050        let local = self.as_local()?;
 8051
 8052        for server in local.language_servers_for_worktree(worktree_id) {
 8053            if let Some(include_text) = include_text(server.as_ref()) {
 8054                let text = if include_text {
 8055                    Some(buffer.read(cx).text())
 8056                } else {
 8057                    None
 8058                };
 8059                server
 8060                    .notify::<lsp::notification::DidSaveTextDocument>(
 8061                        lsp::DidSaveTextDocumentParams {
 8062                            text_document: text_document.clone(),
 8063                            text,
 8064                        },
 8065                    )
 8066                    .ok();
 8067            }
 8068        }
 8069
 8070        let language_servers = buffer.update(cx, |buffer, cx| {
 8071            local.language_server_ids_for_buffer(buffer, cx)
 8072        });
 8073        for language_server_id in language_servers {
 8074            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8075        }
 8076
 8077        None
 8078    }
 8079
 8080    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8081        maybe!(async move {
 8082            let mut refreshed_servers = HashSet::default();
 8083            let servers = lsp_store
 8084                .update(cx, |lsp_store, cx| {
 8085                    let local = lsp_store.as_local()?;
 8086
 8087                    let servers = local
 8088                        .language_server_ids
 8089                        .iter()
 8090                        .filter_map(|(seed, state)| {
 8091                            let worktree = lsp_store
 8092                                .worktree_store
 8093                                .read(cx)
 8094                                .worktree_for_id(seed.worktree_id, cx);
 8095                            let delegate: Arc<dyn LspAdapterDelegate> =
 8096                                worktree.map(|worktree| {
 8097                                    LocalLspAdapterDelegate::new(
 8098                                        local.languages.clone(),
 8099                                        &local.environment,
 8100                                        cx.weak_entity(),
 8101                                        &worktree,
 8102                                        local.http_client.clone(),
 8103                                        local.fs.clone(),
 8104                                        cx,
 8105                                    )
 8106                                })?;
 8107                            let server_id = state.id;
 8108
 8109                            let states = local.language_servers.get(&server_id)?;
 8110
 8111                            match states {
 8112                                LanguageServerState::Starting { .. } => None,
 8113                                LanguageServerState::Running {
 8114                                    adapter, server, ..
 8115                                } => {
 8116                                    let adapter = adapter.clone();
 8117                                    let server = server.clone();
 8118                                    refreshed_servers.insert(server.name());
 8119                                    let toolchain = seed.toolchain.clone();
 8120                                    Some(cx.spawn(async move |_, cx| {
 8121                                        let settings =
 8122                                            LocalLspStore::workspace_configuration_for_adapter(
 8123                                                adapter.adapter.clone(),
 8124                                                &delegate,
 8125                                                toolchain,
 8126                                                None,
 8127                                                cx,
 8128                                            )
 8129                                            .await
 8130                                            .ok()?;
 8131                                        server
 8132                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8133                                                lsp::DidChangeConfigurationParams { settings },
 8134                                            )
 8135                                            .ok()?;
 8136                                        Some(())
 8137                                    }))
 8138                                }
 8139                            }
 8140                        })
 8141                        .collect::<Vec<_>>();
 8142
 8143                    Some(servers)
 8144                })
 8145                .ok()
 8146                .flatten()?;
 8147
 8148            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8149            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8150            // to stop and unregister its language server wrapper.
 8151            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8152            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8153            let _: Vec<Option<()>> = join_all(servers).await;
 8154
 8155            Some(())
 8156        })
 8157        .await;
 8158    }
 8159
 8160    fn maintain_workspace_config(
 8161        external_refresh_requests: watch::Receiver<()>,
 8162        cx: &mut Context<Self>,
 8163    ) -> Task<Result<()>> {
 8164        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8165        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8166
 8167        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8168            *settings_changed_tx.borrow_mut() = ();
 8169        });
 8170
 8171        let mut joint_future =
 8172            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8173        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8174        // - 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).
 8175        // - 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.
 8176        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8177        // - 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,
 8178        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8179        cx.spawn(async move |this, cx| {
 8180            while let Some(()) = joint_future.next().await {
 8181                this.update(cx, |this, cx| {
 8182                    this.refresh_server_tree(cx);
 8183                })
 8184                .ok();
 8185
 8186                Self::refresh_workspace_configurations(&this, cx).await;
 8187            }
 8188
 8189            drop(settings_observation);
 8190            anyhow::Ok(())
 8191        })
 8192    }
 8193
 8194    pub fn running_language_servers_for_local_buffer<'a>(
 8195        &'a self,
 8196        buffer: &Buffer,
 8197        cx: &mut App,
 8198    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8199        let local = self.as_local();
 8200        let language_server_ids = local
 8201            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8202            .unwrap_or_default();
 8203
 8204        language_server_ids
 8205            .into_iter()
 8206            .filter_map(
 8207                move |server_id| match local?.language_servers.get(&server_id)? {
 8208                    LanguageServerState::Running {
 8209                        adapter, server, ..
 8210                    } => Some((adapter, server)),
 8211                    _ => None,
 8212                },
 8213            )
 8214    }
 8215
 8216    pub fn language_servers_for_local_buffer(
 8217        &self,
 8218        buffer: &Buffer,
 8219        cx: &mut App,
 8220    ) -> Vec<LanguageServerId> {
 8221        let local = self.as_local();
 8222        local
 8223            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8224            .unwrap_or_default()
 8225    }
 8226
 8227    pub fn language_server_for_local_buffer<'a>(
 8228        &'a self,
 8229        buffer: &'a Buffer,
 8230        server_id: LanguageServerId,
 8231        cx: &'a mut App,
 8232    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8233        self.as_local()?
 8234            .language_servers_for_buffer(buffer, cx)
 8235            .find(|(_, s)| s.server_id() == server_id)
 8236    }
 8237
 8238    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8239        self.diagnostic_summaries.remove(&id_to_remove);
 8240        if let Some(local) = self.as_local_mut() {
 8241            let to_remove = local.remove_worktree(id_to_remove, cx);
 8242            for server in to_remove {
 8243                self.language_server_statuses.remove(&server);
 8244            }
 8245        }
 8246    }
 8247
 8248    fn invalidate_diagnostic_summaries_for_removed_entries(
 8249        &mut self,
 8250        worktree_id: WorktreeId,
 8251        changes: &UpdatedEntriesSet,
 8252        cx: &mut Context<Self>,
 8253    ) {
 8254        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8255            return;
 8256        };
 8257
 8258        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8259        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8260        let downstream = self.downstream_client.clone();
 8261
 8262        for (path, _, _) in changes
 8263            .iter()
 8264            .filter(|(_, _, change)| *change == PathChange::Removed)
 8265        {
 8266            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8267                for (server_id, _) in &summaries_by_server_id {
 8268                    cleared_server_ids.insert(*server_id);
 8269                    if let Some((client, project_id)) = &downstream {
 8270                        client
 8271                            .send(proto::UpdateDiagnosticSummary {
 8272                                project_id: *project_id,
 8273                                worktree_id: worktree_id.to_proto(),
 8274                                summary: Some(proto::DiagnosticSummary {
 8275                                    path: path.as_ref().to_proto(),
 8276                                    language_server_id: server_id.0 as u64,
 8277                                    error_count: 0,
 8278                                    warning_count: 0,
 8279                                }),
 8280                                more_summaries: Vec::new(),
 8281                            })
 8282                            .ok();
 8283                    }
 8284                }
 8285                cleared_paths.push(ProjectPath {
 8286                    worktree_id,
 8287                    path: path.clone(),
 8288                });
 8289            }
 8290        }
 8291
 8292        if !cleared_paths.is_empty() {
 8293            for server_id in cleared_server_ids {
 8294                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8295                    server_id,
 8296                    paths: cleared_paths.clone(),
 8297                });
 8298            }
 8299        }
 8300    }
 8301
 8302    pub fn shared(
 8303        &mut self,
 8304        project_id: u64,
 8305        downstream_client: AnyProtoClient,
 8306        _: &mut Context<Self>,
 8307    ) {
 8308        self.downstream_client = Some((downstream_client.clone(), project_id));
 8309
 8310        for (server_id, status) in &self.language_server_statuses {
 8311            if let Some(server) = self.language_server_for_id(*server_id) {
 8312                downstream_client
 8313                    .send(proto::StartLanguageServer {
 8314                        project_id,
 8315                        server: Some(proto::LanguageServer {
 8316                            id: server_id.to_proto(),
 8317                            name: status.name.to_string(),
 8318                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8319                        }),
 8320                        capabilities: serde_json::to_string(&server.capabilities())
 8321                            .expect("serializing server LSP capabilities"),
 8322                    })
 8323                    .log_err();
 8324            }
 8325        }
 8326    }
 8327
 8328    pub fn disconnected_from_host(&mut self) {
 8329        self.downstream_client.take();
 8330    }
 8331
 8332    pub fn disconnected_from_ssh_remote(&mut self) {
 8333        if let LspStoreMode::Remote(RemoteLspStore {
 8334            upstream_client, ..
 8335        }) = &mut self.mode
 8336        {
 8337            upstream_client.take();
 8338        }
 8339    }
 8340
 8341    pub(crate) fn set_language_server_statuses_from_proto(
 8342        &mut self,
 8343        project: WeakEntity<Project>,
 8344        language_servers: Vec<proto::LanguageServer>,
 8345        server_capabilities: Vec<String>,
 8346        cx: &mut Context<Self>,
 8347    ) {
 8348        let lsp_logs = cx
 8349            .try_global::<GlobalLogStore>()
 8350            .map(|lsp_store| lsp_store.0.clone());
 8351
 8352        self.language_server_statuses = language_servers
 8353            .into_iter()
 8354            .zip(server_capabilities)
 8355            .map(|(server, server_capabilities)| {
 8356                let server_id = LanguageServerId(server.id as usize);
 8357                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8358                    self.lsp_server_capabilities
 8359                        .insert(server_id, server_capabilities);
 8360                }
 8361
 8362                let name = LanguageServerName::from_proto(server.name);
 8363                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8364
 8365                if let Some(lsp_logs) = &lsp_logs {
 8366                    lsp_logs.update(cx, |lsp_logs, cx| {
 8367                        lsp_logs.add_language_server(
 8368                            // Only remote clients get their language servers set from proto
 8369                            LanguageServerKind::Remote {
 8370                                project: project.clone(),
 8371                            },
 8372                            server_id,
 8373                            Some(name.clone()),
 8374                            worktree,
 8375                            None,
 8376                            cx,
 8377                        );
 8378                    });
 8379                }
 8380
 8381                (
 8382                    server_id,
 8383                    LanguageServerStatus {
 8384                        name,
 8385                        server_version: None,
 8386                        server_readable_version: None,
 8387                        pending_work: Default::default(),
 8388                        has_pending_diagnostic_updates: false,
 8389                        progress_tokens: Default::default(),
 8390                        worktree,
 8391                        binary: None,
 8392                        configuration: None,
 8393                        workspace_folders: BTreeSet::new(),
 8394                        process_id: None,
 8395                    },
 8396                )
 8397            })
 8398            .collect();
 8399    }
 8400
 8401    #[cfg(feature = "test-support")]
 8402    pub fn update_diagnostic_entries(
 8403        &mut self,
 8404        server_id: LanguageServerId,
 8405        abs_path: PathBuf,
 8406        result_id: Option<SharedString>,
 8407        version: Option<i32>,
 8408        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8409        cx: &mut Context<Self>,
 8410    ) -> anyhow::Result<()> {
 8411        self.merge_diagnostic_entries(
 8412            vec![DocumentDiagnosticsUpdate {
 8413                diagnostics: DocumentDiagnostics {
 8414                    diagnostics,
 8415                    document_abs_path: abs_path,
 8416                    version,
 8417                },
 8418                result_id,
 8419                server_id,
 8420                disk_based_sources: Cow::Borrowed(&[]),
 8421                registration_id: None,
 8422            }],
 8423            |_, _, _| false,
 8424            cx,
 8425        )?;
 8426        Ok(())
 8427    }
 8428
 8429    pub fn merge_diagnostic_entries<'a>(
 8430        &mut self,
 8431        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8432        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8433        cx: &mut Context<Self>,
 8434    ) -> anyhow::Result<()> {
 8435        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8436        let mut updated_diagnostics_paths = HashMap::default();
 8437        for mut update in diagnostic_updates {
 8438            let abs_path = &update.diagnostics.document_abs_path;
 8439            let server_id = update.server_id;
 8440            let Some((worktree, relative_path)) =
 8441                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8442            else {
 8443                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8444                return Ok(());
 8445            };
 8446
 8447            let worktree_id = worktree.read(cx).id();
 8448            let project_path = ProjectPath {
 8449                worktree_id,
 8450                path: relative_path,
 8451            };
 8452
 8453            let document_uri = lsp::Uri::from_file_path(abs_path)
 8454                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8455            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8456                let snapshot = buffer_handle.read(cx).snapshot();
 8457                let buffer = buffer_handle.read(cx);
 8458                let reused_diagnostics = buffer
 8459                    .buffer_diagnostics(Some(server_id))
 8460                    .iter()
 8461                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8462                    .map(|v| {
 8463                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8464                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8465                        DiagnosticEntry {
 8466                            range: start..end,
 8467                            diagnostic: v.diagnostic.clone(),
 8468                        }
 8469                    })
 8470                    .collect::<Vec<_>>();
 8471
 8472                self.as_local_mut()
 8473                    .context("cannot merge diagnostics on a remote LspStore")?
 8474                    .update_buffer_diagnostics(
 8475                        &buffer_handle,
 8476                        server_id,
 8477                        Some(update.registration_id),
 8478                        update.result_id,
 8479                        update.diagnostics.version,
 8480                        update.diagnostics.diagnostics.clone(),
 8481                        reused_diagnostics.clone(),
 8482                        cx,
 8483                    )?;
 8484
 8485                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8486            } else if let Some(local) = self.as_local() {
 8487                let reused_diagnostics = local
 8488                    .diagnostics
 8489                    .get(&worktree_id)
 8490                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8491                    .and_then(|diagnostics_by_server_id| {
 8492                        diagnostics_by_server_id
 8493                            .binary_search_by_key(&server_id, |e| e.0)
 8494                            .ok()
 8495                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8496                    })
 8497                    .into_iter()
 8498                    .flatten()
 8499                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8500
 8501                update
 8502                    .diagnostics
 8503                    .diagnostics
 8504                    .extend(reused_diagnostics.cloned());
 8505            }
 8506
 8507            let updated = worktree.update(cx, |worktree, cx| {
 8508                self.update_worktree_diagnostics(
 8509                    worktree.id(),
 8510                    server_id,
 8511                    project_path.path.clone(),
 8512                    update.diagnostics.diagnostics,
 8513                    cx,
 8514                )
 8515            })?;
 8516            match updated {
 8517                ControlFlow::Continue(new_summary) => {
 8518                    if let Some((project_id, new_summary)) = new_summary {
 8519                        match &mut diagnostics_summary {
 8520                            Some(diagnostics_summary) => {
 8521                                diagnostics_summary
 8522                                    .more_summaries
 8523                                    .push(proto::DiagnosticSummary {
 8524                                        path: project_path.path.as_ref().to_proto(),
 8525                                        language_server_id: server_id.0 as u64,
 8526                                        error_count: new_summary.error_count,
 8527                                        warning_count: new_summary.warning_count,
 8528                                    })
 8529                            }
 8530                            None => {
 8531                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8532                                    project_id,
 8533                                    worktree_id: worktree_id.to_proto(),
 8534                                    summary: Some(proto::DiagnosticSummary {
 8535                                        path: project_path.path.as_ref().to_proto(),
 8536                                        language_server_id: server_id.0 as u64,
 8537                                        error_count: new_summary.error_count,
 8538                                        warning_count: new_summary.warning_count,
 8539                                    }),
 8540                                    more_summaries: Vec::new(),
 8541                                })
 8542                            }
 8543                        }
 8544                    }
 8545                    updated_diagnostics_paths
 8546                        .entry(server_id)
 8547                        .or_insert_with(Vec::new)
 8548                        .push(project_path);
 8549                }
 8550                ControlFlow::Break(()) => {}
 8551            }
 8552        }
 8553
 8554        if let Some((diagnostics_summary, (downstream_client, _))) =
 8555            diagnostics_summary.zip(self.downstream_client.as_ref())
 8556        {
 8557            downstream_client.send(diagnostics_summary).log_err();
 8558        }
 8559        for (server_id, paths) in updated_diagnostics_paths {
 8560            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8561        }
 8562        Ok(())
 8563    }
 8564
 8565    fn update_worktree_diagnostics(
 8566        &mut self,
 8567        worktree_id: WorktreeId,
 8568        server_id: LanguageServerId,
 8569        path_in_worktree: Arc<RelPath>,
 8570        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8571        _: &mut Context<Worktree>,
 8572    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8573        let local = match &mut self.mode {
 8574            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8575            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8576        };
 8577
 8578        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8579        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8580        let summaries_by_server_id = summaries_for_tree
 8581            .entry(path_in_worktree.clone())
 8582            .or_default();
 8583
 8584        let old_summary = summaries_by_server_id
 8585            .remove(&server_id)
 8586            .unwrap_or_default();
 8587
 8588        let new_summary = DiagnosticSummary::new(&diagnostics);
 8589        if diagnostics.is_empty() {
 8590            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8591            {
 8592                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8593                    diagnostics_by_server_id.remove(ix);
 8594                }
 8595                if diagnostics_by_server_id.is_empty() {
 8596                    diagnostics_for_tree.remove(&path_in_worktree);
 8597                }
 8598            }
 8599        } else {
 8600            summaries_by_server_id.insert(server_id, new_summary);
 8601            let diagnostics_by_server_id = diagnostics_for_tree
 8602                .entry(path_in_worktree.clone())
 8603                .or_default();
 8604            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8605                Ok(ix) => {
 8606                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8607                }
 8608                Err(ix) => {
 8609                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8610                }
 8611            }
 8612        }
 8613
 8614        if !old_summary.is_empty() || !new_summary.is_empty() {
 8615            if let Some((_, project_id)) = &self.downstream_client {
 8616                Ok(ControlFlow::Continue(Some((
 8617                    *project_id,
 8618                    proto::DiagnosticSummary {
 8619                        path: path_in_worktree.to_proto(),
 8620                        language_server_id: server_id.0 as u64,
 8621                        error_count: new_summary.error_count as u32,
 8622                        warning_count: new_summary.warning_count as u32,
 8623                    },
 8624                ))))
 8625            } else {
 8626                Ok(ControlFlow::Continue(None))
 8627            }
 8628        } else {
 8629            Ok(ControlFlow::Break(()))
 8630        }
 8631    }
 8632
 8633    pub fn open_buffer_for_symbol(
 8634        &mut self,
 8635        symbol: &Symbol,
 8636        cx: &mut Context<Self>,
 8637    ) -> Task<Result<Entity<Buffer>>> {
 8638        if let Some((client, project_id)) = self.upstream_client() {
 8639            let request = client.request(proto::OpenBufferForSymbol {
 8640                project_id,
 8641                symbol: Some(Self::serialize_symbol(symbol)),
 8642            });
 8643            cx.spawn(async move |this, cx| {
 8644                let response = request.await?;
 8645                let buffer_id = BufferId::new(response.buffer_id)?;
 8646                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8647                    .await
 8648            })
 8649        } else if let Some(local) = self.as_local() {
 8650            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8651                seed.worktree_id == symbol.source_worktree_id
 8652                    && state.id == symbol.source_language_server_id
 8653                    && symbol.language_server_name == seed.name
 8654            });
 8655            if !is_valid {
 8656                return Task::ready(Err(anyhow!(
 8657                    "language server for worktree and language not found"
 8658                )));
 8659            };
 8660
 8661            let symbol_abs_path = match &symbol.path {
 8662                SymbolLocation::InProject(project_path) => self
 8663                    .worktree_store
 8664                    .read(cx)
 8665                    .absolutize(&project_path, cx)
 8666                    .context("no such worktree"),
 8667                SymbolLocation::OutsideProject {
 8668                    abs_path,
 8669                    signature: _,
 8670                } => Ok(abs_path.to_path_buf()),
 8671            };
 8672            let symbol_abs_path = match symbol_abs_path {
 8673                Ok(abs_path) => abs_path,
 8674                Err(err) => return Task::ready(Err(err)),
 8675            };
 8676            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8677                uri
 8678            } else {
 8679                return Task::ready(Err(anyhow!("invalid symbol path")));
 8680            };
 8681
 8682            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8683        } else {
 8684            Task::ready(Err(anyhow!("no upstream client or local store")))
 8685        }
 8686    }
 8687
 8688    pub(crate) fn open_local_buffer_via_lsp(
 8689        &mut self,
 8690        abs_path: lsp::Uri,
 8691        language_server_id: LanguageServerId,
 8692        cx: &mut Context<Self>,
 8693    ) -> Task<Result<Entity<Buffer>>> {
 8694        let path_style = self.worktree_store.read(cx).path_style();
 8695        cx.spawn(async move |lsp_store, cx| {
 8696            // Escape percent-encoded string.
 8697            let current_scheme = abs_path.scheme().to_owned();
 8698            // Uri is immutable, so we can't modify the scheme
 8699
 8700            let abs_path = abs_path
 8701                .to_file_path_ext(path_style)
 8702                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8703            let p = abs_path.clone();
 8704            let yarn_worktree = lsp_store
 8705                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8706                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8707                        cx.spawn(async move |this, cx| {
 8708                            let t = this
 8709                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8710                                .ok()?;
 8711                            t.await
 8712                        })
 8713                    }),
 8714                    None => Task::ready(None),
 8715                })?
 8716                .await;
 8717            let (worktree_root_target, known_relative_path) =
 8718                if let Some((zip_root, relative_path)) = yarn_worktree {
 8719                    (zip_root, Some(relative_path))
 8720                } else {
 8721                    (Arc::<Path>::from(abs_path.as_path()), None)
 8722                };
 8723            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8724                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8725                    worktree_store.find_worktree(&worktree_root_target, cx)
 8726                })
 8727            })?;
 8728            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8729                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8730                (result.0, relative_path, None)
 8731            } else {
 8732                let worktree = lsp_store
 8733                    .update(cx, |lsp_store, cx| {
 8734                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8735                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8736                        })
 8737                    })?
 8738                    .await?;
 8739                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8740                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8741                    lsp_store
 8742                        .update(cx, |lsp_store, cx| {
 8743                            if let Some(local) = lsp_store.as_local_mut() {
 8744                                local.register_language_server_for_invisible_worktree(
 8745                                    &worktree,
 8746                                    language_server_id,
 8747                                    cx,
 8748                                )
 8749                            }
 8750                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8751                                Some(status) => status.worktree,
 8752                                None => None,
 8753                            }
 8754                        })
 8755                        .ok()
 8756                        .flatten()
 8757                        .zip(Some(worktree_root.clone()))
 8758                } else {
 8759                    None
 8760                };
 8761                let relative_path = if let Some(known_path) = known_relative_path {
 8762                    known_path
 8763                } else {
 8764                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8765                        .into_arc()
 8766                };
 8767                (worktree, relative_path, source_ws)
 8768            };
 8769            let project_path = ProjectPath {
 8770                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8771                path: relative_path,
 8772            };
 8773            let buffer = lsp_store
 8774                .update(cx, |lsp_store, cx| {
 8775                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8776                        buffer_store.open_buffer(project_path, cx)
 8777                    })
 8778                })?
 8779                .await?;
 8780            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8781            if let Some((source_ws, worktree_root)) = source_ws {
 8782                buffer.update(cx, |buffer, cx| {
 8783                    let settings = WorktreeSettings::get(
 8784                        Some(
 8785                            (&ProjectPath {
 8786                                worktree_id: source_ws,
 8787                                path: Arc::from(RelPath::empty()),
 8788                            })
 8789                                .into(),
 8790                        ),
 8791                        cx,
 8792                    );
 8793                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8794                    if is_read_only {
 8795                        buffer.set_capability(Capability::ReadOnly, cx);
 8796                    }
 8797                });
 8798            }
 8799            Ok(buffer)
 8800        })
 8801    }
 8802
 8803    fn local_lsp_servers_for_buffer(
 8804        &self,
 8805        buffer: &Entity<Buffer>,
 8806        cx: &mut Context<Self>,
 8807    ) -> Vec<LanguageServerId> {
 8808        let Some(local) = self.as_local() else {
 8809            return Vec::new();
 8810        };
 8811
 8812        let snapshot = buffer.read(cx).snapshot();
 8813
 8814        buffer.update(cx, |buffer, cx| {
 8815            local
 8816                .language_servers_for_buffer(buffer, cx)
 8817                .map(|(_, server)| server.server_id())
 8818                .filter(|server_id| {
 8819                    self.as_local().is_none_or(|local| {
 8820                        local
 8821                            .buffers_opened_in_servers
 8822                            .get(&snapshot.remote_id())
 8823                            .is_some_and(|servers| servers.contains(server_id))
 8824                    })
 8825                })
 8826                .collect()
 8827        })
 8828    }
 8829
 8830    fn request_multiple_lsp_locally<P, R>(
 8831        &mut self,
 8832        buffer: &Entity<Buffer>,
 8833        position: Option<P>,
 8834        request: R,
 8835        cx: &mut Context<Self>,
 8836    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8837    where
 8838        P: ToOffset,
 8839        R: LspCommand + Clone,
 8840        <R::LspRequest as lsp::request::Request>::Result: Send,
 8841        <R::LspRequest as lsp::request::Request>::Params: Send,
 8842    {
 8843        let Some(local) = self.as_local() else {
 8844            return Task::ready(Vec::new());
 8845        };
 8846
 8847        let snapshot = buffer.read(cx).snapshot();
 8848        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8849
 8850        let server_ids = buffer.update(cx, |buffer, cx| {
 8851            local
 8852                .language_servers_for_buffer(buffer, cx)
 8853                .filter(|(adapter, _)| {
 8854                    scope
 8855                        .as_ref()
 8856                        .map(|scope| scope.language_allowed(&adapter.name))
 8857                        .unwrap_or(true)
 8858                })
 8859                .map(|(_, server)| server.server_id())
 8860                .filter(|server_id| {
 8861                    self.as_local().is_none_or(|local| {
 8862                        local
 8863                            .buffers_opened_in_servers
 8864                            .get(&snapshot.remote_id())
 8865                            .is_some_and(|servers| servers.contains(server_id))
 8866                    })
 8867                })
 8868                .collect::<Vec<_>>()
 8869        });
 8870
 8871        let mut response_results = server_ids
 8872            .into_iter()
 8873            .map(|server_id| {
 8874                let task = self.request_lsp(
 8875                    buffer.clone(),
 8876                    LanguageServerToQuery::Other(server_id),
 8877                    request.clone(),
 8878                    cx,
 8879                );
 8880                async move { (server_id, task.await) }
 8881            })
 8882            .collect::<FuturesUnordered<_>>();
 8883
 8884        cx.background_spawn(async move {
 8885            let mut responses = Vec::with_capacity(response_results.len());
 8886            while let Some((server_id, response_result)) = response_results.next().await {
 8887                match response_result {
 8888                    Ok(response) => responses.push((server_id, response)),
 8889                    // rust-analyzer likes to error with this when its still loading up
 8890                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8891                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8892                }
 8893            }
 8894            responses
 8895        })
 8896    }
 8897
 8898    async fn handle_lsp_get_completions(
 8899        this: Entity<Self>,
 8900        envelope: TypedEnvelope<proto::GetCompletions>,
 8901        mut cx: AsyncApp,
 8902    ) -> Result<proto::GetCompletionsResponse> {
 8903        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8904
 8905        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8906        let buffer_handle = this.update(&mut cx, |this, cx| {
 8907            this.buffer_store.read(cx).get_existing(buffer_id)
 8908        })?;
 8909        let request = GetCompletions::from_proto(
 8910            envelope.payload,
 8911            this.clone(),
 8912            buffer_handle.clone(),
 8913            cx.clone(),
 8914        )
 8915        .await?;
 8916
 8917        let server_to_query = match request.server_id {
 8918            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8919            None => LanguageServerToQuery::FirstCapable,
 8920        };
 8921
 8922        let response = this
 8923            .update(&mut cx, |this, cx| {
 8924                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8925            })
 8926            .await?;
 8927        this.update(&mut cx, |this, cx| {
 8928            Ok(GetCompletions::response_to_proto(
 8929                response,
 8930                this,
 8931                sender_id,
 8932                &buffer_handle.read(cx).version(),
 8933                cx,
 8934            ))
 8935        })
 8936    }
 8937
 8938    async fn handle_lsp_command<T: LspCommand>(
 8939        this: Entity<Self>,
 8940        envelope: TypedEnvelope<T::ProtoRequest>,
 8941        mut cx: AsyncApp,
 8942    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8943    where
 8944        <T::LspRequest as lsp::request::Request>::Params: Send,
 8945        <T::LspRequest as lsp::request::Request>::Result: Send,
 8946    {
 8947        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8948        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8949        let buffer_handle = this.update(&mut cx, |this, cx| {
 8950            this.buffer_store.read(cx).get_existing(buffer_id)
 8951        })?;
 8952        let request = T::from_proto(
 8953            envelope.payload,
 8954            this.clone(),
 8955            buffer_handle.clone(),
 8956            cx.clone(),
 8957        )
 8958        .await?;
 8959        let response = this
 8960            .update(&mut cx, |this, cx| {
 8961                this.request_lsp(
 8962                    buffer_handle.clone(),
 8963                    LanguageServerToQuery::FirstCapable,
 8964                    request,
 8965                    cx,
 8966                )
 8967            })
 8968            .await?;
 8969        this.update(&mut cx, |this, cx| {
 8970            Ok(T::response_to_proto(
 8971                response,
 8972                this,
 8973                sender_id,
 8974                &buffer_handle.read(cx).version(),
 8975                cx,
 8976            ))
 8977        })
 8978    }
 8979
 8980    async fn handle_lsp_query(
 8981        lsp_store: Entity<Self>,
 8982        envelope: TypedEnvelope<proto::LspQuery>,
 8983        mut cx: AsyncApp,
 8984    ) -> Result<proto::Ack> {
 8985        use proto::lsp_query::Request;
 8986        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8987        let lsp_query = envelope.payload;
 8988        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8989        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8990        match lsp_query.request.context("invalid LSP query request")? {
 8991            Request::GetReferences(get_references) => {
 8992                let position = get_references.position.clone().and_then(deserialize_anchor);
 8993                Self::query_lsp_locally::<GetReferences>(
 8994                    lsp_store,
 8995                    server_id,
 8996                    sender_id,
 8997                    lsp_request_id,
 8998                    get_references,
 8999                    position,
 9000                    &mut cx,
 9001                )
 9002                .await?;
 9003            }
 9004            Request::GetDocumentColor(get_document_color) => {
 9005                Self::query_lsp_locally::<GetDocumentColor>(
 9006                    lsp_store,
 9007                    server_id,
 9008                    sender_id,
 9009                    lsp_request_id,
 9010                    get_document_color,
 9011                    None,
 9012                    &mut cx,
 9013                )
 9014                .await?;
 9015            }
 9016            Request::GetFoldingRanges(get_folding_ranges) => {
 9017                Self::query_lsp_locally::<GetFoldingRanges>(
 9018                    lsp_store,
 9019                    server_id,
 9020                    sender_id,
 9021                    lsp_request_id,
 9022                    get_folding_ranges,
 9023                    None,
 9024                    &mut cx,
 9025                )
 9026                .await?;
 9027            }
 9028            Request::GetDocumentSymbols(get_document_symbols) => {
 9029                Self::query_lsp_locally::<GetDocumentSymbols>(
 9030                    lsp_store,
 9031                    server_id,
 9032                    sender_id,
 9033                    lsp_request_id,
 9034                    get_document_symbols,
 9035                    None,
 9036                    &mut cx,
 9037                )
 9038                .await?;
 9039            }
 9040            Request::GetHover(get_hover) => {
 9041                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9042                Self::query_lsp_locally::<GetHover>(
 9043                    lsp_store,
 9044                    server_id,
 9045                    sender_id,
 9046                    lsp_request_id,
 9047                    get_hover,
 9048                    position,
 9049                    &mut cx,
 9050                )
 9051                .await?;
 9052            }
 9053            Request::GetCodeActions(get_code_actions) => {
 9054                Self::query_lsp_locally::<GetCodeActions>(
 9055                    lsp_store,
 9056                    server_id,
 9057                    sender_id,
 9058                    lsp_request_id,
 9059                    get_code_actions,
 9060                    None,
 9061                    &mut cx,
 9062                )
 9063                .await?;
 9064            }
 9065            Request::GetSignatureHelp(get_signature_help) => {
 9066                let position = get_signature_help
 9067                    .position
 9068                    .clone()
 9069                    .and_then(deserialize_anchor);
 9070                Self::query_lsp_locally::<GetSignatureHelp>(
 9071                    lsp_store,
 9072                    server_id,
 9073                    sender_id,
 9074                    lsp_request_id,
 9075                    get_signature_help,
 9076                    position,
 9077                    &mut cx,
 9078                )
 9079                .await?;
 9080            }
 9081            Request::GetCodeLens(get_code_lens) => {
 9082                Self::query_lsp_locally::<GetCodeLens>(
 9083                    lsp_store,
 9084                    server_id,
 9085                    sender_id,
 9086                    lsp_request_id,
 9087                    get_code_lens,
 9088                    None,
 9089                    &mut cx,
 9090                )
 9091                .await?;
 9092            }
 9093            Request::GetDefinition(get_definition) => {
 9094                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9095                Self::query_lsp_locally::<GetDefinitions>(
 9096                    lsp_store,
 9097                    server_id,
 9098                    sender_id,
 9099                    lsp_request_id,
 9100                    get_definition,
 9101                    position,
 9102                    &mut cx,
 9103                )
 9104                .await?;
 9105            }
 9106            Request::GetDeclaration(get_declaration) => {
 9107                let position = get_declaration
 9108                    .position
 9109                    .clone()
 9110                    .and_then(deserialize_anchor);
 9111                Self::query_lsp_locally::<GetDeclarations>(
 9112                    lsp_store,
 9113                    server_id,
 9114                    sender_id,
 9115                    lsp_request_id,
 9116                    get_declaration,
 9117                    position,
 9118                    &mut cx,
 9119                )
 9120                .await?;
 9121            }
 9122            Request::GetTypeDefinition(get_type_definition) => {
 9123                let position = get_type_definition
 9124                    .position
 9125                    .clone()
 9126                    .and_then(deserialize_anchor);
 9127                Self::query_lsp_locally::<GetTypeDefinitions>(
 9128                    lsp_store,
 9129                    server_id,
 9130                    sender_id,
 9131                    lsp_request_id,
 9132                    get_type_definition,
 9133                    position,
 9134                    &mut cx,
 9135                )
 9136                .await?;
 9137            }
 9138            Request::GetImplementation(get_implementation) => {
 9139                let position = get_implementation
 9140                    .position
 9141                    .clone()
 9142                    .and_then(deserialize_anchor);
 9143                Self::query_lsp_locally::<GetImplementations>(
 9144                    lsp_store,
 9145                    server_id,
 9146                    sender_id,
 9147                    lsp_request_id,
 9148                    get_implementation,
 9149                    position,
 9150                    &mut cx,
 9151                )
 9152                .await?;
 9153            }
 9154            Request::InlayHints(inlay_hints) => {
 9155                let query_start = inlay_hints
 9156                    .start
 9157                    .clone()
 9158                    .and_then(deserialize_anchor)
 9159                    .context("invalid inlay hints range start")?;
 9160                let query_end = inlay_hints
 9161                    .end
 9162                    .clone()
 9163                    .and_then(deserialize_anchor)
 9164                    .context("invalid inlay hints range end")?;
 9165                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9166                    &lsp_store,
 9167                    server_id,
 9168                    lsp_request_id,
 9169                    &inlay_hints,
 9170                    query_start..query_end,
 9171                    &mut cx,
 9172                )
 9173                .await
 9174                .context("preparing inlay hints request")?;
 9175                Self::query_lsp_locally::<InlayHints>(
 9176                    lsp_store,
 9177                    server_id,
 9178                    sender_id,
 9179                    lsp_request_id,
 9180                    inlay_hints,
 9181                    None,
 9182                    &mut cx,
 9183                )
 9184                .await
 9185                .context("querying for inlay hints")?
 9186            }
 9187            //////////////////////////////
 9188            // Below are LSP queries that need to fetch more data,
 9189            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9190            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9191                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9192                    &lsp_store,
 9193                    &get_document_diagnostics,
 9194                    &mut cx,
 9195                )
 9196                .await?;
 9197                lsp_store.update(&mut cx, |lsp_store, cx| {
 9198                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9199                    let key = LspKey {
 9200                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9201                        server_queried: server_id,
 9202                    };
 9203                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9204                    ) {
 9205                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9206                            lsp_requests.clear();
 9207                        };
 9208                    }
 9209
 9210                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9211                        lsp_request_id,
 9212                        cx.spawn(async move |lsp_store, cx| {
 9213                            let diagnostics_pull = lsp_store
 9214                                .update(cx, |lsp_store, cx| {
 9215                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9216                                })
 9217                                .ok();
 9218                            if let Some(diagnostics_pull) = diagnostics_pull {
 9219                                match diagnostics_pull.await {
 9220                                    Ok(()) => {}
 9221                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9222                                };
 9223                            }
 9224                        }),
 9225                    );
 9226                });
 9227            }
 9228            Request::SemanticTokens(semantic_tokens) => {
 9229                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9230                    &lsp_store,
 9231                    &semantic_tokens,
 9232                    &mut cx,
 9233                )
 9234                .await?;
 9235                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9236                lsp_store.update(&mut cx, |lsp_store, cx| {
 9237                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9238                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9239                        let key = LspKey {
 9240                            request_type: TypeId::of::<SemanticTokensFull>(),
 9241                            server_queried: server_id,
 9242                        };
 9243                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9244                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9245                                lsp_requests.clear();
 9246                            };
 9247                        }
 9248
 9249                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9250                            lsp_request_id,
 9251                            cx.spawn(async move |lsp_store, cx| {
 9252                                let tokens_fetch = lsp_store
 9253                                    .update(cx, |lsp_store, cx| {
 9254                                        lsp_store
 9255                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9256                                    })
 9257                                    .ok();
 9258                                if let Some(tokens_fetch) = tokens_fetch {
 9259                                    let new_tokens = tokens_fetch.await;
 9260                                    if let Some(new_tokens) = new_tokens {
 9261                                        lsp_store
 9262                                            .update(cx, |lsp_store, cx| {
 9263                                                let response = new_tokens
 9264                                                    .into_iter()
 9265                                                    .map(|(server_id, response)| {
 9266                                                        (
 9267                                                            server_id.to_proto(),
 9268                                                            SemanticTokensFull::response_to_proto(
 9269                                                                response,
 9270                                                                lsp_store,
 9271                                                                sender_id,
 9272                                                                &buffer_version,
 9273                                                                cx,
 9274                                                            ),
 9275                                                        )
 9276                                                    })
 9277                                                    .collect::<HashMap<_, _>>();
 9278                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9279                                                    project_id,
 9280                                                    lsp_request_id,
 9281                                                    response,
 9282                                                ) {
 9283                                                    Ok(()) => {}
 9284                                                    Err(e) => {
 9285                                                        log::error!(
 9286                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9287                                                        )
 9288                                                    }
 9289                                                }
 9290                                            })
 9291                                            .ok();
 9292                                    }
 9293                                }
 9294                            }),
 9295                        );
 9296                    }
 9297                });
 9298            }
 9299        }
 9300        Ok(proto::Ack {})
 9301    }
 9302
 9303    async fn handle_lsp_query_response(
 9304        lsp_store: Entity<Self>,
 9305        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9306        cx: AsyncApp,
 9307    ) -> Result<()> {
 9308        lsp_store.read_with(&cx, |lsp_store, _| {
 9309            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9310                upstream_client.handle_lsp_response(envelope.clone());
 9311            }
 9312        });
 9313        Ok(())
 9314    }
 9315
 9316    async fn handle_apply_code_action(
 9317        this: Entity<Self>,
 9318        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9319        mut cx: AsyncApp,
 9320    ) -> Result<proto::ApplyCodeActionResponse> {
 9321        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9322        let action =
 9323            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9324        let apply_code_action = this.update(&mut cx, |this, cx| {
 9325            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9326            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9327            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9328        })?;
 9329
 9330        let project_transaction = apply_code_action.await?;
 9331        let project_transaction = this.update(&mut cx, |this, cx| {
 9332            this.buffer_store.update(cx, |buffer_store, cx| {
 9333                buffer_store.serialize_project_transaction_for_peer(
 9334                    project_transaction,
 9335                    sender_id,
 9336                    cx,
 9337                )
 9338            })
 9339        });
 9340        Ok(proto::ApplyCodeActionResponse {
 9341            transaction: Some(project_transaction),
 9342        })
 9343    }
 9344
 9345    async fn handle_register_buffer_with_language_servers(
 9346        this: Entity<Self>,
 9347        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9348        mut cx: AsyncApp,
 9349    ) -> Result<proto::Ack> {
 9350        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9351        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9352        this.update(&mut cx, |this, cx| {
 9353            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9354                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9355                    project_id: upstream_project_id,
 9356                    buffer_id: buffer_id.to_proto(),
 9357                    only_servers: envelope.payload.only_servers,
 9358                });
 9359            }
 9360
 9361            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9362                anyhow::bail!("buffer is not open");
 9363            };
 9364
 9365            let handle = this.register_buffer_with_language_servers(
 9366                &buffer,
 9367                envelope
 9368                    .payload
 9369                    .only_servers
 9370                    .into_iter()
 9371                    .filter_map(|selector| {
 9372                        Some(match selector.selector? {
 9373                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9374                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9375                            }
 9376                            proto::language_server_selector::Selector::Name(name) => {
 9377                                LanguageServerSelector::Name(LanguageServerName(
 9378                                    SharedString::from(name),
 9379                                ))
 9380                            }
 9381                        })
 9382                    })
 9383                    .collect(),
 9384                false,
 9385                cx,
 9386            );
 9387            // Pull diagnostics for the buffer even if it was already registered.
 9388            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9389            // but it's unclear if we need it.
 9390            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9391                .detach();
 9392            this.buffer_store().update(cx, |buffer_store, _| {
 9393                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9394            });
 9395
 9396            Ok(())
 9397        })?;
 9398        Ok(proto::Ack {})
 9399    }
 9400
 9401    async fn handle_rename_project_entry(
 9402        this: Entity<Self>,
 9403        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9404        mut cx: AsyncApp,
 9405    ) -> Result<proto::ProjectEntryResponse> {
 9406        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9407        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9408        let new_path =
 9409            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9410
 9411        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9412            .update(&mut cx, |this, cx| {
 9413                let (worktree, entry) = this
 9414                    .worktree_store
 9415                    .read(cx)
 9416                    .worktree_and_entry_for_id(entry_id, cx)?;
 9417                let new_worktree = this
 9418                    .worktree_store
 9419                    .read(cx)
 9420                    .worktree_for_id(new_worktree_id, cx)?;
 9421                Some((
 9422                    this.worktree_store.clone(),
 9423                    worktree,
 9424                    new_worktree,
 9425                    entry.clone(),
 9426                ))
 9427            })
 9428            .context("worktree not found")?;
 9429        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9430            (worktree.absolutize(&old_entry.path), worktree.id())
 9431        });
 9432        let new_abs_path =
 9433            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9434
 9435        let _transaction = Self::will_rename_entry(
 9436            this.downgrade(),
 9437            old_worktree_id,
 9438            &old_abs_path,
 9439            &new_abs_path,
 9440            old_entry.is_dir(),
 9441            cx.clone(),
 9442        )
 9443        .await;
 9444        let response = WorktreeStore::handle_rename_project_entry(
 9445            worktree_store,
 9446            envelope.payload,
 9447            cx.clone(),
 9448        )
 9449        .await;
 9450        this.read_with(&cx, |this, _| {
 9451            this.did_rename_entry(
 9452                old_worktree_id,
 9453                &old_abs_path,
 9454                &new_abs_path,
 9455                old_entry.is_dir(),
 9456            );
 9457        });
 9458        response
 9459    }
 9460
 9461    async fn handle_update_diagnostic_summary(
 9462        this: Entity<Self>,
 9463        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9464        mut cx: AsyncApp,
 9465    ) -> Result<()> {
 9466        this.update(&mut cx, |lsp_store, cx| {
 9467            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9468            let mut updated_diagnostics_paths = HashMap::default();
 9469            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9470            for message_summary in envelope
 9471                .payload
 9472                .summary
 9473                .into_iter()
 9474                .chain(envelope.payload.more_summaries)
 9475            {
 9476                let project_path = ProjectPath {
 9477                    worktree_id,
 9478                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9479                };
 9480                let path = project_path.path.clone();
 9481                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9482                let summary = DiagnosticSummary {
 9483                    error_count: message_summary.error_count as usize,
 9484                    warning_count: message_summary.warning_count as usize,
 9485                };
 9486
 9487                if summary.is_empty() {
 9488                    if let Some(worktree_summaries) =
 9489                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9490                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9491                    {
 9492                        summaries.remove(&server_id);
 9493                        if summaries.is_empty() {
 9494                            worktree_summaries.remove(&path);
 9495                        }
 9496                    }
 9497                } else {
 9498                    lsp_store
 9499                        .diagnostic_summaries
 9500                        .entry(worktree_id)
 9501                        .or_default()
 9502                        .entry(path)
 9503                        .or_default()
 9504                        .insert(server_id, summary);
 9505                }
 9506
 9507                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9508                    match &mut diagnostics_summary {
 9509                        Some(diagnostics_summary) => {
 9510                            diagnostics_summary
 9511                                .more_summaries
 9512                                .push(proto::DiagnosticSummary {
 9513                                    path: project_path.path.as_ref().to_proto(),
 9514                                    language_server_id: server_id.0 as u64,
 9515                                    error_count: summary.error_count as u32,
 9516                                    warning_count: summary.warning_count as u32,
 9517                                })
 9518                        }
 9519                        None => {
 9520                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9521                                project_id: *project_id,
 9522                                worktree_id: worktree_id.to_proto(),
 9523                                summary: Some(proto::DiagnosticSummary {
 9524                                    path: project_path.path.as_ref().to_proto(),
 9525                                    language_server_id: server_id.0 as u64,
 9526                                    error_count: summary.error_count as u32,
 9527                                    warning_count: summary.warning_count as u32,
 9528                                }),
 9529                                more_summaries: Vec::new(),
 9530                            })
 9531                        }
 9532                    }
 9533                }
 9534                updated_diagnostics_paths
 9535                    .entry(server_id)
 9536                    .or_insert_with(Vec::new)
 9537                    .push(project_path);
 9538            }
 9539
 9540            if let Some((diagnostics_summary, (downstream_client, _))) =
 9541                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9542            {
 9543                downstream_client.send(diagnostics_summary).log_err();
 9544            }
 9545            for (server_id, paths) in updated_diagnostics_paths {
 9546                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9547            }
 9548            Ok(())
 9549        })
 9550    }
 9551
 9552    async fn handle_start_language_server(
 9553        lsp_store: Entity<Self>,
 9554        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9555        mut cx: AsyncApp,
 9556    ) -> Result<()> {
 9557        let server = envelope.payload.server.context("invalid server")?;
 9558        let server_capabilities =
 9559            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9560                .with_context(|| {
 9561                    format!(
 9562                        "incorrect server capabilities {}",
 9563                        envelope.payload.capabilities
 9564                    )
 9565                })?;
 9566        lsp_store.update(&mut cx, |lsp_store, cx| {
 9567            let server_id = LanguageServerId(server.id as usize);
 9568            let server_name = LanguageServerName::from_proto(server.name.clone());
 9569            lsp_store
 9570                .lsp_server_capabilities
 9571                .insert(server_id, server_capabilities);
 9572            lsp_store.language_server_statuses.insert(
 9573                server_id,
 9574                LanguageServerStatus {
 9575                    name: server_name.clone(),
 9576                    server_version: None,
 9577                    server_readable_version: None,
 9578                    pending_work: Default::default(),
 9579                    has_pending_diagnostic_updates: false,
 9580                    progress_tokens: Default::default(),
 9581                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9582                    binary: None,
 9583                    configuration: None,
 9584                    workspace_folders: BTreeSet::new(),
 9585                    process_id: None,
 9586                },
 9587            );
 9588            cx.emit(LspStoreEvent::LanguageServerAdded(
 9589                server_id,
 9590                server_name,
 9591                server.worktree_id.map(WorktreeId::from_proto),
 9592            ));
 9593            cx.notify();
 9594        });
 9595        Ok(())
 9596    }
 9597
 9598    async fn handle_update_language_server(
 9599        lsp_store: Entity<Self>,
 9600        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9601        mut cx: AsyncApp,
 9602    ) -> Result<()> {
 9603        lsp_store.update(&mut cx, |lsp_store, cx| {
 9604            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9605
 9606            match envelope.payload.variant.context("invalid variant")? {
 9607                proto::update_language_server::Variant::WorkStart(payload) => {
 9608                    lsp_store.on_lsp_work_start(
 9609                        language_server_id,
 9610                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9611                            .context("invalid progress token value")?,
 9612                        LanguageServerProgress {
 9613                            title: payload.title,
 9614                            is_disk_based_diagnostics_progress: false,
 9615                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9616                            message: payload.message,
 9617                            percentage: payload.percentage.map(|p| p as usize),
 9618                            last_update_at: cx.background_executor().now(),
 9619                        },
 9620                        cx,
 9621                    );
 9622                }
 9623                proto::update_language_server::Variant::WorkProgress(payload) => {
 9624                    lsp_store.on_lsp_work_progress(
 9625                        language_server_id,
 9626                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9627                            .context("invalid progress token value")?,
 9628                        LanguageServerProgress {
 9629                            title: None,
 9630                            is_disk_based_diagnostics_progress: false,
 9631                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9632                            message: payload.message,
 9633                            percentage: payload.percentage.map(|p| p as usize),
 9634                            last_update_at: cx.background_executor().now(),
 9635                        },
 9636                        cx,
 9637                    );
 9638                }
 9639
 9640                proto::update_language_server::Variant::WorkEnd(payload) => {
 9641                    lsp_store.on_lsp_work_end(
 9642                        language_server_id,
 9643                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9644                            .context("invalid progress token value")?,
 9645                        cx,
 9646                    );
 9647                }
 9648
 9649                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9650                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9651                }
 9652
 9653                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9654                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9655                }
 9656
 9657                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9658                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9659                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9660                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9661                        language_server_id,
 9662                        name: envelope
 9663                            .payload
 9664                            .server_name
 9665                            .map(SharedString::new)
 9666                            .map(LanguageServerName),
 9667                        message: non_lsp,
 9668                    });
 9669                }
 9670            }
 9671
 9672            Ok(())
 9673        })
 9674    }
 9675
 9676    async fn handle_language_server_log(
 9677        this: Entity<Self>,
 9678        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9679        mut cx: AsyncApp,
 9680    ) -> Result<()> {
 9681        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9682        let log_type = envelope
 9683            .payload
 9684            .log_type
 9685            .map(LanguageServerLogType::from_proto)
 9686            .context("invalid language server log type")?;
 9687
 9688        let message = envelope.payload.message;
 9689
 9690        this.update(&mut cx, |_, cx| {
 9691            cx.emit(LspStoreEvent::LanguageServerLog(
 9692                language_server_id,
 9693                log_type,
 9694                message,
 9695            ));
 9696        });
 9697        Ok(())
 9698    }
 9699
 9700    async fn handle_lsp_ext_cancel_flycheck(
 9701        lsp_store: Entity<Self>,
 9702        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9703        cx: AsyncApp,
 9704    ) -> Result<proto::Ack> {
 9705        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9706        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9707            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9708                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9709            } else {
 9710                None
 9711            }
 9712        });
 9713        if let Some(task) = task {
 9714            task.context("handling lsp ext cancel flycheck")?;
 9715        }
 9716
 9717        Ok(proto::Ack {})
 9718    }
 9719
 9720    async fn handle_lsp_ext_run_flycheck(
 9721        lsp_store: Entity<Self>,
 9722        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9723        mut cx: AsyncApp,
 9724    ) -> Result<proto::Ack> {
 9725        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9726        lsp_store.update(&mut cx, |lsp_store, cx| {
 9727            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9728                let text_document = if envelope.payload.current_file_only {
 9729                    let buffer_id = envelope
 9730                        .payload
 9731                        .buffer_id
 9732                        .map(|id| BufferId::new(id))
 9733                        .transpose()?;
 9734                    buffer_id
 9735                        .and_then(|buffer_id| {
 9736                            lsp_store
 9737                                .buffer_store()
 9738                                .read(cx)
 9739                                .get(buffer_id)
 9740                                .and_then(|buffer| {
 9741                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9742                                })
 9743                                .map(|path| make_text_document_identifier(&path))
 9744                        })
 9745                        .transpose()?
 9746                } else {
 9747                    None
 9748                };
 9749                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9750                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9751                )?;
 9752            }
 9753            anyhow::Ok(())
 9754        })?;
 9755
 9756        Ok(proto::Ack {})
 9757    }
 9758
 9759    async fn handle_lsp_ext_clear_flycheck(
 9760        lsp_store: Entity<Self>,
 9761        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9762        cx: AsyncApp,
 9763    ) -> Result<proto::Ack> {
 9764        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9765        lsp_store.read_with(&cx, |lsp_store, _| {
 9766            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9767                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9768            } else {
 9769                None
 9770            }
 9771        });
 9772
 9773        Ok(proto::Ack {})
 9774    }
 9775
 9776    pub fn disk_based_diagnostics_started(
 9777        &mut self,
 9778        language_server_id: LanguageServerId,
 9779        cx: &mut Context<Self>,
 9780    ) {
 9781        if let Some(language_server_status) =
 9782            self.language_server_statuses.get_mut(&language_server_id)
 9783        {
 9784            language_server_status.has_pending_diagnostic_updates = true;
 9785        }
 9786
 9787        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9788        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9789            language_server_id,
 9790            name: self
 9791                .language_server_adapter_for_id(language_server_id)
 9792                .map(|adapter| adapter.name()),
 9793            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9794                Default::default(),
 9795            ),
 9796        })
 9797    }
 9798
 9799    pub fn disk_based_diagnostics_finished(
 9800        &mut self,
 9801        language_server_id: LanguageServerId,
 9802        cx: &mut Context<Self>,
 9803    ) {
 9804        if let Some(language_server_status) =
 9805            self.language_server_statuses.get_mut(&language_server_id)
 9806        {
 9807            language_server_status.has_pending_diagnostic_updates = false;
 9808        }
 9809
 9810        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9811        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9812            language_server_id,
 9813            name: self
 9814                .language_server_adapter_for_id(language_server_id)
 9815                .map(|adapter| adapter.name()),
 9816            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9817                Default::default(),
 9818            ),
 9819        })
 9820    }
 9821
 9822    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9823    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9824    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9825    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9826    // the language server might take some time to publish diagnostics.
 9827    fn simulate_disk_based_diagnostics_events_if_needed(
 9828        &mut self,
 9829        language_server_id: LanguageServerId,
 9830        cx: &mut Context<Self>,
 9831    ) {
 9832        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9833
 9834        let Some(LanguageServerState::Running {
 9835            simulate_disk_based_diagnostics_completion,
 9836            adapter,
 9837            ..
 9838        }) = self
 9839            .as_local_mut()
 9840            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9841        else {
 9842            return;
 9843        };
 9844
 9845        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9846            return;
 9847        }
 9848
 9849        let prev_task =
 9850            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9851                cx.background_executor()
 9852                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9853                    .await;
 9854
 9855                this.update(cx, |this, cx| {
 9856                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9857
 9858                    if let Some(LanguageServerState::Running {
 9859                        simulate_disk_based_diagnostics_completion,
 9860                        ..
 9861                    }) = this.as_local_mut().and_then(|local_store| {
 9862                        local_store.language_servers.get_mut(&language_server_id)
 9863                    }) {
 9864                        *simulate_disk_based_diagnostics_completion = None;
 9865                    }
 9866                })
 9867                .ok();
 9868            }));
 9869
 9870        if prev_task.is_none() {
 9871            self.disk_based_diagnostics_started(language_server_id, cx);
 9872        }
 9873    }
 9874
 9875    pub fn language_server_statuses(
 9876        &self,
 9877    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9878        self.language_server_statuses
 9879            .iter()
 9880            .map(|(key, value)| (*key, value))
 9881    }
 9882
 9883    pub(super) fn did_rename_entry(
 9884        &self,
 9885        worktree_id: WorktreeId,
 9886        old_path: &Path,
 9887        new_path: &Path,
 9888        is_dir: bool,
 9889    ) {
 9890        maybe!({
 9891            let local_store = self.as_local()?;
 9892
 9893            let old_uri = lsp::Uri::from_file_path(old_path)
 9894                .ok()
 9895                .map(|uri| uri.to_string())?;
 9896            let new_uri = lsp::Uri::from_file_path(new_path)
 9897                .ok()
 9898                .map(|uri| uri.to_string())?;
 9899
 9900            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9901                let Some(filter) = local_store
 9902                    .language_server_paths_watched_for_rename
 9903                    .get(&language_server.server_id())
 9904                else {
 9905                    continue;
 9906                };
 9907
 9908                if filter.should_send_did_rename(&old_uri, is_dir) {
 9909                    language_server
 9910                        .notify::<DidRenameFiles>(RenameFilesParams {
 9911                            files: vec![FileRename {
 9912                                old_uri: old_uri.clone(),
 9913                                new_uri: new_uri.clone(),
 9914                            }],
 9915                        })
 9916                        .ok();
 9917                }
 9918            }
 9919            Some(())
 9920        });
 9921    }
 9922
 9923    pub(super) fn will_rename_entry(
 9924        this: WeakEntity<Self>,
 9925        worktree_id: WorktreeId,
 9926        old_path: &Path,
 9927        new_path: &Path,
 9928        is_dir: bool,
 9929        cx: AsyncApp,
 9930    ) -> Task<ProjectTransaction> {
 9931        let old_uri = lsp::Uri::from_file_path(old_path)
 9932            .ok()
 9933            .map(|uri| uri.to_string());
 9934        let new_uri = lsp::Uri::from_file_path(new_path)
 9935            .ok()
 9936            .map(|uri| uri.to_string());
 9937        cx.spawn(async move |cx| {
 9938            let mut tasks = vec![];
 9939            this.update(cx, |this, cx| {
 9940                let local_store = this.as_local()?;
 9941                let old_uri = old_uri?;
 9942                let new_uri = new_uri?;
 9943                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9944                    let Some(filter) = local_store
 9945                        .language_server_paths_watched_for_rename
 9946                        .get(&language_server.server_id())
 9947                    else {
 9948                        continue;
 9949                    };
 9950
 9951                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9952                        continue;
 9953                    }
 9954                    let request_timeout = ProjectSettings::get_global(cx)
 9955                        .global_lsp_settings
 9956                        .get_request_timeout();
 9957
 9958                    let apply_edit = cx.spawn({
 9959                        let old_uri = old_uri.clone();
 9960                        let new_uri = new_uri.clone();
 9961                        let language_server = language_server.clone();
 9962                        async move |this, cx| {
 9963                            let edit = language_server
 9964                                .request::<WillRenameFiles>(
 9965                                    RenameFilesParams {
 9966                                        files: vec![FileRename { old_uri, new_uri }],
 9967                                    },
 9968                                    request_timeout,
 9969                                )
 9970                                .await
 9971                                .into_response()
 9972                                .context("will rename files")
 9973                                .log_err()
 9974                                .flatten()?;
 9975
 9976                            LocalLspStore::deserialize_workspace_edit(
 9977                                this.upgrade()?,
 9978                                edit,
 9979                                false,
 9980                                language_server.clone(),
 9981                                cx,
 9982                            )
 9983                            .await
 9984                            .ok()
 9985                        }
 9986                    });
 9987                    tasks.push(apply_edit);
 9988                }
 9989                Some(())
 9990            })
 9991            .ok()
 9992            .flatten();
 9993            let mut merged_transaction = ProjectTransaction::default();
 9994            for task in tasks {
 9995                // Await on tasks sequentially so that the order of application of edits is deterministic
 9996                // (at least with regards to the order of registration of language servers)
 9997                if let Some(transaction) = task.await {
 9998                    for (buffer, buffer_transaction) in transaction.0 {
 9999                        merged_transaction.0.insert(buffer, buffer_transaction);
10000                    }
10001                }
10002            }
10003            merged_transaction
10004        })
10005    }
10006
10007    fn lsp_notify_abs_paths_changed(
10008        &mut self,
10009        server_id: LanguageServerId,
10010        changes: Vec<PathEvent>,
10011    ) {
10012        maybe!({
10013            let server = self.language_server_for_id(server_id)?;
10014            let changes = changes
10015                .into_iter()
10016                .filter_map(|event| {
10017                    let typ = match event.kind? {
10018                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10019                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10020                        PathEventKind::Changed | PathEventKind::Rescan => {
10021                            lsp::FileChangeType::CHANGED
10022                        }
10023                    };
10024                    Some(lsp::FileEvent {
10025                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10026                        typ,
10027                    })
10028                })
10029                .collect::<Vec<_>>();
10030            if !changes.is_empty() {
10031                server
10032                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10033                        lsp::DidChangeWatchedFilesParams { changes },
10034                    )
10035                    .ok();
10036            }
10037            Some(())
10038        });
10039    }
10040
10041    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10042        self.as_local()?.language_server_for_id(id)
10043    }
10044
10045    fn on_lsp_progress(
10046        &mut self,
10047        progress_params: lsp::ProgressParams,
10048        language_server_id: LanguageServerId,
10049        disk_based_diagnostics_progress_token: Option<String>,
10050        cx: &mut Context<Self>,
10051    ) {
10052        match progress_params.value {
10053            lsp::ProgressParamsValue::WorkDone(progress) => {
10054                self.handle_work_done_progress(
10055                    progress,
10056                    language_server_id,
10057                    disk_based_diagnostics_progress_token,
10058                    ProgressToken::from_lsp(progress_params.token),
10059                    cx,
10060                );
10061            }
10062            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10063                let registration_id = match progress_params.token {
10064                    lsp::NumberOrString::Number(_) => None,
10065                    lsp::NumberOrString::String(token) => token
10066                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10067                        .map(|(_, id)| id.to_owned()),
10068                };
10069                if let Some(LanguageServerState::Running {
10070                    workspace_diagnostics_refresh_tasks,
10071                    ..
10072                }) = self
10073                    .as_local_mut()
10074                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10075                    && let Some(workspace_diagnostics) =
10076                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10077                {
10078                    workspace_diagnostics.progress_tx.try_send(()).ok();
10079                    self.apply_workspace_diagnostic_report(
10080                        language_server_id,
10081                        report,
10082                        registration_id.map(SharedString::from),
10083                        cx,
10084                    )
10085                }
10086            }
10087        }
10088    }
10089
10090    fn handle_work_done_progress(
10091        &mut self,
10092        progress: lsp::WorkDoneProgress,
10093        language_server_id: LanguageServerId,
10094        disk_based_diagnostics_progress_token: Option<String>,
10095        token: ProgressToken,
10096        cx: &mut Context<Self>,
10097    ) {
10098        let language_server_status =
10099            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10100                status
10101            } else {
10102                return;
10103            };
10104
10105        if !language_server_status.progress_tokens.contains(&token) {
10106            return;
10107        }
10108
10109        let is_disk_based_diagnostics_progress =
10110            if let (Some(disk_based_token), ProgressToken::String(token)) =
10111                (&disk_based_diagnostics_progress_token, &token)
10112            {
10113                token.starts_with(disk_based_token)
10114            } else {
10115                false
10116            };
10117
10118        match progress {
10119            lsp::WorkDoneProgress::Begin(report) => {
10120                if is_disk_based_diagnostics_progress {
10121                    self.disk_based_diagnostics_started(language_server_id, cx);
10122                }
10123                self.on_lsp_work_start(
10124                    language_server_id,
10125                    token.clone(),
10126                    LanguageServerProgress {
10127                        title: Some(report.title),
10128                        is_disk_based_diagnostics_progress,
10129                        is_cancellable: report.cancellable.unwrap_or(false),
10130                        message: report.message.clone(),
10131                        percentage: report.percentage.map(|p| p as usize),
10132                        last_update_at: cx.background_executor().now(),
10133                    },
10134                    cx,
10135                );
10136            }
10137            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10138                language_server_id,
10139                token,
10140                LanguageServerProgress {
10141                    title: None,
10142                    is_disk_based_diagnostics_progress,
10143                    is_cancellable: report.cancellable.unwrap_or(false),
10144                    message: report.message,
10145                    percentage: report.percentage.map(|p| p as usize),
10146                    last_update_at: cx.background_executor().now(),
10147                },
10148                cx,
10149            ),
10150            lsp::WorkDoneProgress::End(_) => {
10151                language_server_status.progress_tokens.remove(&token);
10152                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10153                if is_disk_based_diagnostics_progress {
10154                    self.disk_based_diagnostics_finished(language_server_id, cx);
10155                }
10156            }
10157        }
10158    }
10159
10160    fn on_lsp_work_start(
10161        &mut self,
10162        language_server_id: LanguageServerId,
10163        token: ProgressToken,
10164        progress: LanguageServerProgress,
10165        cx: &mut Context<Self>,
10166    ) {
10167        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10168            status.pending_work.insert(token.clone(), progress.clone());
10169            cx.notify();
10170        }
10171        cx.emit(LspStoreEvent::LanguageServerUpdate {
10172            language_server_id,
10173            name: self
10174                .language_server_adapter_for_id(language_server_id)
10175                .map(|adapter| adapter.name()),
10176            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10177                token: Some(token.to_proto()),
10178                title: progress.title,
10179                message: progress.message,
10180                percentage: progress.percentage.map(|p| p as u32),
10181                is_cancellable: Some(progress.is_cancellable),
10182            }),
10183        })
10184    }
10185
10186    fn on_lsp_work_progress(
10187        &mut self,
10188        language_server_id: LanguageServerId,
10189        token: ProgressToken,
10190        progress: LanguageServerProgress,
10191        cx: &mut Context<Self>,
10192    ) {
10193        let mut did_update = false;
10194        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10195            match status.pending_work.entry(token.clone()) {
10196                btree_map::Entry::Vacant(entry) => {
10197                    entry.insert(progress.clone());
10198                    did_update = true;
10199                }
10200                btree_map::Entry::Occupied(mut entry) => {
10201                    let entry = entry.get_mut();
10202                    if (progress.last_update_at - entry.last_update_at)
10203                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10204                    {
10205                        entry.last_update_at = progress.last_update_at;
10206                        if progress.message.is_some() {
10207                            entry.message = progress.message.clone();
10208                        }
10209                        if progress.percentage.is_some() {
10210                            entry.percentage = progress.percentage;
10211                        }
10212                        if progress.is_cancellable != entry.is_cancellable {
10213                            entry.is_cancellable = progress.is_cancellable;
10214                        }
10215                        did_update = true;
10216                    }
10217                }
10218            }
10219        }
10220
10221        if did_update {
10222            cx.emit(LspStoreEvent::LanguageServerUpdate {
10223                language_server_id,
10224                name: self
10225                    .language_server_adapter_for_id(language_server_id)
10226                    .map(|adapter| adapter.name()),
10227                message: proto::update_language_server::Variant::WorkProgress(
10228                    proto::LspWorkProgress {
10229                        token: Some(token.to_proto()),
10230                        message: progress.message,
10231                        percentage: progress.percentage.map(|p| p as u32),
10232                        is_cancellable: Some(progress.is_cancellable),
10233                    },
10234                ),
10235            })
10236        }
10237    }
10238
10239    fn on_lsp_work_end(
10240        &mut self,
10241        language_server_id: LanguageServerId,
10242        token: ProgressToken,
10243        cx: &mut Context<Self>,
10244    ) {
10245        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10246            if let Some(work) = status.pending_work.remove(&token)
10247                && !work.is_disk_based_diagnostics_progress
10248            {
10249                cx.emit(LspStoreEvent::RefreshInlayHints {
10250                    server_id: language_server_id,
10251                    request_id: None,
10252                });
10253            }
10254            cx.notify();
10255        }
10256
10257        cx.emit(LspStoreEvent::LanguageServerUpdate {
10258            language_server_id,
10259            name: self
10260                .language_server_adapter_for_id(language_server_id)
10261                .map(|adapter| adapter.name()),
10262            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10263                token: Some(token.to_proto()),
10264            }),
10265        })
10266    }
10267
10268    pub async fn handle_resolve_completion_documentation(
10269        this: Entity<Self>,
10270        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10271        mut cx: AsyncApp,
10272    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10273        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10274
10275        let completion = this
10276            .read_with(&cx, |this, cx| {
10277                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10278                let server = this
10279                    .language_server_for_id(id)
10280                    .with_context(|| format!("No language server {id}"))?;
10281
10282                let request_timeout = ProjectSettings::get_global(cx)
10283                    .global_lsp_settings
10284                    .get_request_timeout();
10285
10286                anyhow::Ok(cx.background_spawn(async move {
10287                    let can_resolve = server
10288                        .capabilities()
10289                        .completion_provider
10290                        .as_ref()
10291                        .and_then(|options| options.resolve_provider)
10292                        .unwrap_or(false);
10293                    if can_resolve {
10294                        server
10295                            .request::<lsp::request::ResolveCompletionItem>(
10296                                lsp_completion,
10297                                request_timeout,
10298                            )
10299                            .await
10300                            .into_response()
10301                            .context("resolve completion item")
10302                    } else {
10303                        anyhow::Ok(lsp_completion)
10304                    }
10305                }))
10306            })?
10307            .await?;
10308
10309        let mut documentation_is_markdown = false;
10310        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10311        let documentation = match completion.documentation {
10312            Some(lsp::Documentation::String(text)) => text,
10313
10314            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10315                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10316                value
10317            }
10318
10319            _ => String::new(),
10320        };
10321
10322        // If we have a new buffer_id, that means we're talking to a new client
10323        // and want to check for new text_edits in the completion too.
10324        let mut old_replace_start = None;
10325        let mut old_replace_end = None;
10326        let mut old_insert_start = None;
10327        let mut old_insert_end = None;
10328        let mut new_text = String::default();
10329        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10330            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10331                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10332                anyhow::Ok(buffer.read(cx).snapshot())
10333            })?;
10334
10335            if let Some(text_edit) = completion.text_edit.as_ref() {
10336                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10337
10338                if let Some(mut edit) = edit {
10339                    LineEnding::normalize(&mut edit.new_text);
10340
10341                    new_text = edit.new_text;
10342                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10343                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10344                    if let Some(insert_range) = edit.insert_range {
10345                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10346                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10347                    }
10348                }
10349            }
10350        }
10351
10352        Ok(proto::ResolveCompletionDocumentationResponse {
10353            documentation,
10354            documentation_is_markdown,
10355            old_replace_start,
10356            old_replace_end,
10357            new_text,
10358            lsp_completion,
10359            old_insert_start,
10360            old_insert_end,
10361        })
10362    }
10363
10364    async fn handle_on_type_formatting(
10365        this: Entity<Self>,
10366        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10367        mut cx: AsyncApp,
10368    ) -> Result<proto::OnTypeFormattingResponse> {
10369        let on_type_formatting = this.update(&mut cx, |this, cx| {
10370            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10371            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10372            let position = envelope
10373                .payload
10374                .position
10375                .and_then(deserialize_anchor)
10376                .context("invalid position")?;
10377            anyhow::Ok(this.apply_on_type_formatting(
10378                buffer,
10379                position,
10380                envelope.payload.trigger.clone(),
10381                cx,
10382            ))
10383        })?;
10384
10385        let transaction = on_type_formatting
10386            .await?
10387            .as_ref()
10388            .map(language::proto::serialize_transaction);
10389        Ok(proto::OnTypeFormattingResponse { transaction })
10390    }
10391
10392    async fn handle_pull_workspace_diagnostics(
10393        lsp_store: Entity<Self>,
10394        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10395        mut cx: AsyncApp,
10396    ) -> Result<proto::Ack> {
10397        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10398        lsp_store.update(&mut cx, |lsp_store, _| {
10399            lsp_store.pull_workspace_diagnostics(server_id);
10400        });
10401        Ok(proto::Ack {})
10402    }
10403
10404    async fn handle_open_buffer_for_symbol(
10405        this: Entity<Self>,
10406        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10407        mut cx: AsyncApp,
10408    ) -> Result<proto::OpenBufferForSymbolResponse> {
10409        let peer_id = envelope.original_sender_id().unwrap_or_default();
10410        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10411        let symbol = Self::deserialize_symbol(symbol)?;
10412        this.read_with(&cx, |this, _| {
10413            if let SymbolLocation::OutsideProject {
10414                abs_path,
10415                signature,
10416            } = &symbol.path
10417            {
10418                let new_signature = this.symbol_signature(&abs_path);
10419                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10420            }
10421            Ok(())
10422        })?;
10423        let buffer = this
10424            .update(&mut cx, |this, cx| {
10425                this.open_buffer_for_symbol(
10426                    &Symbol {
10427                        language_server_name: symbol.language_server_name,
10428                        source_worktree_id: symbol.source_worktree_id,
10429                        source_language_server_id: symbol.source_language_server_id,
10430                        path: symbol.path,
10431                        name: symbol.name,
10432                        kind: symbol.kind,
10433                        range: symbol.range,
10434                        label: CodeLabel::default(),
10435                        container_name: symbol.container_name,
10436                    },
10437                    cx,
10438                )
10439            })
10440            .await?;
10441
10442        this.update(&mut cx, |this, cx| {
10443            let is_private = buffer
10444                .read(cx)
10445                .file()
10446                .map(|f| f.is_private())
10447                .unwrap_or_default();
10448            if is_private {
10449                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10450            } else {
10451                this.buffer_store
10452                    .update(cx, |buffer_store, cx| {
10453                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10454                    })
10455                    .detach_and_log_err(cx);
10456                let buffer_id = buffer.read(cx).remote_id().to_proto();
10457                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10458            }
10459        })
10460    }
10461
10462    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10463        let mut hasher = Sha256::new();
10464        hasher.update(abs_path.to_string_lossy().as_bytes());
10465        hasher.update(self.nonce.to_be_bytes());
10466        hasher.finalize().as_slice().try_into().unwrap()
10467    }
10468
10469    pub async fn handle_get_project_symbols(
10470        this: Entity<Self>,
10471        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10472        mut cx: AsyncApp,
10473    ) -> Result<proto::GetProjectSymbolsResponse> {
10474        let symbols = this
10475            .update(&mut cx, |this, cx| {
10476                this.symbols(&envelope.payload.query, cx)
10477            })
10478            .await?;
10479
10480        Ok(proto::GetProjectSymbolsResponse {
10481            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10482        })
10483    }
10484
10485    pub async fn handle_restart_language_servers(
10486        this: Entity<Self>,
10487        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10488        mut cx: AsyncApp,
10489    ) -> Result<proto::Ack> {
10490        this.update(&mut cx, |lsp_store, cx| {
10491            let buffers =
10492                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10493            lsp_store.restart_language_servers_for_buffers(
10494                buffers,
10495                envelope
10496                    .payload
10497                    .only_servers
10498                    .into_iter()
10499                    .filter_map(|selector| {
10500                        Some(match selector.selector? {
10501                            proto::language_server_selector::Selector::ServerId(server_id) => {
10502                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10503                            }
10504                            proto::language_server_selector::Selector::Name(name) => {
10505                                LanguageServerSelector::Name(LanguageServerName(
10506                                    SharedString::from(name),
10507                                ))
10508                            }
10509                        })
10510                    })
10511                    .collect(),
10512                cx,
10513            );
10514        });
10515
10516        Ok(proto::Ack {})
10517    }
10518
10519    pub async fn handle_stop_language_servers(
10520        lsp_store: Entity<Self>,
10521        envelope: TypedEnvelope<proto::StopLanguageServers>,
10522        mut cx: AsyncApp,
10523    ) -> Result<proto::Ack> {
10524        lsp_store.update(&mut cx, |lsp_store, cx| {
10525            if envelope.payload.all
10526                && envelope.payload.also_servers.is_empty()
10527                && envelope.payload.buffer_ids.is_empty()
10528            {
10529                lsp_store.stop_all_language_servers(cx);
10530            } else {
10531                let buffers =
10532                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10533                lsp_store
10534                    .stop_language_servers_for_buffers(
10535                        buffers,
10536                        envelope
10537                            .payload
10538                            .also_servers
10539                            .into_iter()
10540                            .filter_map(|selector| {
10541                                Some(match selector.selector? {
10542                                    proto::language_server_selector::Selector::ServerId(
10543                                        server_id,
10544                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10545                                        server_id,
10546                                    )),
10547                                    proto::language_server_selector::Selector::Name(name) => {
10548                                        LanguageServerSelector::Name(LanguageServerName(
10549                                            SharedString::from(name),
10550                                        ))
10551                                    }
10552                                })
10553                            })
10554                            .collect(),
10555                        cx,
10556                    )
10557                    .detach_and_log_err(cx);
10558            }
10559        });
10560
10561        Ok(proto::Ack {})
10562    }
10563
10564    pub async fn handle_cancel_language_server_work(
10565        lsp_store: Entity<Self>,
10566        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10567        mut cx: AsyncApp,
10568    ) -> Result<proto::Ack> {
10569        lsp_store.update(&mut cx, |lsp_store, cx| {
10570            if let Some(work) = envelope.payload.work {
10571                match work {
10572                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10573                        let buffers =
10574                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10575                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10576                    }
10577                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10578                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10579                        let token = work
10580                            .token
10581                            .map(|token| {
10582                                ProgressToken::from_proto(token)
10583                                    .context("invalid work progress token")
10584                            })
10585                            .transpose()?;
10586                        lsp_store.cancel_language_server_work(server_id, token, cx);
10587                    }
10588                }
10589            }
10590            anyhow::Ok(())
10591        })?;
10592
10593        Ok(proto::Ack {})
10594    }
10595
10596    fn buffer_ids_to_buffers(
10597        &mut self,
10598        buffer_ids: impl Iterator<Item = u64>,
10599        cx: &mut Context<Self>,
10600    ) -> Vec<Entity<Buffer>> {
10601        buffer_ids
10602            .into_iter()
10603            .flat_map(|buffer_id| {
10604                self.buffer_store
10605                    .read(cx)
10606                    .get(BufferId::new(buffer_id).log_err()?)
10607            })
10608            .collect::<Vec<_>>()
10609    }
10610
10611    async fn handle_apply_additional_edits_for_completion(
10612        this: Entity<Self>,
10613        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10614        mut cx: AsyncApp,
10615    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10616        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10617            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10618            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10619            let completion = Self::deserialize_completion(
10620                envelope.payload.completion.context("invalid completion")?,
10621            )?;
10622            let all_commit_ranges = envelope
10623                .payload
10624                .all_commit_ranges
10625                .into_iter()
10626                .map(language::proto::deserialize_anchor_range)
10627                .collect::<Result<Vec<_>, _>>()?;
10628            anyhow::Ok((buffer, completion, all_commit_ranges))
10629        })?;
10630
10631        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10632            this.apply_additional_edits_for_completion(
10633                buffer,
10634                Rc::new(RefCell::new(Box::new([Completion {
10635                    replace_range: completion.replace_range,
10636                    new_text: completion.new_text,
10637                    source: completion.source,
10638                    documentation: None,
10639                    label: CodeLabel::default(),
10640                    match_start: None,
10641                    snippet_deduplication_key: None,
10642                    insert_text_mode: None,
10643                    icon_path: None,
10644                    confirm: None,
10645                }]))),
10646                0,
10647                false,
10648                all_commit_ranges,
10649                cx,
10650            )
10651        });
10652
10653        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10654            transaction: apply_additional_edits
10655                .await?
10656                .as_ref()
10657                .map(language::proto::serialize_transaction),
10658        })
10659    }
10660
10661    pub fn last_formatting_failure(&self) -> Option<&str> {
10662        self.last_formatting_failure.as_deref()
10663    }
10664
10665    pub fn reset_last_formatting_failure(&mut self) {
10666        self.last_formatting_failure = None;
10667    }
10668
10669    pub fn environment_for_buffer(
10670        &self,
10671        buffer: &Entity<Buffer>,
10672        cx: &mut Context<Self>,
10673    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10674        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10675            environment.update(cx, |env, cx| {
10676                env.buffer_environment(buffer, &self.worktree_store, cx)
10677            })
10678        } else {
10679            Task::ready(None).shared()
10680        }
10681    }
10682
10683    pub fn format(
10684        &mut self,
10685        buffers: HashSet<Entity<Buffer>>,
10686        target: LspFormatTarget,
10687        push_to_history: bool,
10688        trigger: FormatTrigger,
10689        cx: &mut Context<Self>,
10690    ) -> Task<anyhow::Result<ProjectTransaction>> {
10691        let logger = zlog::scoped!("format");
10692        if self.as_local().is_some() {
10693            zlog::trace!(logger => "Formatting locally");
10694            let logger = zlog::scoped!(logger => "local");
10695            let buffers = buffers
10696                .into_iter()
10697                .map(|buffer_handle| {
10698                    let buffer = buffer_handle.read(cx);
10699                    let buffer_abs_path = File::from_dyn(buffer.file())
10700                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10701
10702                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10703                })
10704                .collect::<Vec<_>>();
10705
10706            cx.spawn(async move |lsp_store, cx| {
10707                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10708
10709                for (handle, abs_path, id) in buffers {
10710                    let env = lsp_store
10711                        .update(cx, |lsp_store, cx| {
10712                            lsp_store.environment_for_buffer(&handle, cx)
10713                        })?
10714                        .await;
10715
10716                    let ranges = match &target {
10717                        LspFormatTarget::Buffers => None,
10718                        LspFormatTarget::Ranges(ranges) => {
10719                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10720                        }
10721                    };
10722
10723                    formattable_buffers.push(FormattableBuffer {
10724                        handle,
10725                        abs_path,
10726                        env,
10727                        ranges,
10728                    });
10729                }
10730                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10731
10732                let format_timer = zlog::time!(logger => "Formatting buffers");
10733                let result = LocalLspStore::format_locally(
10734                    lsp_store.clone(),
10735                    formattable_buffers,
10736                    push_to_history,
10737                    trigger,
10738                    logger,
10739                    cx,
10740                )
10741                .await;
10742                format_timer.end();
10743
10744                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10745
10746                lsp_store.update(cx, |lsp_store, _| {
10747                    lsp_store.update_last_formatting_failure(&result);
10748                })?;
10749
10750                result
10751            })
10752        } else if let Some((client, project_id)) = self.upstream_client() {
10753            zlog::trace!(logger => "Formatting remotely");
10754            let logger = zlog::scoped!(logger => "remote");
10755
10756            let buffer_ranges = match &target {
10757                LspFormatTarget::Buffers => Vec::new(),
10758                LspFormatTarget::Ranges(ranges) => ranges
10759                    .iter()
10760                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10761                        buffer_id: buffer_id.to_proto(),
10762                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10763                    })
10764                    .collect(),
10765            };
10766
10767            let buffer_store = self.buffer_store();
10768            cx.spawn(async move |lsp_store, cx| {
10769                zlog::trace!(logger => "Sending remote format request");
10770                let request_timer = zlog::time!(logger => "remote format request");
10771                let result = client
10772                    .request(proto::FormatBuffers {
10773                        project_id,
10774                        trigger: trigger as i32,
10775                        buffer_ids: buffers
10776                            .iter()
10777                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10778                            .collect(),
10779                        buffer_ranges,
10780                    })
10781                    .await
10782                    .and_then(|result| result.transaction.context("missing transaction"));
10783                request_timer.end();
10784
10785                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10786
10787                lsp_store.update(cx, |lsp_store, _| {
10788                    lsp_store.update_last_formatting_failure(&result);
10789                })?;
10790
10791                let transaction_response = result?;
10792                let _timer = zlog::time!(logger => "deserializing project transaction");
10793                buffer_store
10794                    .update(cx, |buffer_store, cx| {
10795                        buffer_store.deserialize_project_transaction(
10796                            transaction_response,
10797                            push_to_history,
10798                            cx,
10799                        )
10800                    })
10801                    .await
10802            })
10803        } else {
10804            zlog::trace!(logger => "Not formatting");
10805            Task::ready(Ok(ProjectTransaction::default()))
10806        }
10807    }
10808
10809    async fn handle_format_buffers(
10810        this: Entity<Self>,
10811        envelope: TypedEnvelope<proto::FormatBuffers>,
10812        mut cx: AsyncApp,
10813    ) -> Result<proto::FormatBuffersResponse> {
10814        let sender_id = envelope.original_sender_id().unwrap_or_default();
10815        let format = this.update(&mut cx, |this, cx| {
10816            let mut buffers = HashSet::default();
10817            for buffer_id in &envelope.payload.buffer_ids {
10818                let buffer_id = BufferId::new(*buffer_id)?;
10819                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10820            }
10821
10822            let target = if envelope.payload.buffer_ranges.is_empty() {
10823                LspFormatTarget::Buffers
10824            } else {
10825                let mut ranges_map = BTreeMap::new();
10826                for buffer_range in &envelope.payload.buffer_ranges {
10827                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10828                    let ranges: Result<Vec<_>> = buffer_range
10829                        .ranges
10830                        .iter()
10831                        .map(|range| {
10832                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10833                        })
10834                        .collect();
10835                    ranges_map.insert(buffer_id, ranges?);
10836                }
10837                LspFormatTarget::Ranges(ranges_map)
10838            };
10839
10840            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10841            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10842        })?;
10843
10844        let project_transaction = format.await?;
10845        let project_transaction = this.update(&mut cx, |this, cx| {
10846            this.buffer_store.update(cx, |buffer_store, cx| {
10847                buffer_store.serialize_project_transaction_for_peer(
10848                    project_transaction,
10849                    sender_id,
10850                    cx,
10851                )
10852            })
10853        });
10854        Ok(proto::FormatBuffersResponse {
10855            transaction: Some(project_transaction),
10856        })
10857    }
10858
10859    async fn handle_apply_code_action_kind(
10860        this: Entity<Self>,
10861        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10862        mut cx: AsyncApp,
10863    ) -> Result<proto::ApplyCodeActionKindResponse> {
10864        let sender_id = envelope.original_sender_id().unwrap_or_default();
10865        let format = this.update(&mut cx, |this, cx| {
10866            let mut buffers = HashSet::default();
10867            for buffer_id in &envelope.payload.buffer_ids {
10868                let buffer_id = BufferId::new(*buffer_id)?;
10869                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10870            }
10871            let kind = match envelope.payload.kind.as_str() {
10872                "" => CodeActionKind::EMPTY,
10873                "quickfix" => CodeActionKind::QUICKFIX,
10874                "refactor" => CodeActionKind::REFACTOR,
10875                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10876                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10877                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10878                "source" => CodeActionKind::SOURCE,
10879                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10880                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10881                _ => anyhow::bail!(
10882                    "Invalid code action kind {}",
10883                    envelope.payload.kind.as_str()
10884                ),
10885            };
10886            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10887        })?;
10888
10889        let project_transaction = format.await?;
10890        let project_transaction = this.update(&mut cx, |this, cx| {
10891            this.buffer_store.update(cx, |buffer_store, cx| {
10892                buffer_store.serialize_project_transaction_for_peer(
10893                    project_transaction,
10894                    sender_id,
10895                    cx,
10896                )
10897            })
10898        });
10899        Ok(proto::ApplyCodeActionKindResponse {
10900            transaction: Some(project_transaction),
10901        })
10902    }
10903
10904    async fn shutdown_language_server(
10905        server_state: Option<LanguageServerState>,
10906        name: LanguageServerName,
10907        cx: &mut AsyncApp,
10908    ) {
10909        let server = match server_state {
10910            Some(LanguageServerState::Starting { startup, .. }) => {
10911                let mut timer = cx
10912                    .background_executor()
10913                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10914                    .fuse();
10915
10916                select! {
10917                    server = startup.fuse() => server,
10918                    () = timer => {
10919                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10920                        None
10921                    },
10922                }
10923            }
10924
10925            Some(LanguageServerState::Running { server, .. }) => Some(server),
10926
10927            None => None,
10928        };
10929
10930        let Some(server) = server else { return };
10931        if let Some(shutdown) = server.shutdown() {
10932            shutdown.await;
10933        }
10934    }
10935
10936    // Returns a list of all of the worktrees which no longer have a language server and the root path
10937    // for the stopped server
10938    fn stop_local_language_server(
10939        &mut self,
10940        server_id: LanguageServerId,
10941        cx: &mut Context<Self>,
10942    ) -> Task<()> {
10943        let local = match &mut self.mode {
10944            LspStoreMode::Local(local) => local,
10945            _ => {
10946                return Task::ready(());
10947            }
10948        };
10949
10950        // Remove this server ID from all entries in the given worktree.
10951        local
10952            .language_server_ids
10953            .retain(|_, state| state.id != server_id);
10954        self.buffer_store.update(cx, |buffer_store, cx| {
10955            for buffer in buffer_store.buffers() {
10956                buffer.update(cx, |buffer, cx| {
10957                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10958                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10959                });
10960            }
10961        });
10962
10963        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10964        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10965            summaries.retain(|path, summaries_by_server_id| {
10966                if summaries_by_server_id.remove(&server_id).is_some() {
10967                    if let Some((client, project_id)) = self.downstream_client.clone() {
10968                        client
10969                            .send(proto::UpdateDiagnosticSummary {
10970                                project_id,
10971                                worktree_id: worktree_id.to_proto(),
10972                                summary: Some(proto::DiagnosticSummary {
10973                                    path: path.as_ref().to_proto(),
10974                                    language_server_id: server_id.0 as u64,
10975                                    error_count: 0,
10976                                    warning_count: 0,
10977                                }),
10978                                more_summaries: Vec::new(),
10979                            })
10980                            .log_err();
10981                    }
10982                    cleared_paths.push(ProjectPath {
10983                        worktree_id: *worktree_id,
10984                        path: path.clone(),
10985                    });
10986                    !summaries_by_server_id.is_empty()
10987                } else {
10988                    true
10989                }
10990            });
10991        }
10992        if !cleared_paths.is_empty() {
10993            cx.emit(LspStoreEvent::DiagnosticsUpdated {
10994                server_id,
10995                paths: cleared_paths,
10996            });
10997        }
10998
10999        let local = self.as_local_mut().unwrap();
11000        for diagnostics in local.diagnostics.values_mut() {
11001            diagnostics.retain(|_, diagnostics_by_server_id| {
11002                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11003                    diagnostics_by_server_id.remove(ix);
11004                    !diagnostics_by_server_id.is_empty()
11005                } else {
11006                    true
11007                }
11008            });
11009        }
11010        local.language_server_watched_paths.remove(&server_id);
11011
11012        let server_state = local.language_servers.remove(&server_id);
11013        self.cleanup_lsp_data(server_id);
11014        let name = self
11015            .language_server_statuses
11016            .remove(&server_id)
11017            .map(|status| status.name)
11018            .or_else(|| {
11019                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11020                    Some(adapter.name())
11021                } else {
11022                    None
11023                }
11024            });
11025
11026        if let Some(name) = name {
11027            log::info!("stopping language server {name}");
11028            self.languages
11029                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11030            cx.notify();
11031
11032            return cx.spawn(async move |lsp_store, cx| {
11033                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11034                lsp_store
11035                    .update(cx, |lsp_store, cx| {
11036                        lsp_store
11037                            .languages
11038                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11039                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11040                        cx.notify();
11041                    })
11042                    .ok();
11043            });
11044        }
11045
11046        if server_state.is_some() {
11047            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11048        }
11049        Task::ready(())
11050    }
11051
11052    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11053        self.shutdown_all_language_servers(cx).detach();
11054    }
11055
11056    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11057        if let Some((client, project_id)) = self.upstream_client() {
11058            let request = client.request(proto::StopLanguageServers {
11059                project_id,
11060                buffer_ids: Vec::new(),
11061                also_servers: Vec::new(),
11062                all: true,
11063            });
11064            cx.background_spawn(async move {
11065                request.await.ok();
11066            })
11067        } else {
11068            let Some(local) = self.as_local_mut() else {
11069                return Task::ready(());
11070            };
11071            let language_servers_to_stop = local
11072                .language_server_ids
11073                .values()
11074                .map(|state| state.id)
11075                .collect();
11076            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11077            let tasks = language_servers_to_stop
11078                .into_iter()
11079                .map(|server| self.stop_local_language_server(server, cx))
11080                .collect::<Vec<_>>();
11081            cx.background_spawn(async move {
11082                futures::future::join_all(tasks).await;
11083            })
11084        }
11085    }
11086
11087    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11088        let buffers = self.buffer_store.read(cx).buffers().collect();
11089        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11090    }
11091
11092    pub fn restart_language_servers_for_buffers(
11093        &mut self,
11094        buffers: Vec<Entity<Buffer>>,
11095        only_restart_servers: HashSet<LanguageServerSelector>,
11096        cx: &mut Context<Self>,
11097    ) {
11098        if let Some((client, project_id)) = self.upstream_client() {
11099            let request = client.request(proto::RestartLanguageServers {
11100                project_id,
11101                buffer_ids: buffers
11102                    .into_iter()
11103                    .map(|b| b.read(cx).remote_id().to_proto())
11104                    .collect(),
11105                only_servers: only_restart_servers
11106                    .into_iter()
11107                    .map(|selector| {
11108                        let selector = match selector {
11109                            LanguageServerSelector::Id(language_server_id) => {
11110                                proto::language_server_selector::Selector::ServerId(
11111                                    language_server_id.to_proto(),
11112                                )
11113                            }
11114                            LanguageServerSelector::Name(language_server_name) => {
11115                                proto::language_server_selector::Selector::Name(
11116                                    language_server_name.to_string(),
11117                                )
11118                            }
11119                        };
11120                        proto::LanguageServerSelector {
11121                            selector: Some(selector),
11122                        }
11123                    })
11124                    .collect(),
11125                all: false,
11126            });
11127            cx.background_spawn(request).detach_and_log_err(cx);
11128        } else {
11129            let stop_task = if only_restart_servers.is_empty() {
11130                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11131            } else {
11132                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11133            };
11134            cx.spawn(async move |lsp_store, cx| {
11135                stop_task.await;
11136                lsp_store.update(cx, |lsp_store, cx| {
11137                    for buffer in buffers {
11138                        lsp_store.register_buffer_with_language_servers(
11139                            &buffer,
11140                            only_restart_servers.clone(),
11141                            true,
11142                            cx,
11143                        );
11144                    }
11145                })
11146            })
11147            .detach();
11148        }
11149    }
11150
11151    pub fn stop_language_servers_for_buffers(
11152        &mut self,
11153        buffers: Vec<Entity<Buffer>>,
11154        also_stop_servers: HashSet<LanguageServerSelector>,
11155        cx: &mut Context<Self>,
11156    ) -> Task<Result<()>> {
11157        if let Some((client, project_id)) = self.upstream_client() {
11158            let request = client.request(proto::StopLanguageServers {
11159                project_id,
11160                buffer_ids: buffers
11161                    .into_iter()
11162                    .map(|b| b.read(cx).remote_id().to_proto())
11163                    .collect(),
11164                also_servers: also_stop_servers
11165                    .into_iter()
11166                    .map(|selector| {
11167                        let selector = match selector {
11168                            LanguageServerSelector::Id(language_server_id) => {
11169                                proto::language_server_selector::Selector::ServerId(
11170                                    language_server_id.to_proto(),
11171                                )
11172                            }
11173                            LanguageServerSelector::Name(language_server_name) => {
11174                                proto::language_server_selector::Selector::Name(
11175                                    language_server_name.to_string(),
11176                                )
11177                            }
11178                        };
11179                        proto::LanguageServerSelector {
11180                            selector: Some(selector),
11181                        }
11182                    })
11183                    .collect(),
11184                all: false,
11185            });
11186            cx.background_spawn(async move {
11187                let _ = request.await?;
11188                Ok(())
11189            })
11190        } else {
11191            let task =
11192                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11193            cx.background_spawn(async move {
11194                task.await;
11195                Ok(())
11196            })
11197        }
11198    }
11199
11200    fn stop_local_language_servers_for_buffers(
11201        &mut self,
11202        buffers: &[Entity<Buffer>],
11203        also_stop_servers: HashSet<LanguageServerSelector>,
11204        cx: &mut Context<Self>,
11205    ) -> Task<()> {
11206        let Some(local) = self.as_local_mut() else {
11207            return Task::ready(());
11208        };
11209        let mut language_server_names_to_stop = BTreeSet::default();
11210        let mut language_servers_to_stop = also_stop_servers
11211            .into_iter()
11212            .flat_map(|selector| match selector {
11213                LanguageServerSelector::Id(id) => Some(id),
11214                LanguageServerSelector::Name(name) => {
11215                    language_server_names_to_stop.insert(name);
11216                    None
11217                }
11218            })
11219            .collect::<BTreeSet<_>>();
11220
11221        let mut covered_worktrees = HashSet::default();
11222        for buffer in buffers {
11223            buffer.update(cx, |buffer, cx| {
11224                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11225                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11226                    && covered_worktrees.insert(worktree_id)
11227                {
11228                    language_server_names_to_stop.retain(|name| {
11229                        let old_ids_count = language_servers_to_stop.len();
11230                        let all_language_servers_with_this_name = local
11231                            .language_server_ids
11232                            .iter()
11233                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11234                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11235                        old_ids_count == language_servers_to_stop.len()
11236                    });
11237                }
11238            });
11239        }
11240        for name in language_server_names_to_stop {
11241            language_servers_to_stop.extend(
11242                local
11243                    .language_server_ids
11244                    .iter()
11245                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11246            );
11247        }
11248
11249        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11250        let tasks = language_servers_to_stop
11251            .into_iter()
11252            .map(|server| self.stop_local_language_server(server, cx))
11253            .collect::<Vec<_>>();
11254
11255        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11256    }
11257
11258    #[cfg(any(test, feature = "test-support"))]
11259    pub fn update_diagnostics(
11260        &mut self,
11261        server_id: LanguageServerId,
11262        diagnostics: lsp::PublishDiagnosticsParams,
11263        result_id: Option<SharedString>,
11264        source_kind: DiagnosticSourceKind,
11265        disk_based_sources: &[String],
11266        cx: &mut Context<Self>,
11267    ) -> Result<()> {
11268        self.merge_lsp_diagnostics(
11269            source_kind,
11270            vec![DocumentDiagnosticsUpdate {
11271                diagnostics,
11272                result_id,
11273                server_id,
11274                disk_based_sources: Cow::Borrowed(disk_based_sources),
11275                registration_id: None,
11276            }],
11277            |_, _, _| false,
11278            cx,
11279        )
11280    }
11281
11282    pub fn merge_lsp_diagnostics(
11283        &mut self,
11284        source_kind: DiagnosticSourceKind,
11285        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11286        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11287        cx: &mut Context<Self>,
11288    ) -> Result<()> {
11289        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11290        let updates = lsp_diagnostics
11291            .into_iter()
11292            .filter_map(|update| {
11293                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11294                Some(DocumentDiagnosticsUpdate {
11295                    diagnostics: self.lsp_to_document_diagnostics(
11296                        abs_path,
11297                        source_kind,
11298                        update.server_id,
11299                        update.diagnostics,
11300                        &update.disk_based_sources,
11301                        update.registration_id.clone(),
11302                    ),
11303                    result_id: update.result_id,
11304                    server_id: update.server_id,
11305                    disk_based_sources: update.disk_based_sources,
11306                    registration_id: update.registration_id,
11307                })
11308            })
11309            .collect();
11310        self.merge_diagnostic_entries(updates, merge, cx)?;
11311        Ok(())
11312    }
11313
11314    fn lsp_to_document_diagnostics(
11315        &mut self,
11316        document_abs_path: PathBuf,
11317        source_kind: DiagnosticSourceKind,
11318        server_id: LanguageServerId,
11319        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11320        disk_based_sources: &[String],
11321        registration_id: Option<SharedString>,
11322    ) -> DocumentDiagnostics {
11323        let mut diagnostics = Vec::default();
11324        let mut primary_diagnostic_group_ids = HashMap::default();
11325        let mut sources_by_group_id = HashMap::default();
11326        let mut supporting_diagnostics = HashMap::default();
11327
11328        let adapter = self.language_server_adapter_for_id(server_id);
11329
11330        // Ensure that primary diagnostics are always the most severe
11331        lsp_diagnostics
11332            .diagnostics
11333            .sort_by_key(|item| item.severity);
11334
11335        for diagnostic in &lsp_diagnostics.diagnostics {
11336            let source = diagnostic.source.as_ref();
11337            let range = range_from_lsp(diagnostic.range);
11338            let is_supporting = diagnostic
11339                .related_information
11340                .as_ref()
11341                .is_some_and(|infos| {
11342                    infos.iter().any(|info| {
11343                        primary_diagnostic_group_ids.contains_key(&(
11344                            source,
11345                            diagnostic.code.clone(),
11346                            range_from_lsp(info.location.range),
11347                        ))
11348                    })
11349                });
11350
11351            let is_unnecessary = diagnostic
11352                .tags
11353                .as_ref()
11354                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11355
11356            let underline = self
11357                .language_server_adapter_for_id(server_id)
11358                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11359
11360            if is_supporting {
11361                supporting_diagnostics.insert(
11362                    (source, diagnostic.code.clone(), range),
11363                    (diagnostic.severity, is_unnecessary),
11364                );
11365            } else {
11366                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11367                let is_disk_based =
11368                    source.is_some_and(|source| disk_based_sources.contains(source));
11369
11370                sources_by_group_id.insert(group_id, source);
11371                primary_diagnostic_group_ids
11372                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11373
11374                diagnostics.push(DiagnosticEntry {
11375                    range,
11376                    diagnostic: Diagnostic {
11377                        source: diagnostic.source.clone(),
11378                        source_kind,
11379                        code: diagnostic.code.clone(),
11380                        code_description: diagnostic
11381                            .code_description
11382                            .as_ref()
11383                            .and_then(|d| d.href.clone()),
11384                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11385                        markdown: adapter.as_ref().and_then(|adapter| {
11386                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11387                        }),
11388                        message: diagnostic.message.trim().to_string(),
11389                        group_id,
11390                        is_primary: true,
11391                        is_disk_based,
11392                        is_unnecessary,
11393                        underline,
11394                        data: diagnostic.data.clone(),
11395                        registration_id: registration_id.clone(),
11396                    },
11397                });
11398                if let Some(infos) = &diagnostic.related_information {
11399                    for info in infos {
11400                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11401                            let range = range_from_lsp(info.location.range);
11402                            diagnostics.push(DiagnosticEntry {
11403                                range,
11404                                diagnostic: Diagnostic {
11405                                    source: diagnostic.source.clone(),
11406                                    source_kind,
11407                                    code: diagnostic.code.clone(),
11408                                    code_description: diagnostic
11409                                        .code_description
11410                                        .as_ref()
11411                                        .and_then(|d| d.href.clone()),
11412                                    severity: DiagnosticSeverity::INFORMATION,
11413                                    markdown: adapter.as_ref().and_then(|adapter| {
11414                                        adapter.diagnostic_message_to_markdown(&info.message)
11415                                    }),
11416                                    message: info.message.trim().to_string(),
11417                                    group_id,
11418                                    is_primary: false,
11419                                    is_disk_based,
11420                                    is_unnecessary: false,
11421                                    underline,
11422                                    data: diagnostic.data.clone(),
11423                                    registration_id: registration_id.clone(),
11424                                },
11425                            });
11426                        }
11427                    }
11428                }
11429            }
11430        }
11431
11432        for entry in &mut diagnostics {
11433            let diagnostic = &mut entry.diagnostic;
11434            if !diagnostic.is_primary {
11435                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11436                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11437                    source,
11438                    diagnostic.code.clone(),
11439                    entry.range.clone(),
11440                )) {
11441                    if let Some(severity) = severity {
11442                        diagnostic.severity = severity;
11443                    }
11444                    diagnostic.is_unnecessary = is_unnecessary;
11445                }
11446            }
11447        }
11448
11449        DocumentDiagnostics {
11450            diagnostics,
11451            document_abs_path,
11452            version: lsp_diagnostics.version,
11453        }
11454    }
11455
11456    fn insert_newly_running_language_server(
11457        &mut self,
11458        adapter: Arc<CachedLspAdapter>,
11459        language_server: Arc<LanguageServer>,
11460        server_id: LanguageServerId,
11461        key: LanguageServerSeed,
11462        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11463        cx: &mut Context<Self>,
11464    ) {
11465        let Some(local) = self.as_local_mut() else {
11466            return;
11467        };
11468        // If the language server for this key doesn't match the server id, don't store the
11469        // server. Which will cause it to be dropped, killing the process
11470        if local
11471            .language_server_ids
11472            .get(&key)
11473            .map(|state| state.id != server_id)
11474            .unwrap_or(false)
11475        {
11476            return;
11477        }
11478
11479        // Update language_servers collection with Running variant of LanguageServerState
11480        // indicating that the server is up and running and ready
11481        let workspace_folders = workspace_folders.lock().clone();
11482        language_server.set_workspace_folders(workspace_folders);
11483
11484        let workspace_diagnostics_refresh_tasks = language_server
11485            .capabilities()
11486            .diagnostic_provider
11487            .and_then(|provider| {
11488                local
11489                    .language_server_dynamic_registrations
11490                    .entry(server_id)
11491                    .or_default()
11492                    .diagnostics
11493                    .entry(None)
11494                    .or_insert(provider.clone());
11495                let workspace_refresher =
11496                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11497
11498                Some((None, workspace_refresher))
11499            })
11500            .into_iter()
11501            .collect();
11502        local.language_servers.insert(
11503            server_id,
11504            LanguageServerState::Running {
11505                workspace_diagnostics_refresh_tasks,
11506                adapter: adapter.clone(),
11507                server: language_server.clone(),
11508                simulate_disk_based_diagnostics_completion: None,
11509            },
11510        );
11511        local
11512            .languages
11513            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11514        if let Some(file_ops_caps) = language_server
11515            .capabilities()
11516            .workspace
11517            .as_ref()
11518            .and_then(|ws| ws.file_operations.as_ref())
11519        {
11520            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11521            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11522            if did_rename_caps.or(will_rename_caps).is_some() {
11523                let watcher = RenamePathsWatchedForServer::default()
11524                    .with_did_rename_patterns(did_rename_caps)
11525                    .with_will_rename_patterns(will_rename_caps);
11526                local
11527                    .language_server_paths_watched_for_rename
11528                    .insert(server_id, watcher);
11529            }
11530        }
11531
11532        self.language_server_statuses.insert(
11533            server_id,
11534            LanguageServerStatus {
11535                name: language_server.name(),
11536                server_version: language_server.version(),
11537                server_readable_version: language_server.readable_version(),
11538                pending_work: Default::default(),
11539                has_pending_diagnostic_updates: false,
11540                progress_tokens: Default::default(),
11541                worktree: Some(key.worktree_id),
11542                binary: Some(language_server.binary().clone()),
11543                configuration: Some(language_server.configuration().clone()),
11544                workspace_folders: language_server.workspace_folders(),
11545                process_id: language_server.process_id(),
11546            },
11547        );
11548
11549        cx.emit(LspStoreEvent::LanguageServerAdded(
11550            server_id,
11551            language_server.name(),
11552            Some(key.worktree_id),
11553        ));
11554
11555        let server_capabilities = language_server.capabilities();
11556        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11557            downstream_client
11558                .send(proto::StartLanguageServer {
11559                    project_id: *project_id,
11560                    server: Some(proto::LanguageServer {
11561                        id: server_id.to_proto(),
11562                        name: language_server.name().to_string(),
11563                        worktree_id: Some(key.worktree_id.to_proto()),
11564                    }),
11565                    capabilities: serde_json::to_string(&server_capabilities)
11566                        .expect("serializing server LSP capabilities"),
11567                })
11568                .log_err();
11569        }
11570        self.lsp_server_capabilities
11571            .insert(server_id, server_capabilities);
11572
11573        // Tell the language server about every open buffer in the worktree that matches the language.
11574        // Also check for buffers in worktrees that reused this server
11575        let mut worktrees_using_server = vec![key.worktree_id];
11576        if let Some(local) = self.as_local() {
11577            // Find all worktrees that have this server in their language server tree
11578            for (worktree_id, servers) in &local.lsp_tree.instances {
11579                if *worktree_id != key.worktree_id {
11580                    for server_map in servers.roots.values() {
11581                        if server_map
11582                            .values()
11583                            .any(|(node, _)| node.id() == Some(server_id))
11584                        {
11585                            worktrees_using_server.push(*worktree_id);
11586                        }
11587                    }
11588                }
11589            }
11590        }
11591
11592        let mut buffer_paths_registered = Vec::new();
11593        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11594            let mut lsp_adapters = HashMap::default();
11595            for buffer_handle in buffer_store.buffers() {
11596                let buffer = buffer_handle.read(cx);
11597                let file = match File::from_dyn(buffer.file()) {
11598                    Some(file) => file,
11599                    None => continue,
11600                };
11601                let language = match buffer.language() {
11602                    Some(language) => language,
11603                    None => continue,
11604                };
11605
11606                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11607                    || !lsp_adapters
11608                        .entry(language.name())
11609                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11610                        .iter()
11611                        .any(|a| a.name == key.name)
11612                {
11613                    continue;
11614                }
11615                // didOpen
11616                let file = match file.as_local() {
11617                    Some(file) => file,
11618                    None => continue,
11619                };
11620
11621                let local = self.as_local_mut().unwrap();
11622
11623                let buffer_id = buffer.remote_id();
11624                if local.registered_buffers.contains_key(&buffer_id) {
11625                    let abs_path = file.abs_path(cx);
11626                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11627                        Ok(uri) => uri,
11628                        Err(()) => {
11629                            log::error!("failed to convert path to URI: {:?}", abs_path);
11630                            continue;
11631                        }
11632                    };
11633
11634                    let versions = local
11635                        .buffer_snapshots
11636                        .entry(buffer_id)
11637                        .or_default()
11638                        .entry(server_id)
11639                        .and_modify(|_| {
11640                            assert!(
11641                            false,
11642                            "There should not be an existing snapshot for a newly inserted buffer"
11643                        )
11644                        })
11645                        .or_insert_with(|| {
11646                            vec![LspBufferSnapshot {
11647                                version: 0,
11648                                snapshot: buffer.text_snapshot(),
11649                            }]
11650                        });
11651
11652                    let snapshot = versions.last().unwrap();
11653                    let version = snapshot.version;
11654                    let initial_snapshot = &snapshot.snapshot;
11655                    language_server.register_buffer(
11656                        uri,
11657                        adapter.language_id(&language.name()),
11658                        version,
11659                        initial_snapshot.text(),
11660                    );
11661                    buffer_paths_registered.push((buffer_id, abs_path));
11662                    local
11663                        .buffers_opened_in_servers
11664                        .entry(buffer_id)
11665                        .or_default()
11666                        .insert(server_id);
11667                }
11668                buffer_handle.update(cx, |buffer, cx| {
11669                    buffer.set_completion_triggers(
11670                        server_id,
11671                        language_server
11672                            .capabilities()
11673                            .completion_provider
11674                            .as_ref()
11675                            .and_then(|provider| {
11676                                provider
11677                                    .trigger_characters
11678                                    .as_ref()
11679                                    .map(|characters| characters.iter().cloned().collect())
11680                            })
11681                            .unwrap_or_default(),
11682                        cx,
11683                    )
11684                });
11685            }
11686        });
11687
11688        for (buffer_id, abs_path) in buffer_paths_registered {
11689            cx.emit(LspStoreEvent::LanguageServerUpdate {
11690                language_server_id: server_id,
11691                name: Some(adapter.name()),
11692                message: proto::update_language_server::Variant::RegisteredForBuffer(
11693                    proto::RegisteredForBuffer {
11694                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11695                        buffer_id: buffer_id.to_proto(),
11696                    },
11697                ),
11698            });
11699        }
11700
11701        cx.notify();
11702    }
11703
11704    pub fn language_servers_running_disk_based_diagnostics(
11705        &self,
11706    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11707        self.language_server_statuses
11708            .iter()
11709            .filter_map(|(id, status)| {
11710                if status.has_pending_diagnostic_updates {
11711                    Some(*id)
11712                } else {
11713                    None
11714                }
11715            })
11716    }
11717
11718    pub(crate) fn cancel_language_server_work_for_buffers(
11719        &mut self,
11720        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11721        cx: &mut Context<Self>,
11722    ) {
11723        if let Some((client, project_id)) = self.upstream_client() {
11724            let request = client.request(proto::CancelLanguageServerWork {
11725                project_id,
11726                work: Some(proto::cancel_language_server_work::Work::Buffers(
11727                    proto::cancel_language_server_work::Buffers {
11728                        buffer_ids: buffers
11729                            .into_iter()
11730                            .map(|b| b.read(cx).remote_id().to_proto())
11731                            .collect(),
11732                    },
11733                )),
11734            });
11735            cx.background_spawn(request).detach_and_log_err(cx);
11736        } else if let Some(local) = self.as_local() {
11737            let servers = buffers
11738                .into_iter()
11739                .flat_map(|buffer| {
11740                    buffer.update(cx, |buffer, cx| {
11741                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11742                    })
11743                })
11744                .collect::<HashSet<_>>();
11745            for server_id in servers {
11746                self.cancel_language_server_work(server_id, None, cx);
11747            }
11748        }
11749    }
11750
11751    pub(crate) fn cancel_language_server_work(
11752        &mut self,
11753        server_id: LanguageServerId,
11754        token_to_cancel: Option<ProgressToken>,
11755        cx: &mut Context<Self>,
11756    ) {
11757        if let Some(local) = self.as_local() {
11758            let status = self.language_server_statuses.get(&server_id);
11759            let server = local.language_servers.get(&server_id);
11760            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11761            {
11762                for (token, progress) in &status.pending_work {
11763                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11764                        && token != token_to_cancel
11765                    {
11766                        continue;
11767                    }
11768                    if progress.is_cancellable {
11769                        server
11770                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11771                                WorkDoneProgressCancelParams {
11772                                    token: token.to_lsp(),
11773                                },
11774                            )
11775                            .ok();
11776                    }
11777                }
11778            }
11779        } else if let Some((client, project_id)) = self.upstream_client() {
11780            let request = client.request(proto::CancelLanguageServerWork {
11781                project_id,
11782                work: Some(
11783                    proto::cancel_language_server_work::Work::LanguageServerWork(
11784                        proto::cancel_language_server_work::LanguageServerWork {
11785                            language_server_id: server_id.to_proto(),
11786                            token: token_to_cancel.map(|token| token.to_proto()),
11787                        },
11788                    ),
11789                ),
11790            });
11791            cx.background_spawn(request).detach_and_log_err(cx);
11792        }
11793    }
11794
11795    fn register_supplementary_language_server(
11796        &mut self,
11797        id: LanguageServerId,
11798        name: LanguageServerName,
11799        server: Arc<LanguageServer>,
11800        cx: &mut Context<Self>,
11801    ) {
11802        if let Some(local) = self.as_local_mut() {
11803            local
11804                .supplementary_language_servers
11805                .insert(id, (name.clone(), server));
11806            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11807        }
11808    }
11809
11810    fn unregister_supplementary_language_server(
11811        &mut self,
11812        id: LanguageServerId,
11813        cx: &mut Context<Self>,
11814    ) {
11815        if let Some(local) = self.as_local_mut() {
11816            local.supplementary_language_servers.remove(&id);
11817            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11818        }
11819    }
11820
11821    pub(crate) fn supplementary_language_servers(
11822        &self,
11823    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11824        self.as_local().into_iter().flat_map(|local| {
11825            local
11826                .supplementary_language_servers
11827                .iter()
11828                .map(|(id, (name, _))| (*id, name.clone()))
11829        })
11830    }
11831
11832    pub fn language_server_adapter_for_id(
11833        &self,
11834        id: LanguageServerId,
11835    ) -> Option<Arc<CachedLspAdapter>> {
11836        self.as_local()
11837            .and_then(|local| local.language_servers.get(&id))
11838            .and_then(|language_server_state| match language_server_state {
11839                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11840                _ => None,
11841            })
11842    }
11843
11844    pub(super) fn update_local_worktree_language_servers(
11845        &mut self,
11846        worktree_handle: &Entity<Worktree>,
11847        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11848        cx: &mut Context<Self>,
11849    ) {
11850        if changes.is_empty() {
11851            return;
11852        }
11853
11854        let Some(local) = self.as_local() else { return };
11855
11856        local.prettier_store.update(cx, |prettier_store, cx| {
11857            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11858        });
11859
11860        let worktree_id = worktree_handle.read(cx).id();
11861        let mut language_server_ids = local
11862            .language_server_ids
11863            .iter()
11864            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11865            .collect::<Vec<_>>();
11866        language_server_ids.sort();
11867        language_server_ids.dedup();
11868
11869        // let abs_path = worktree_handle.read(cx).abs_path();
11870        for server_id in &language_server_ids {
11871            if let Some(LanguageServerState::Running { server, .. }) =
11872                local.language_servers.get(server_id)
11873                && let Some(watched_paths) = local
11874                    .language_server_watched_paths
11875                    .get(server_id)
11876                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11877            {
11878                let params = lsp::DidChangeWatchedFilesParams {
11879                    changes: changes
11880                        .iter()
11881                        .filter_map(|(path, _, change)| {
11882                            if !watched_paths.is_match(path.as_std_path()) {
11883                                return None;
11884                            }
11885                            let typ = match change {
11886                                PathChange::Loaded => return None,
11887                                PathChange::Added => lsp::FileChangeType::CREATED,
11888                                PathChange::Removed => lsp::FileChangeType::DELETED,
11889                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11890                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11891                            };
11892                            let uri = lsp::Uri::from_file_path(
11893                                worktree_handle.read(cx).absolutize(&path),
11894                            )
11895                            .ok()?;
11896                            Some(lsp::FileEvent { uri, typ })
11897                        })
11898                        .collect(),
11899                };
11900                if !params.changes.is_empty() {
11901                    server
11902                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11903                        .ok();
11904                }
11905            }
11906        }
11907        for (path, _, _) in changes {
11908            if let Some(file_name) = path.file_name()
11909                && local.watched_manifest_filenames.contains(file_name)
11910            {
11911                self.request_workspace_config_refresh();
11912                break;
11913            }
11914        }
11915    }
11916
11917    pub fn wait_for_remote_buffer(
11918        &mut self,
11919        id: BufferId,
11920        cx: &mut Context<Self>,
11921    ) -> Task<Result<Entity<Buffer>>> {
11922        self.buffer_store.update(cx, |buffer_store, cx| {
11923            buffer_store.wait_for_remote_buffer(id, cx)
11924        })
11925    }
11926
11927    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11928        let mut result = proto::Symbol {
11929            language_server_name: symbol.language_server_name.0.to_string(),
11930            source_worktree_id: symbol.source_worktree_id.to_proto(),
11931            language_server_id: symbol.source_language_server_id.to_proto(),
11932            name: symbol.name.clone(),
11933            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11934            start: Some(proto::PointUtf16 {
11935                row: symbol.range.start.0.row,
11936                column: symbol.range.start.0.column,
11937            }),
11938            end: Some(proto::PointUtf16 {
11939                row: symbol.range.end.0.row,
11940                column: symbol.range.end.0.column,
11941            }),
11942            worktree_id: Default::default(),
11943            path: Default::default(),
11944            signature: Default::default(),
11945            container_name: symbol.container_name.clone(),
11946        };
11947        match &symbol.path {
11948            SymbolLocation::InProject(path) => {
11949                result.worktree_id = path.worktree_id.to_proto();
11950                result.path = path.path.to_proto();
11951            }
11952            SymbolLocation::OutsideProject {
11953                abs_path,
11954                signature,
11955            } => {
11956                result.path = abs_path.to_string_lossy().into_owned();
11957                result.signature = signature.to_vec();
11958            }
11959        }
11960        result
11961    }
11962
11963    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11964        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11965        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11966        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11967
11968        let path = if serialized_symbol.signature.is_empty() {
11969            SymbolLocation::InProject(ProjectPath {
11970                worktree_id,
11971                path: RelPath::from_proto(&serialized_symbol.path)
11972                    .context("invalid symbol path")?,
11973            })
11974        } else {
11975            SymbolLocation::OutsideProject {
11976                abs_path: Path::new(&serialized_symbol.path).into(),
11977                signature: serialized_symbol
11978                    .signature
11979                    .try_into()
11980                    .map_err(|_| anyhow!("invalid signature"))?,
11981            }
11982        };
11983
11984        let start = serialized_symbol.start.context("invalid start")?;
11985        let end = serialized_symbol.end.context("invalid end")?;
11986        Ok(CoreSymbol {
11987            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11988            source_worktree_id,
11989            source_language_server_id: LanguageServerId::from_proto(
11990                serialized_symbol.language_server_id,
11991            ),
11992            path,
11993            name: serialized_symbol.name,
11994            range: Unclipped(PointUtf16::new(start.row, start.column))
11995                ..Unclipped(PointUtf16::new(end.row, end.column)),
11996            kind,
11997            container_name: serialized_symbol.container_name,
11998        })
11999    }
12000
12001    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12002        let mut serialized_completion = proto::Completion {
12003            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12004            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12005            new_text: completion.new_text.clone(),
12006            ..proto::Completion::default()
12007        };
12008        match &completion.source {
12009            CompletionSource::Lsp {
12010                insert_range,
12011                server_id,
12012                lsp_completion,
12013                lsp_defaults,
12014                resolved,
12015            } => {
12016                let (old_insert_start, old_insert_end) = insert_range
12017                    .as_ref()
12018                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12019                    .unzip();
12020
12021                serialized_completion.old_insert_start = old_insert_start;
12022                serialized_completion.old_insert_end = old_insert_end;
12023                serialized_completion.source = proto::completion::Source::Lsp as i32;
12024                serialized_completion.server_id = server_id.0 as u64;
12025                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12026                serialized_completion.lsp_defaults = lsp_defaults
12027                    .as_deref()
12028                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12029                serialized_completion.resolved = *resolved;
12030            }
12031            CompletionSource::BufferWord {
12032                word_range,
12033                resolved,
12034            } => {
12035                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12036                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12037                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12038                serialized_completion.resolved = *resolved;
12039            }
12040            CompletionSource::Custom => {
12041                serialized_completion.source = proto::completion::Source::Custom as i32;
12042                serialized_completion.resolved = true;
12043            }
12044            CompletionSource::Dap { sort_text } => {
12045                serialized_completion.source = proto::completion::Source::Dap as i32;
12046                serialized_completion.sort_text = Some(sort_text.clone());
12047            }
12048        }
12049
12050        serialized_completion
12051    }
12052
12053    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12054        let old_replace_start = completion
12055            .old_replace_start
12056            .and_then(deserialize_anchor)
12057            .context("invalid old start")?;
12058        let old_replace_end = completion
12059            .old_replace_end
12060            .and_then(deserialize_anchor)
12061            .context("invalid old end")?;
12062        let insert_range = {
12063            match completion.old_insert_start.zip(completion.old_insert_end) {
12064                Some((start, end)) => {
12065                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12066                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12067                    Some(start..end)
12068                }
12069                None => None,
12070            }
12071        };
12072        Ok(CoreCompletion {
12073            replace_range: old_replace_start..old_replace_end,
12074            new_text: completion.new_text,
12075            source: match proto::completion::Source::from_i32(completion.source) {
12076                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12077                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12078                    insert_range,
12079                    server_id: LanguageServerId::from_proto(completion.server_id),
12080                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12081                    lsp_defaults: completion
12082                        .lsp_defaults
12083                        .as_deref()
12084                        .map(serde_json::from_slice)
12085                        .transpose()?,
12086                    resolved: completion.resolved,
12087                },
12088                Some(proto::completion::Source::BufferWord) => {
12089                    let word_range = completion
12090                        .buffer_word_start
12091                        .and_then(deserialize_anchor)
12092                        .context("invalid buffer word start")?
12093                        ..completion
12094                            .buffer_word_end
12095                            .and_then(deserialize_anchor)
12096                            .context("invalid buffer word end")?;
12097                    CompletionSource::BufferWord {
12098                        word_range,
12099                        resolved: completion.resolved,
12100                    }
12101                }
12102                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12103                    sort_text: completion
12104                        .sort_text
12105                        .context("expected sort text to exist")?,
12106                },
12107                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12108            },
12109        })
12110    }
12111
12112    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12113        let (kind, lsp_action) = match &action.lsp_action {
12114            LspAction::Action(code_action) => (
12115                proto::code_action::Kind::Action as i32,
12116                serde_json::to_vec(code_action).unwrap(),
12117            ),
12118            LspAction::Command(command) => (
12119                proto::code_action::Kind::Command as i32,
12120                serde_json::to_vec(command).unwrap(),
12121            ),
12122            LspAction::CodeLens(code_lens) => (
12123                proto::code_action::Kind::CodeLens as i32,
12124                serde_json::to_vec(code_lens).unwrap(),
12125            ),
12126        };
12127
12128        proto::CodeAction {
12129            server_id: action.server_id.0 as u64,
12130            start: Some(serialize_anchor(&action.range.start)),
12131            end: Some(serialize_anchor(&action.range.end)),
12132            lsp_action,
12133            kind,
12134            resolved: action.resolved,
12135        }
12136    }
12137
12138    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12139        let start = action
12140            .start
12141            .and_then(deserialize_anchor)
12142            .context("invalid start")?;
12143        let end = action
12144            .end
12145            .and_then(deserialize_anchor)
12146            .context("invalid end")?;
12147        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12148            Some(proto::code_action::Kind::Action) => {
12149                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12150            }
12151            Some(proto::code_action::Kind::Command) => {
12152                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12153            }
12154            Some(proto::code_action::Kind::CodeLens) => {
12155                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12156            }
12157            None => anyhow::bail!("Unknown action kind {}", action.kind),
12158        };
12159        Ok(CodeAction {
12160            server_id: LanguageServerId(action.server_id as usize),
12161            range: start..end,
12162            resolved: action.resolved,
12163            lsp_action,
12164        })
12165    }
12166
12167    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12168        match &formatting_result {
12169            Ok(_) => self.last_formatting_failure = None,
12170            Err(error) => {
12171                let error_string = format!("{error:#}");
12172                log::error!("Formatting failed: {error_string}");
12173                self.last_formatting_failure
12174                    .replace(error_string.lines().join(" "));
12175            }
12176        }
12177    }
12178
12179    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12180        self.lsp_server_capabilities.remove(&for_server);
12181        self.semantic_token_config.remove_server_data(for_server);
12182        for lsp_data in self.lsp_data.values_mut() {
12183            lsp_data.remove_server_data(for_server);
12184        }
12185        if let Some(local) = self.as_local_mut() {
12186            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12187            local
12188                .workspace_pull_diagnostics_result_ids
12189                .remove(&for_server);
12190            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12191                buffer_servers.remove(&for_server);
12192            }
12193        }
12194    }
12195
12196    pub fn result_id_for_buffer_pull(
12197        &self,
12198        server_id: LanguageServerId,
12199        buffer_id: BufferId,
12200        registration_id: &Option<SharedString>,
12201        cx: &App,
12202    ) -> Option<SharedString> {
12203        let abs_path = self
12204            .buffer_store
12205            .read(cx)
12206            .get(buffer_id)
12207            .and_then(|b| File::from_dyn(b.read(cx).file()))
12208            .map(|f| f.abs_path(cx))?;
12209        self.as_local()?
12210            .buffer_pull_diagnostics_result_ids
12211            .get(&server_id)?
12212            .get(registration_id)?
12213            .get(&abs_path)?
12214            .clone()
12215    }
12216
12217    /// Gets all result_ids for a workspace diagnostics pull request.
12218    /// 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.
12219    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12220    pub fn result_ids_for_workspace_refresh(
12221        &self,
12222        server_id: LanguageServerId,
12223        registration_id: &Option<SharedString>,
12224    ) -> HashMap<PathBuf, SharedString> {
12225        let Some(local) = self.as_local() else {
12226            return HashMap::default();
12227        };
12228        local
12229            .workspace_pull_diagnostics_result_ids
12230            .get(&server_id)
12231            .into_iter()
12232            .filter_map(|diagnostics| diagnostics.get(registration_id))
12233            .flatten()
12234            .filter_map(|(abs_path, result_id)| {
12235                let result_id = local
12236                    .buffer_pull_diagnostics_result_ids
12237                    .get(&server_id)
12238                    .and_then(|buffer_ids_result_ids| {
12239                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12240                    })
12241                    .cloned()
12242                    .flatten()
12243                    .or_else(|| result_id.clone())?;
12244                Some((abs_path.clone(), result_id))
12245            })
12246            .collect()
12247    }
12248
12249    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12250        if let Some(LanguageServerState::Running {
12251            workspace_diagnostics_refresh_tasks,
12252            ..
12253        }) = self
12254            .as_local_mut()
12255            .and_then(|local| local.language_servers.get_mut(&server_id))
12256        {
12257            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12258                diagnostics.refresh_tx.try_send(()).ok();
12259            }
12260        }
12261    }
12262
12263    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12264    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12265    /// which requires refreshing both workspace and document diagnostics.
12266    pub fn pull_document_diagnostics_for_server(
12267        &mut self,
12268        server_id: LanguageServerId,
12269        source_buffer_id: Option<BufferId>,
12270        cx: &mut Context<Self>,
12271    ) -> Shared<Task<()>> {
12272        let Some(local) = self.as_local_mut() else {
12273            return Task::ready(()).shared();
12274        };
12275        let mut buffers_to_refresh = HashSet::default();
12276        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12277            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12278                buffers_to_refresh.insert(*buffer_id);
12279            }
12280        }
12281
12282        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12283    }
12284
12285    pub fn pull_document_diagnostics_for_buffer_edit(
12286        &mut self,
12287        buffer_id: BufferId,
12288        cx: &mut Context<Self>,
12289    ) {
12290        let Some(local) = self.as_local_mut() else {
12291            return;
12292        };
12293        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12294        else {
12295            return;
12296        };
12297        for server_id in languages_servers {
12298            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12299        }
12300    }
12301
12302    fn apply_workspace_diagnostic_report(
12303        &mut self,
12304        server_id: LanguageServerId,
12305        report: lsp::WorkspaceDiagnosticReportResult,
12306        registration_id: Option<SharedString>,
12307        cx: &mut Context<Self>,
12308    ) {
12309        let mut workspace_diagnostics =
12310            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12311                report,
12312                server_id,
12313                registration_id,
12314            );
12315        workspace_diagnostics.retain(|d| match &d.diagnostics {
12316            LspPullDiagnostics::Response {
12317                server_id,
12318                registration_id,
12319                ..
12320            } => self.diagnostic_registration_exists(*server_id, registration_id),
12321            LspPullDiagnostics::Default => false,
12322        });
12323        let mut unchanged_buffers = HashMap::default();
12324        let workspace_diagnostics_updates = workspace_diagnostics
12325            .into_iter()
12326            .filter_map(
12327                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12328                    LspPullDiagnostics::Response {
12329                        server_id,
12330                        uri,
12331                        diagnostics,
12332                        registration_id,
12333                    } => Some((
12334                        server_id,
12335                        uri,
12336                        diagnostics,
12337                        workspace_diagnostics.version,
12338                        registration_id,
12339                    )),
12340                    LspPullDiagnostics::Default => None,
12341                },
12342            )
12343            .fold(
12344                HashMap::default(),
12345                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12346                    let (result_id, diagnostics) = match diagnostics {
12347                        PulledDiagnostics::Unchanged { result_id } => {
12348                            unchanged_buffers
12349                                .entry(new_registration_id.clone())
12350                                .or_insert_with(HashSet::default)
12351                                .insert(uri.clone());
12352                            (Some(result_id), Vec::new())
12353                        }
12354                        PulledDiagnostics::Changed {
12355                            result_id,
12356                            diagnostics,
12357                        } => (result_id, diagnostics),
12358                    };
12359                    let disk_based_sources = Cow::Owned(
12360                        self.language_server_adapter_for_id(server_id)
12361                            .as_ref()
12362                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12363                            .unwrap_or(&[])
12364                            .to_vec(),
12365                    );
12366
12367                    let Some(abs_path) = uri.to_file_path().ok() else {
12368                        return acc;
12369                    };
12370                    let Some((worktree, relative_path)) =
12371                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12372                    else {
12373                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12374                        return acc;
12375                    };
12376                    let worktree_id = worktree.read(cx).id();
12377                    let project_path = ProjectPath {
12378                        worktree_id,
12379                        path: relative_path,
12380                    };
12381                    if let Some(local_lsp_store) = self.as_local_mut() {
12382                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12383                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12384                    }
12385                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12386                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12387                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12388                        acc.entry(server_id)
12389                            .or_insert_with(HashMap::default)
12390                            .entry(new_registration_id.clone())
12391                            .or_insert_with(Vec::new)
12392                            .push(DocumentDiagnosticsUpdate {
12393                                server_id,
12394                                diagnostics: lsp::PublishDiagnosticsParams {
12395                                    uri,
12396                                    diagnostics,
12397                                    version,
12398                                },
12399                                result_id: result_id.map(SharedString::new),
12400                                disk_based_sources,
12401                                registration_id: new_registration_id,
12402                            });
12403                    }
12404                    acc
12405                },
12406            );
12407
12408        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12409            for (registration_id, diagnostic_updates) in diagnostic_updates {
12410                self.merge_lsp_diagnostics(
12411                    DiagnosticSourceKind::Pulled,
12412                    diagnostic_updates,
12413                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12414                        DiagnosticSourceKind::Pulled => {
12415                            old_diagnostic.registration_id != registration_id
12416                                || unchanged_buffers
12417                                    .get(&old_diagnostic.registration_id)
12418                                    .is_some_and(|unchanged_buffers| {
12419                                        unchanged_buffers.contains(&document_uri)
12420                                    })
12421                        }
12422                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12423                    },
12424                    cx,
12425                )
12426                .log_err();
12427            }
12428        }
12429    }
12430
12431    fn register_server_capabilities(
12432        &mut self,
12433        server_id: LanguageServerId,
12434        params: lsp::RegistrationParams,
12435        cx: &mut Context<Self>,
12436    ) -> anyhow::Result<()> {
12437        let server = self
12438            .language_server_for_id(server_id)
12439            .with_context(|| format!("no server {server_id} found"))?;
12440        for reg in params.registrations {
12441            match reg.method.as_str() {
12442                "workspace/didChangeWatchedFiles" => {
12443                    if let Some(options) = reg.register_options {
12444                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12445                            let caps = serde_json::from_value(options)?;
12446                            local_lsp_store
12447                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12448                            true
12449                        } else {
12450                            false
12451                        };
12452                        if notify {
12453                            notify_server_capabilities_updated(&server, cx);
12454                        }
12455                    }
12456                }
12457                "workspace/didChangeConfiguration" => {
12458                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12459                }
12460                "workspace/didChangeWorkspaceFolders" => {
12461                    // In this case register options is an empty object, we can ignore it
12462                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12463                        supported: Some(true),
12464                        change_notifications: Some(OneOf::Right(reg.id)),
12465                    };
12466                    server.update_capabilities(|capabilities| {
12467                        capabilities
12468                            .workspace
12469                            .get_or_insert_default()
12470                            .workspace_folders = Some(caps);
12471                    });
12472                    notify_server_capabilities_updated(&server, cx);
12473                }
12474                "workspace/symbol" => {
12475                    let options = parse_register_capabilities(reg)?;
12476                    server.update_capabilities(|capabilities| {
12477                        capabilities.workspace_symbol_provider = Some(options);
12478                    });
12479                    notify_server_capabilities_updated(&server, cx);
12480                }
12481                "workspace/fileOperations" => {
12482                    if let Some(options) = reg.register_options {
12483                        let caps = serde_json::from_value(options)?;
12484                        server.update_capabilities(|capabilities| {
12485                            capabilities
12486                                .workspace
12487                                .get_or_insert_default()
12488                                .file_operations = Some(caps);
12489                        });
12490                        notify_server_capabilities_updated(&server, cx);
12491                    }
12492                }
12493                "workspace/executeCommand" => {
12494                    if let Some(options) = reg.register_options {
12495                        let options = serde_json::from_value(options)?;
12496                        server.update_capabilities(|capabilities| {
12497                            capabilities.execute_command_provider = Some(options);
12498                        });
12499                        notify_server_capabilities_updated(&server, cx);
12500                    }
12501                }
12502                "textDocument/rangeFormatting" => {
12503                    let options = parse_register_capabilities(reg)?;
12504                    server.update_capabilities(|capabilities| {
12505                        capabilities.document_range_formatting_provider = Some(options);
12506                    });
12507                    notify_server_capabilities_updated(&server, cx);
12508                }
12509                "textDocument/onTypeFormatting" => {
12510                    if let Some(options) = reg
12511                        .register_options
12512                        .map(serde_json::from_value)
12513                        .transpose()?
12514                    {
12515                        server.update_capabilities(|capabilities| {
12516                            capabilities.document_on_type_formatting_provider = Some(options);
12517                        });
12518                        notify_server_capabilities_updated(&server, cx);
12519                    }
12520                }
12521                "textDocument/formatting" => {
12522                    let options = parse_register_capabilities(reg)?;
12523                    server.update_capabilities(|capabilities| {
12524                        capabilities.document_formatting_provider = Some(options);
12525                    });
12526                    notify_server_capabilities_updated(&server, cx);
12527                }
12528                "textDocument/rename" => {
12529                    let options = parse_register_capabilities(reg)?;
12530                    server.update_capabilities(|capabilities| {
12531                        capabilities.rename_provider = Some(options);
12532                    });
12533                    notify_server_capabilities_updated(&server, cx);
12534                }
12535                "textDocument/inlayHint" => {
12536                    let options = parse_register_capabilities(reg)?;
12537                    server.update_capabilities(|capabilities| {
12538                        capabilities.inlay_hint_provider = Some(options);
12539                    });
12540                    notify_server_capabilities_updated(&server, cx);
12541                }
12542                "textDocument/documentSymbol" => {
12543                    let options = parse_register_capabilities(reg)?;
12544                    server.update_capabilities(|capabilities| {
12545                        capabilities.document_symbol_provider = Some(options);
12546                    });
12547                    notify_server_capabilities_updated(&server, cx);
12548                }
12549                "textDocument/codeAction" => {
12550                    let options = parse_register_capabilities(reg)?;
12551                    let provider = match options {
12552                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12553                        OneOf::Right(caps) => caps,
12554                    };
12555                    server.update_capabilities(|capabilities| {
12556                        capabilities.code_action_provider = Some(provider);
12557                    });
12558                    notify_server_capabilities_updated(&server, cx);
12559                }
12560                "textDocument/definition" => {
12561                    let options = parse_register_capabilities(reg)?;
12562                    server.update_capabilities(|capabilities| {
12563                        capabilities.definition_provider = Some(options);
12564                    });
12565                    notify_server_capabilities_updated(&server, cx);
12566                }
12567                "textDocument/completion" => {
12568                    if let Some(caps) = reg
12569                        .register_options
12570                        .map(serde_json::from_value::<CompletionOptions>)
12571                        .transpose()?
12572                    {
12573                        server.update_capabilities(|capabilities| {
12574                            capabilities.completion_provider = Some(caps.clone());
12575                        });
12576
12577                        if let Some(local) = self.as_local() {
12578                            let mut buffers_with_language_server = Vec::new();
12579                            for handle in self.buffer_store.read(cx).buffers() {
12580                                let buffer_id = handle.read(cx).remote_id();
12581                                if local
12582                                    .buffers_opened_in_servers
12583                                    .get(&buffer_id)
12584                                    .filter(|s| s.contains(&server_id))
12585                                    .is_some()
12586                                {
12587                                    buffers_with_language_server.push(handle);
12588                                }
12589                            }
12590                            let triggers = caps
12591                                .trigger_characters
12592                                .unwrap_or_default()
12593                                .into_iter()
12594                                .collect::<BTreeSet<_>>();
12595                            for handle in buffers_with_language_server {
12596                                let triggers = triggers.clone();
12597                                let _ = handle.update(cx, move |buffer, cx| {
12598                                    buffer.set_completion_triggers(server_id, triggers, cx);
12599                                });
12600                            }
12601                        }
12602                        notify_server_capabilities_updated(&server, cx);
12603                    }
12604                }
12605                "textDocument/hover" => {
12606                    let options = parse_register_capabilities(reg)?;
12607                    let provider = match options {
12608                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12609                        OneOf::Right(caps) => caps,
12610                    };
12611                    server.update_capabilities(|capabilities| {
12612                        capabilities.hover_provider = Some(provider);
12613                    });
12614                    notify_server_capabilities_updated(&server, cx);
12615                }
12616                "textDocument/signatureHelp" => {
12617                    if let Some(caps) = reg
12618                        .register_options
12619                        .map(serde_json::from_value)
12620                        .transpose()?
12621                    {
12622                        server.update_capabilities(|capabilities| {
12623                            capabilities.signature_help_provider = Some(caps);
12624                        });
12625                        notify_server_capabilities_updated(&server, cx);
12626                    }
12627                }
12628                "textDocument/didChange" => {
12629                    if let Some(sync_kind) = reg
12630                        .register_options
12631                        .and_then(|opts| opts.get("syncKind").cloned())
12632                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12633                        .transpose()?
12634                    {
12635                        server.update_capabilities(|capabilities| {
12636                            let mut sync_options =
12637                                Self::take_text_document_sync_options(capabilities);
12638                            sync_options.change = Some(sync_kind);
12639                            capabilities.text_document_sync =
12640                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12641                        });
12642                        notify_server_capabilities_updated(&server, cx);
12643                    }
12644                }
12645                "textDocument/didSave" => {
12646                    if let Some(include_text) = reg
12647                        .register_options
12648                        .map(|opts| {
12649                            let transpose = opts
12650                                .get("includeText")
12651                                .cloned()
12652                                .map(serde_json::from_value::<Option<bool>>)
12653                                .transpose();
12654                            match transpose {
12655                                Ok(value) => Ok(value.flatten()),
12656                                Err(e) => Err(e),
12657                            }
12658                        })
12659                        .transpose()?
12660                    {
12661                        server.update_capabilities(|capabilities| {
12662                            let mut sync_options =
12663                                Self::take_text_document_sync_options(capabilities);
12664                            sync_options.save =
12665                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12666                                    include_text,
12667                                }));
12668                            capabilities.text_document_sync =
12669                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12670                        });
12671                        notify_server_capabilities_updated(&server, cx);
12672                    }
12673                }
12674                "textDocument/codeLens" => {
12675                    if let Some(caps) = reg
12676                        .register_options
12677                        .map(serde_json::from_value)
12678                        .transpose()?
12679                    {
12680                        server.update_capabilities(|capabilities| {
12681                            capabilities.code_lens_provider = Some(caps);
12682                        });
12683                        notify_server_capabilities_updated(&server, cx);
12684                    }
12685                }
12686                "textDocument/diagnostic" => {
12687                    if let Some(caps) = reg
12688                        .register_options
12689                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12690                        .transpose()?
12691                    {
12692                        let local = self
12693                            .as_local_mut()
12694                            .context("Expected LSP Store to be local")?;
12695                        let state = local
12696                            .language_servers
12697                            .get_mut(&server_id)
12698                            .context("Could not obtain Language Servers state")?;
12699                        local
12700                            .language_server_dynamic_registrations
12701                            .entry(server_id)
12702                            .or_default()
12703                            .diagnostics
12704                            .insert(Some(reg.id.clone()), caps.clone());
12705
12706                        let supports_workspace_diagnostics =
12707                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12708                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12709                                    diagnostic_options.workspace_diagnostics
12710                                }
12711                                DiagnosticServerCapabilities::RegistrationOptions(
12712                                    diagnostic_registration_options,
12713                                ) => {
12714                                    diagnostic_registration_options
12715                                        .diagnostic_options
12716                                        .workspace_diagnostics
12717                                }
12718                            };
12719
12720                        if supports_workspace_diagnostics(&caps) {
12721                            if let LanguageServerState::Running {
12722                                workspace_diagnostics_refresh_tasks,
12723                                ..
12724                            } = state
12725                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12726                                    Some(reg.id.clone()),
12727                                    caps.clone(),
12728                                    server.clone(),
12729                                    cx,
12730                                )
12731                            {
12732                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12733                            }
12734                        }
12735
12736                        server.update_capabilities(|capabilities| {
12737                            capabilities.diagnostic_provider = Some(caps);
12738                        });
12739
12740                        notify_server_capabilities_updated(&server, cx);
12741
12742                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12743                    }
12744                }
12745                "textDocument/documentColor" => {
12746                    let options = parse_register_capabilities(reg)?;
12747                    let provider = match options {
12748                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12749                        OneOf::Right(caps) => caps,
12750                    };
12751                    server.update_capabilities(|capabilities| {
12752                        capabilities.color_provider = Some(provider);
12753                    });
12754                    notify_server_capabilities_updated(&server, cx);
12755                }
12756                "textDocument/foldingRange" => {
12757                    let options = parse_register_capabilities(reg)?;
12758                    let provider = match options {
12759                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12760                        OneOf::Right(caps) => caps,
12761                    };
12762                    server.update_capabilities(|capabilities| {
12763                        capabilities.folding_range_provider = Some(provider);
12764                    });
12765                    notify_server_capabilities_updated(&server, cx);
12766                }
12767                _ => log::warn!("unhandled capability registration: {reg:?}"),
12768            }
12769        }
12770
12771        Ok(())
12772    }
12773
12774    fn unregister_server_capabilities(
12775        &mut self,
12776        server_id: LanguageServerId,
12777        params: lsp::UnregistrationParams,
12778        cx: &mut Context<Self>,
12779    ) -> anyhow::Result<()> {
12780        let server = self
12781            .language_server_for_id(server_id)
12782            .with_context(|| format!("no server {server_id} found"))?;
12783        for unreg in params.unregisterations.iter() {
12784            match unreg.method.as_str() {
12785                "workspace/didChangeWatchedFiles" => {
12786                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12787                        local_lsp_store
12788                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12789                        true
12790                    } else {
12791                        false
12792                    };
12793                    if notify {
12794                        notify_server_capabilities_updated(&server, cx);
12795                    }
12796                }
12797                "workspace/didChangeConfiguration" => {
12798                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12799                }
12800                "workspace/didChangeWorkspaceFolders" => {
12801                    server.update_capabilities(|capabilities| {
12802                        capabilities
12803                            .workspace
12804                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12805                                workspace_folders: None,
12806                                file_operations: None,
12807                            })
12808                            .workspace_folders = None;
12809                    });
12810                    notify_server_capabilities_updated(&server, cx);
12811                }
12812                "workspace/symbol" => {
12813                    server.update_capabilities(|capabilities| {
12814                        capabilities.workspace_symbol_provider = None
12815                    });
12816                    notify_server_capabilities_updated(&server, cx);
12817                }
12818                "workspace/fileOperations" => {
12819                    server.update_capabilities(|capabilities| {
12820                        capabilities
12821                            .workspace
12822                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12823                                workspace_folders: None,
12824                                file_operations: None,
12825                            })
12826                            .file_operations = None;
12827                    });
12828                    notify_server_capabilities_updated(&server, cx);
12829                }
12830                "workspace/executeCommand" => {
12831                    server.update_capabilities(|capabilities| {
12832                        capabilities.execute_command_provider = None;
12833                    });
12834                    notify_server_capabilities_updated(&server, cx);
12835                }
12836                "textDocument/rangeFormatting" => {
12837                    server.update_capabilities(|capabilities| {
12838                        capabilities.document_range_formatting_provider = None
12839                    });
12840                    notify_server_capabilities_updated(&server, cx);
12841                }
12842                "textDocument/onTypeFormatting" => {
12843                    server.update_capabilities(|capabilities| {
12844                        capabilities.document_on_type_formatting_provider = None;
12845                    });
12846                    notify_server_capabilities_updated(&server, cx);
12847                }
12848                "textDocument/formatting" => {
12849                    server.update_capabilities(|capabilities| {
12850                        capabilities.document_formatting_provider = None;
12851                    });
12852                    notify_server_capabilities_updated(&server, cx);
12853                }
12854                "textDocument/rename" => {
12855                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12856                    notify_server_capabilities_updated(&server, cx);
12857                }
12858                "textDocument/codeAction" => {
12859                    server.update_capabilities(|capabilities| {
12860                        capabilities.code_action_provider = None;
12861                    });
12862                    notify_server_capabilities_updated(&server, cx);
12863                }
12864                "textDocument/definition" => {
12865                    server.update_capabilities(|capabilities| {
12866                        capabilities.definition_provider = None;
12867                    });
12868                    notify_server_capabilities_updated(&server, cx);
12869                }
12870                "textDocument/completion" => {
12871                    server.update_capabilities(|capabilities| {
12872                        capabilities.completion_provider = None;
12873                    });
12874                    notify_server_capabilities_updated(&server, cx);
12875                }
12876                "textDocument/hover" => {
12877                    server.update_capabilities(|capabilities| {
12878                        capabilities.hover_provider = None;
12879                    });
12880                    notify_server_capabilities_updated(&server, cx);
12881                }
12882                "textDocument/signatureHelp" => {
12883                    server.update_capabilities(|capabilities| {
12884                        capabilities.signature_help_provider = None;
12885                    });
12886                    notify_server_capabilities_updated(&server, cx);
12887                }
12888                "textDocument/didChange" => {
12889                    server.update_capabilities(|capabilities| {
12890                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12891                        sync_options.change = None;
12892                        capabilities.text_document_sync =
12893                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12894                    });
12895                    notify_server_capabilities_updated(&server, cx);
12896                }
12897                "textDocument/didSave" => {
12898                    server.update_capabilities(|capabilities| {
12899                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12900                        sync_options.save = None;
12901                        capabilities.text_document_sync =
12902                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12903                    });
12904                    notify_server_capabilities_updated(&server, cx);
12905                }
12906                "textDocument/codeLens" => {
12907                    server.update_capabilities(|capabilities| {
12908                        capabilities.code_lens_provider = None;
12909                    });
12910                    notify_server_capabilities_updated(&server, cx);
12911                }
12912                "textDocument/diagnostic" => {
12913                    let local = self
12914                        .as_local_mut()
12915                        .context("Expected LSP Store to be local")?;
12916
12917                    let state = local
12918                        .language_servers
12919                        .get_mut(&server_id)
12920                        .context("Could not obtain Language Servers state")?;
12921                    let registrations = local
12922                        .language_server_dynamic_registrations
12923                        .get_mut(&server_id)
12924                        .with_context(|| {
12925                            format!("Expected dynamic registration to exist for server {server_id}")
12926                        })?;
12927                    registrations.diagnostics
12928                        .remove(&Some(unreg.id.clone()))
12929                        .with_context(|| format!(
12930                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12931                            unreg.id)
12932                        )?;
12933                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12934
12935                    if let LanguageServerState::Running {
12936                        workspace_diagnostics_refresh_tasks,
12937                        ..
12938                    } = state
12939                    {
12940                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12941                    }
12942
12943                    self.clear_unregistered_diagnostics(
12944                        server_id,
12945                        SharedString::from(unreg.id.clone()),
12946                        cx,
12947                    )?;
12948
12949                    if removed_last_diagnostic_provider {
12950                        server.update_capabilities(|capabilities| {
12951                            debug_assert!(capabilities.diagnostic_provider.is_some());
12952                            capabilities.diagnostic_provider = None;
12953                        });
12954                    }
12955
12956                    notify_server_capabilities_updated(&server, cx);
12957                }
12958                "textDocument/documentColor" => {
12959                    server.update_capabilities(|capabilities| {
12960                        capabilities.color_provider = None;
12961                    });
12962                    notify_server_capabilities_updated(&server, cx);
12963                }
12964                "textDocument/foldingRange" => {
12965                    server.update_capabilities(|capabilities| {
12966                        capabilities.folding_range_provider = None;
12967                    });
12968                    notify_server_capabilities_updated(&server, cx);
12969                }
12970                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12971            }
12972        }
12973
12974        Ok(())
12975    }
12976
12977    fn clear_unregistered_diagnostics(
12978        &mut self,
12979        server_id: LanguageServerId,
12980        cleared_registration_id: SharedString,
12981        cx: &mut Context<Self>,
12982    ) -> anyhow::Result<()> {
12983        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
12984
12985        self.buffer_store.update(cx, |buffer_store, cx| {
12986            for buffer_handle in buffer_store.buffers() {
12987                let buffer = buffer_handle.read(cx);
12988                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
12989                let Some(abs_path) = abs_path else {
12990                    continue;
12991                };
12992                affected_abs_paths.insert(abs_path);
12993            }
12994        });
12995
12996        let local = self.as_local().context("Expected LSP Store to be local")?;
12997        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
12998            let Some(worktree) = self
12999                .worktree_store
13000                .read(cx)
13001                .worktree_for_id(*worktree_id, cx)
13002            else {
13003                continue;
13004            };
13005
13006            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13007                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13008                    let has_matching_registration =
13009                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13010                            entry.diagnostic.registration_id.as_ref()
13011                                == Some(&cleared_registration_id)
13012                        });
13013                    if has_matching_registration {
13014                        let abs_path = worktree.read(cx).absolutize(rel_path);
13015                        affected_abs_paths.insert(abs_path);
13016                    }
13017                }
13018            }
13019        }
13020
13021        if affected_abs_paths.is_empty() {
13022            return Ok(());
13023        }
13024
13025        // Send a fake diagnostic update which clears the state for the registration ID
13026        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13027            affected_abs_paths
13028                .into_iter()
13029                .map(|abs_path| DocumentDiagnosticsUpdate {
13030                    diagnostics: DocumentDiagnostics {
13031                        diagnostics: Vec::new(),
13032                        document_abs_path: abs_path,
13033                        version: None,
13034                    },
13035                    result_id: None,
13036                    registration_id: Some(cleared_registration_id.clone()),
13037                    server_id,
13038                    disk_based_sources: Cow::Borrowed(&[]),
13039                })
13040                .collect();
13041
13042        let merge_registration_id = cleared_registration_id.clone();
13043        self.merge_diagnostic_entries(
13044            clears,
13045            move |_, diagnostic, _| {
13046                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13047                    diagnostic.registration_id != Some(merge_registration_id.clone())
13048                } else {
13049                    true
13050                }
13051            },
13052            cx,
13053        )?;
13054
13055        Ok(())
13056    }
13057
13058    async fn deduplicate_range_based_lsp_requests<T>(
13059        lsp_store: &Entity<Self>,
13060        server_id: Option<LanguageServerId>,
13061        lsp_request_id: LspRequestId,
13062        proto_request: &T::ProtoRequest,
13063        range: Range<Anchor>,
13064        cx: &mut AsyncApp,
13065    ) -> Result<()>
13066    where
13067        T: LspCommand,
13068        T::ProtoRequest: proto::LspRequestMessage,
13069    {
13070        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13071        let version = deserialize_version(proto_request.buffer_version());
13072        let buffer = lsp_store.update(cx, |this, cx| {
13073            this.buffer_store.read(cx).get_existing(buffer_id)
13074        })?;
13075        buffer
13076            .update(cx, |buffer, _| buffer.wait_for_version(version))
13077            .await?;
13078        lsp_store.update(cx, |lsp_store, cx| {
13079            let buffer_snapshot = buffer.read(cx).snapshot();
13080            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13081            let chunks_queried_for = lsp_data
13082                .inlay_hints
13083                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13084                .collect::<Vec<_>>();
13085            match chunks_queried_for.as_slice() {
13086                &[chunk] => {
13087                    let key = LspKey {
13088                        request_type: TypeId::of::<T>(),
13089                        server_queried: server_id,
13090                    };
13091                    let previous_request = lsp_data
13092                        .chunk_lsp_requests
13093                        .entry(key)
13094                        .or_default()
13095                        .insert(chunk, lsp_request_id);
13096                    if let Some((previous_request, running_requests)) =
13097                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13098                    {
13099                        running_requests.remove(&previous_request);
13100                    }
13101                }
13102                _ambiguous_chunks => {
13103                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13104                    // there, a buffer version-based check will be performed and outdated requests discarded.
13105                }
13106            }
13107            anyhow::Ok(())
13108        })?;
13109
13110        Ok(())
13111    }
13112
13113    async fn query_lsp_locally<T>(
13114        lsp_store: Entity<Self>,
13115        for_server_id: Option<LanguageServerId>,
13116        sender_id: proto::PeerId,
13117        lsp_request_id: LspRequestId,
13118        proto_request: T::ProtoRequest,
13119        position: Option<Anchor>,
13120        cx: &mut AsyncApp,
13121    ) -> Result<()>
13122    where
13123        T: LspCommand + Clone,
13124        T::ProtoRequest: proto::LspRequestMessage,
13125        <T::ProtoRequest as proto::RequestMessage>::Response:
13126            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13127    {
13128        let (buffer_version, buffer) =
13129            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13130        let request =
13131            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13132        let key = LspKey {
13133            request_type: TypeId::of::<T>(),
13134            server_queried: for_server_id,
13135        };
13136        lsp_store.update(cx, |lsp_store, cx| {
13137            let request_task = match for_server_id {
13138                Some(server_id) => {
13139                    let server_task = lsp_store.request_lsp(
13140                        buffer.clone(),
13141                        LanguageServerToQuery::Other(server_id),
13142                        request.clone(),
13143                        cx,
13144                    );
13145                    cx.background_spawn(async move {
13146                        let mut responses = Vec::new();
13147                        match server_task.await {
13148                            Ok(response) => responses.push((server_id, response)),
13149                            // rust-analyzer likes to error with this when its still loading up
13150                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13151                            Err(e) => log::error!(
13152                                "Error handling response for request {request:?}: {e:#}"
13153                            ),
13154                        }
13155                        responses
13156                    })
13157                }
13158                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13159            };
13160            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13161            if T::ProtoRequest::stop_previous_requests() {
13162                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13163                    lsp_requests.clear();
13164                }
13165            }
13166            lsp_data.lsp_requests.entry(key).or_default().insert(
13167                lsp_request_id,
13168                cx.spawn(async move |lsp_store, cx| {
13169                    let response = request_task.await;
13170                    lsp_store
13171                        .update(cx, |lsp_store, cx| {
13172                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13173                            {
13174                                let response = response
13175                                    .into_iter()
13176                                    .map(|(server_id, response)| {
13177                                        (
13178                                            server_id.to_proto(),
13179                                            T::response_to_proto(
13180                                                response,
13181                                                lsp_store,
13182                                                sender_id,
13183                                                &buffer_version,
13184                                                cx,
13185                                            )
13186                                            .into(),
13187                                        )
13188                                    })
13189                                    .collect::<HashMap<_, _>>();
13190                                match client.send_lsp_response::<T::ProtoRequest>(
13191                                    project_id,
13192                                    lsp_request_id,
13193                                    response,
13194                                ) {
13195                                    Ok(()) => {}
13196                                    Err(e) => {
13197                                        log::error!("Failed to send LSP response: {e:#}",)
13198                                    }
13199                                }
13200                            }
13201                        })
13202                        .ok();
13203                }),
13204            );
13205        });
13206        Ok(())
13207    }
13208
13209    async fn wait_for_buffer_version<T>(
13210        lsp_store: &Entity<Self>,
13211        proto_request: &T::ProtoRequest,
13212        cx: &mut AsyncApp,
13213    ) -> Result<(Global, Entity<Buffer>)>
13214    where
13215        T: LspCommand,
13216        T::ProtoRequest: proto::LspRequestMessage,
13217    {
13218        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13219        let version = deserialize_version(proto_request.buffer_version());
13220        let buffer = lsp_store.update(cx, |this, cx| {
13221            this.buffer_store.read(cx).get_existing(buffer_id)
13222        })?;
13223        buffer
13224            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13225            .await?;
13226        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13227        Ok((buffer_version, buffer))
13228    }
13229
13230    fn take_text_document_sync_options(
13231        capabilities: &mut lsp::ServerCapabilities,
13232    ) -> lsp::TextDocumentSyncOptions {
13233        match capabilities.text_document_sync.take() {
13234            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13235            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13236                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13237                sync_options.change = Some(sync_kind);
13238                sync_options
13239            }
13240            None => lsp::TextDocumentSyncOptions::default(),
13241        }
13242    }
13243
13244    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13245        self.downstream_client.clone()
13246    }
13247
13248    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13249        self.worktree_store.clone()
13250    }
13251
13252    /// Gets what's stored in the LSP data for the given buffer.
13253    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13254        self.lsp_data.get_mut(&buffer_id)
13255    }
13256
13257    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13258    /// new [`BufferLspData`] will be created to replace the previous state.
13259    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13260        let (buffer_id, buffer_version) =
13261            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13262        let lsp_data = self
13263            .lsp_data
13264            .entry(buffer_id)
13265            .or_insert_with(|| BufferLspData::new(buffer, cx));
13266        if buffer_version.changed_since(&lsp_data.buffer_version) {
13267            // To send delta requests for semantic tokens, the previous tokens
13268            // need to be kept between buffer changes.
13269            let semantic_tokens = lsp_data.semantic_tokens.take();
13270            *lsp_data = BufferLspData::new(buffer, cx);
13271            lsp_data.semantic_tokens = semantic_tokens;
13272        }
13273        lsp_data
13274    }
13275}
13276
13277// Registration with registerOptions as null, should fallback to true.
13278// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13279fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13280    reg: lsp::Registration,
13281) -> Result<OneOf<bool, T>> {
13282    Ok(match reg.register_options {
13283        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13284        None => OneOf::Left(true),
13285    })
13286}
13287
13288fn subscribe_to_binary_statuses(
13289    languages: &Arc<LanguageRegistry>,
13290    cx: &mut Context<'_, LspStore>,
13291) -> Task<()> {
13292    let mut server_statuses = languages.language_server_binary_statuses();
13293    cx.spawn(async move |lsp_store, cx| {
13294        while let Some((server_name, binary_status)) = server_statuses.next().await {
13295            if lsp_store
13296                .update(cx, |_, cx| {
13297                    let mut message = None;
13298                    let binary_status = match binary_status {
13299                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13300                        BinaryStatus::CheckingForUpdate => {
13301                            proto::ServerBinaryStatus::CheckingForUpdate
13302                        }
13303                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13304                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13305                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13306                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13307                        BinaryStatus::Failed { error } => {
13308                            message = Some(error);
13309                            proto::ServerBinaryStatus::Failed
13310                        }
13311                    };
13312                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13313                        // Binary updates are about the binary that might not have any language server id at that point.
13314                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13315                        language_server_id: LanguageServerId(0),
13316                        name: Some(server_name),
13317                        message: proto::update_language_server::Variant::StatusUpdate(
13318                            proto::StatusUpdate {
13319                                message,
13320                                status: Some(proto::status_update::Status::Binary(
13321                                    binary_status as i32,
13322                                )),
13323                            },
13324                        ),
13325                    });
13326                })
13327                .is_err()
13328            {
13329                break;
13330            }
13331        }
13332    })
13333}
13334
13335fn lsp_workspace_diagnostics_refresh(
13336    registration_id: Option<String>,
13337    options: DiagnosticServerCapabilities,
13338    server: Arc<LanguageServer>,
13339    cx: &mut Context<'_, LspStore>,
13340) -> Option<WorkspaceRefreshTask> {
13341    let identifier = workspace_diagnostic_identifier(&options)?;
13342    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13343
13344    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13345    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13346    refresh_tx.try_send(()).ok();
13347
13348    let request_timeout = ProjectSettings::get_global(cx)
13349        .global_lsp_settings
13350        .get_request_timeout();
13351
13352    // 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.
13353    // This allows users to increase the duration if need be
13354    let timeout = if request_timeout != Duration::ZERO {
13355        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13356    } else {
13357        request_timeout
13358    };
13359
13360    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13361        let mut attempts = 0;
13362        let max_attempts = 50;
13363        let mut requests = 0;
13364
13365        loop {
13366            let Some(()) = refresh_rx.recv().await else {
13367                return;
13368            };
13369
13370            'request: loop {
13371                requests += 1;
13372                if attempts > max_attempts {
13373                    log::error!(
13374                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13375                    );
13376                    return;
13377                }
13378                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13379                cx.background_executor()
13380                    .timer(Duration::from_millis(backoff_millis))
13381                    .await;
13382                attempts += 1;
13383
13384                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13385                    lsp_store
13386                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13387                        .into_iter()
13388                        .filter_map(|(abs_path, result_id)| {
13389                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13390                            Some(lsp::PreviousResultId {
13391                                uri,
13392                                value: result_id.to_string(),
13393                            })
13394                        })
13395                        .collect()
13396                }) else {
13397                    return;
13398                };
13399
13400                let token = if let Some(registration_id) = &registration_id {
13401                    format!(
13402                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13403                        server.server_id(),
13404                    )
13405                } else {
13406                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13407                };
13408
13409                progress_rx.try_recv().ok();
13410                let timer = server.request_timer(timeout).fuse();
13411                let progress = pin!(progress_rx.recv().fuse());
13412                let response_result = server
13413                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13414                        lsp::WorkspaceDiagnosticParams {
13415                            previous_result_ids,
13416                            identifier: identifier.clone(),
13417                            work_done_progress_params: Default::default(),
13418                            partial_result_params: lsp::PartialResultParams {
13419                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13420                            },
13421                        },
13422                        select(timer, progress).then(|either| match either {
13423                            Either::Left((message, ..)) => ready(message).left_future(),
13424                            Either::Right(..) => pending::<String>().right_future(),
13425                        }),
13426                    )
13427                    .await;
13428
13429                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13430                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13431                match response_result {
13432                    ConnectionResult::Timeout => {
13433                        log::error!("Timeout during workspace diagnostics pull");
13434                        continue 'request;
13435                    }
13436                    ConnectionResult::ConnectionReset => {
13437                        log::error!("Server closed a workspace diagnostics pull request");
13438                        continue 'request;
13439                    }
13440                    ConnectionResult::Result(Err(e)) => {
13441                        log::error!("Error during workspace diagnostics pull: {e:#}");
13442                        break 'request;
13443                    }
13444                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13445                        attempts = 0;
13446                        if lsp_store
13447                            .update(cx, |lsp_store, cx| {
13448                                lsp_store.apply_workspace_diagnostic_report(
13449                                    server.server_id(),
13450                                    pulled_diagnostics,
13451                                    registration_id_shared.clone(),
13452                                    cx,
13453                                )
13454                            })
13455                            .is_err()
13456                        {
13457                            return;
13458                        }
13459                        break 'request;
13460                    }
13461                }
13462            }
13463        }
13464    });
13465
13466    Some(WorkspaceRefreshTask {
13467        refresh_tx,
13468        progress_tx,
13469        task: workspace_query_language_server,
13470    })
13471}
13472
13473fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13474    match &options {
13475        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13476            .identifier
13477            .as_deref()
13478            .map(SharedString::new),
13479        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13480            let diagnostic_options = &registration_options.diagnostic_options;
13481            diagnostic_options
13482                .identifier
13483                .as_deref()
13484                .map(SharedString::new)
13485        }
13486    }
13487}
13488
13489fn workspace_diagnostic_identifier(
13490    options: &DiagnosticServerCapabilities,
13491) -> Option<Option<String>> {
13492    match &options {
13493        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13494            if !diagnostic_options.workspace_diagnostics {
13495                return None;
13496            }
13497            Some(diagnostic_options.identifier.clone())
13498        }
13499        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13500            let diagnostic_options = &registration_options.diagnostic_options;
13501            if !diagnostic_options.workspace_diagnostics {
13502                return None;
13503            }
13504            Some(diagnostic_options.identifier.clone())
13505        }
13506    }
13507}
13508
13509fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13510    let CompletionSource::BufferWord {
13511        word_range,
13512        resolved,
13513    } = &mut completion.source
13514    else {
13515        return;
13516    };
13517    if *resolved {
13518        return;
13519    }
13520
13521    if completion.new_text
13522        != snapshot
13523            .text_for_range(word_range.clone())
13524            .collect::<String>()
13525    {
13526        return;
13527    }
13528
13529    let mut offset = 0;
13530    for chunk in snapshot.chunks(word_range.clone(), true) {
13531        let end_offset = offset + chunk.text.len();
13532        if let Some(highlight_id) = chunk.syntax_highlight_id {
13533            completion
13534                .label
13535                .runs
13536                .push((offset..end_offset, highlight_id));
13537        }
13538        offset = end_offset;
13539    }
13540    *resolved = true;
13541}
13542
13543impl EventEmitter<LspStoreEvent> for LspStore {}
13544
13545fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13546    hover
13547        .contents
13548        .retain(|hover_block| !hover_block.text.trim().is_empty());
13549    if hover.contents.is_empty() {
13550        None
13551    } else {
13552        Some(hover)
13553    }
13554}
13555
13556async fn populate_labels_for_completions(
13557    new_completions: Vec<CoreCompletion>,
13558    language: Option<Arc<Language>>,
13559    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13560) -> Vec<Completion> {
13561    let lsp_completions = new_completions
13562        .iter()
13563        .filter_map(|new_completion| {
13564            new_completion
13565                .source
13566                .lsp_completion(true)
13567                .map(|lsp_completion| lsp_completion.into_owned())
13568        })
13569        .collect::<Vec<_>>();
13570
13571    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13572        lsp_adapter
13573            .labels_for_completions(&lsp_completions, language)
13574            .await
13575            .log_err()
13576            .unwrap_or_default()
13577    } else {
13578        Vec::new()
13579    }
13580    .into_iter()
13581    .fuse();
13582
13583    let mut completions = Vec::new();
13584    for completion in new_completions {
13585        match completion.source.lsp_completion(true) {
13586            Some(lsp_completion) => {
13587                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13588
13589                let mut label = labels.next().flatten().unwrap_or_else(|| {
13590                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13591                });
13592                ensure_uniform_list_compatible_label(&mut label);
13593                completions.push(Completion {
13594                    label,
13595                    documentation,
13596                    replace_range: completion.replace_range,
13597                    new_text: completion.new_text,
13598                    insert_text_mode: lsp_completion.insert_text_mode,
13599                    source: completion.source,
13600                    icon_path: None,
13601                    confirm: None,
13602                    match_start: None,
13603                    snippet_deduplication_key: None,
13604                });
13605            }
13606            None => {
13607                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13608                ensure_uniform_list_compatible_label(&mut label);
13609                completions.push(Completion {
13610                    label,
13611                    documentation: None,
13612                    replace_range: completion.replace_range,
13613                    new_text: completion.new_text,
13614                    source: completion.source,
13615                    insert_text_mode: None,
13616                    icon_path: None,
13617                    confirm: None,
13618                    match_start: None,
13619                    snippet_deduplication_key: None,
13620                });
13621            }
13622        }
13623    }
13624    completions
13625}
13626
13627#[derive(Debug)]
13628pub enum LanguageServerToQuery {
13629    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13630    FirstCapable,
13631    /// Query a specific language server.
13632    Other(LanguageServerId),
13633}
13634
13635#[derive(Default)]
13636struct RenamePathsWatchedForServer {
13637    did_rename: Vec<RenameActionPredicate>,
13638    will_rename: Vec<RenameActionPredicate>,
13639}
13640
13641impl RenamePathsWatchedForServer {
13642    fn with_did_rename_patterns(
13643        mut self,
13644        did_rename: Option<&FileOperationRegistrationOptions>,
13645    ) -> Self {
13646        if let Some(did_rename) = did_rename {
13647            self.did_rename = did_rename
13648                .filters
13649                .iter()
13650                .filter_map(|filter| filter.try_into().log_err())
13651                .collect();
13652        }
13653        self
13654    }
13655    fn with_will_rename_patterns(
13656        mut self,
13657        will_rename: Option<&FileOperationRegistrationOptions>,
13658    ) -> Self {
13659        if let Some(will_rename) = will_rename {
13660            self.will_rename = will_rename
13661                .filters
13662                .iter()
13663                .filter_map(|filter| filter.try_into().log_err())
13664                .collect();
13665        }
13666        self
13667    }
13668
13669    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13670        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13671    }
13672    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13673        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13674    }
13675}
13676
13677impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13678    type Error = globset::Error;
13679    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13680        Ok(Self {
13681            kind: ops.pattern.matches.clone(),
13682            glob: GlobBuilder::new(&ops.pattern.glob)
13683                .case_insensitive(
13684                    ops.pattern
13685                        .options
13686                        .as_ref()
13687                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13688                )
13689                .build()?
13690                .compile_matcher(),
13691        })
13692    }
13693}
13694struct RenameActionPredicate {
13695    glob: GlobMatcher,
13696    kind: Option<FileOperationPatternKind>,
13697}
13698
13699impl RenameActionPredicate {
13700    // Returns true if language server should be notified
13701    fn eval(&self, path: &str, is_dir: bool) -> bool {
13702        self.kind.as_ref().is_none_or(|kind| {
13703            let expected_kind = if is_dir {
13704                FileOperationPatternKind::Folder
13705            } else {
13706                FileOperationPatternKind::File
13707            };
13708            kind == &expected_kind
13709        }) && self.glob.is_match(path)
13710    }
13711}
13712
13713#[derive(Default)]
13714struct LanguageServerWatchedPaths {
13715    worktree_paths: HashMap<WorktreeId, GlobSet>,
13716    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13717}
13718
13719#[derive(Default)]
13720struct LanguageServerWatchedPathsBuilder {
13721    worktree_paths: HashMap<WorktreeId, GlobSet>,
13722    abs_paths: HashMap<Arc<Path>, GlobSet>,
13723}
13724
13725impl LanguageServerWatchedPathsBuilder {
13726    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13727        self.worktree_paths.insert(worktree_id, glob_set);
13728    }
13729    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13730        self.abs_paths.insert(path, glob_set);
13731    }
13732    fn build(
13733        self,
13734        fs: Arc<dyn Fs>,
13735        language_server_id: LanguageServerId,
13736        cx: &mut Context<LspStore>,
13737    ) -> LanguageServerWatchedPaths {
13738        let lsp_store = cx.weak_entity();
13739
13740        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13741        let abs_paths = self
13742            .abs_paths
13743            .into_iter()
13744            .map(|(abs_path, globset)| {
13745                let task = cx.spawn({
13746                    let abs_path = abs_path.clone();
13747                    let fs = fs.clone();
13748
13749                    let lsp_store = lsp_store.clone();
13750                    async move |_, cx| {
13751                        maybe!(async move {
13752                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13753                            while let Some(update) = push_updates.0.next().await {
13754                                let action = lsp_store
13755                                    .update(cx, |this, _| {
13756                                        let Some(local) = this.as_local() else {
13757                                            return ControlFlow::Break(());
13758                                        };
13759                                        let Some(watcher) = local
13760                                            .language_server_watched_paths
13761                                            .get(&language_server_id)
13762                                        else {
13763                                            return ControlFlow::Break(());
13764                                        };
13765                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13766                                            "Watched abs path is not registered with a watcher",
13767                                        );
13768                                        let matching_entries = update
13769                                            .into_iter()
13770                                            .filter(|event| globs.is_match(&event.path))
13771                                            .collect::<Vec<_>>();
13772                                        this.lsp_notify_abs_paths_changed(
13773                                            language_server_id,
13774                                            matching_entries,
13775                                        );
13776                                        ControlFlow::Continue(())
13777                                    })
13778                                    .ok()?;
13779
13780                                if action.is_break() {
13781                                    break;
13782                                }
13783                            }
13784                            Some(())
13785                        })
13786                        .await;
13787                    }
13788                });
13789                (abs_path, (globset, task))
13790            })
13791            .collect();
13792        LanguageServerWatchedPaths {
13793            worktree_paths: self.worktree_paths,
13794            abs_paths,
13795        }
13796    }
13797}
13798
13799struct LspBufferSnapshot {
13800    version: i32,
13801    snapshot: TextBufferSnapshot,
13802}
13803
13804/// A prompt requested by LSP server.
13805#[derive(Clone, Debug)]
13806pub struct LanguageServerPromptRequest {
13807    pub id: usize,
13808    pub level: PromptLevel,
13809    pub message: String,
13810    pub actions: Vec<MessageActionItem>,
13811    pub lsp_name: String,
13812    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13813}
13814
13815impl LanguageServerPromptRequest {
13816    pub fn new(
13817        level: PromptLevel,
13818        message: String,
13819        actions: Vec<MessageActionItem>,
13820        lsp_name: String,
13821        response_channel: smol::channel::Sender<MessageActionItem>,
13822    ) -> Self {
13823        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13824        LanguageServerPromptRequest {
13825            id,
13826            level,
13827            message,
13828            actions,
13829            lsp_name,
13830            response_channel,
13831        }
13832    }
13833    pub async fn respond(self, index: usize) -> Option<()> {
13834        if let Some(response) = self.actions.into_iter().nth(index) {
13835            self.response_channel.send(response).await.ok()
13836        } else {
13837            None
13838        }
13839    }
13840
13841    #[cfg(any(test, feature = "test-support"))]
13842    pub fn test(
13843        level: PromptLevel,
13844        message: String,
13845        actions: Vec<MessageActionItem>,
13846        lsp_name: String,
13847    ) -> Self {
13848        let (tx, _rx) = smol::channel::unbounded();
13849        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13850    }
13851}
13852impl PartialEq for LanguageServerPromptRequest {
13853    fn eq(&self, other: &Self) -> bool {
13854        self.message == other.message && self.actions == other.actions
13855    }
13856}
13857
13858#[derive(Clone, Debug, PartialEq)]
13859pub enum LanguageServerLogType {
13860    Log(MessageType),
13861    Trace { verbose_info: Option<String> },
13862    Rpc { received: bool },
13863}
13864
13865impl LanguageServerLogType {
13866    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13867        match self {
13868            Self::Log(log_type) => {
13869                use proto::log_message::LogLevel;
13870                let level = match *log_type {
13871                    MessageType::ERROR => LogLevel::Error,
13872                    MessageType::WARNING => LogLevel::Warning,
13873                    MessageType::INFO => LogLevel::Info,
13874                    MessageType::LOG => LogLevel::Log,
13875                    other => {
13876                        log::warn!("Unknown lsp log message type: {other:?}");
13877                        LogLevel::Log
13878                    }
13879                };
13880                proto::language_server_log::LogType::Log(proto::LogMessage {
13881                    level: level as i32,
13882                })
13883            }
13884            Self::Trace { verbose_info } => {
13885                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13886                    verbose_info: verbose_info.to_owned(),
13887                })
13888            }
13889            Self::Rpc { received } => {
13890                let kind = if *received {
13891                    proto::rpc_message::Kind::Received
13892                } else {
13893                    proto::rpc_message::Kind::Sent
13894                };
13895                let kind = kind as i32;
13896                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13897            }
13898        }
13899    }
13900
13901    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13902        use proto::log_message::LogLevel;
13903        use proto::rpc_message;
13904        match log_type {
13905            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13906                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13907                    LogLevel::Error => MessageType::ERROR,
13908                    LogLevel::Warning => MessageType::WARNING,
13909                    LogLevel::Info => MessageType::INFO,
13910                    LogLevel::Log => MessageType::LOG,
13911                },
13912            ),
13913            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13914                verbose_info: trace_message.verbose_info,
13915            },
13916            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13917                received: match rpc_message::Kind::from_i32(message.kind)
13918                    .unwrap_or(rpc_message::Kind::Received)
13919                {
13920                    rpc_message::Kind::Received => true,
13921                    rpc_message::Kind::Sent => false,
13922                },
13923            },
13924        }
13925    }
13926}
13927
13928pub struct WorkspaceRefreshTask {
13929    refresh_tx: mpsc::Sender<()>,
13930    progress_tx: mpsc::Sender<()>,
13931    #[allow(dead_code)]
13932    task: Task<()>,
13933}
13934
13935pub enum LanguageServerState {
13936    Starting {
13937        startup: Task<Option<Arc<LanguageServer>>>,
13938        /// List of language servers that will be added to the workspace once it's initialization completes.
13939        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13940    },
13941
13942    Running {
13943        adapter: Arc<CachedLspAdapter>,
13944        server: Arc<LanguageServer>,
13945        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13946        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13947    },
13948}
13949
13950impl LanguageServerState {
13951    fn add_workspace_folder(&self, uri: Uri) {
13952        match self {
13953            LanguageServerState::Starting {
13954                pending_workspace_folders,
13955                ..
13956            } => {
13957                pending_workspace_folders.lock().insert(uri);
13958            }
13959            LanguageServerState::Running { server, .. } => {
13960                server.add_workspace_folder(uri);
13961            }
13962        }
13963    }
13964    fn _remove_workspace_folder(&self, uri: Uri) {
13965        match self {
13966            LanguageServerState::Starting {
13967                pending_workspace_folders,
13968                ..
13969            } => {
13970                pending_workspace_folders.lock().remove(&uri);
13971            }
13972            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13973        }
13974    }
13975}
13976
13977impl std::fmt::Debug for LanguageServerState {
13978    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13979        match self {
13980            LanguageServerState::Starting { .. } => {
13981                f.debug_struct("LanguageServerState::Starting").finish()
13982            }
13983            LanguageServerState::Running { .. } => {
13984                f.debug_struct("LanguageServerState::Running").finish()
13985            }
13986        }
13987    }
13988}
13989
13990#[derive(Clone, Debug, Serialize)]
13991pub struct LanguageServerProgress {
13992    pub is_disk_based_diagnostics_progress: bool,
13993    pub is_cancellable: bool,
13994    pub title: Option<String>,
13995    pub message: Option<String>,
13996    pub percentage: Option<usize>,
13997    #[serde(skip_serializing)]
13998    pub last_update_at: Instant,
13999}
14000
14001#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14002pub struct DiagnosticSummary {
14003    pub error_count: usize,
14004    pub warning_count: usize,
14005}
14006
14007impl DiagnosticSummary {
14008    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14009        let mut this = Self {
14010            error_count: 0,
14011            warning_count: 0,
14012        };
14013
14014        for entry in diagnostics {
14015            if entry.diagnostic.is_primary {
14016                match entry.diagnostic.severity {
14017                    DiagnosticSeverity::ERROR => this.error_count += 1,
14018                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14019                    _ => {}
14020                }
14021            }
14022        }
14023
14024        this
14025    }
14026
14027    pub fn is_empty(&self) -> bool {
14028        self.error_count == 0 && self.warning_count == 0
14029    }
14030
14031    pub fn to_proto(
14032        self,
14033        language_server_id: LanguageServerId,
14034        path: &RelPath,
14035    ) -> proto::DiagnosticSummary {
14036        proto::DiagnosticSummary {
14037            path: path.to_proto(),
14038            language_server_id: language_server_id.0 as u64,
14039            error_count: self.error_count as u32,
14040            warning_count: self.warning_count as u32,
14041        }
14042    }
14043}
14044
14045#[derive(Clone, Debug)]
14046pub enum CompletionDocumentation {
14047    /// There is no documentation for this completion.
14048    Undocumented,
14049    /// A single line of documentation.
14050    SingleLine(SharedString),
14051    /// Multiple lines of plain text documentation.
14052    MultiLinePlainText(SharedString),
14053    /// Markdown documentation.
14054    MultiLineMarkdown(SharedString),
14055    /// Both single line and multiple lines of plain text documentation.
14056    SingleLineAndMultiLinePlainText {
14057        single_line: SharedString,
14058        plain_text: Option<SharedString>,
14059    },
14060}
14061
14062impl CompletionDocumentation {
14063    #[cfg(any(test, feature = "test-support"))]
14064    pub fn text(&self) -> SharedString {
14065        match self {
14066            CompletionDocumentation::Undocumented => "".into(),
14067            CompletionDocumentation::SingleLine(s) => s.clone(),
14068            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14069            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14070            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14071                single_line.clone()
14072            }
14073        }
14074    }
14075}
14076
14077impl From<lsp::Documentation> for CompletionDocumentation {
14078    fn from(docs: lsp::Documentation) -> Self {
14079        match docs {
14080            lsp::Documentation::String(text) => {
14081                if text.lines().count() <= 1 {
14082                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14083                } else {
14084                    CompletionDocumentation::MultiLinePlainText(text.into())
14085                }
14086            }
14087
14088            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14089                lsp::MarkupKind::PlainText => {
14090                    if value.lines().count() <= 1 {
14091                        CompletionDocumentation::SingleLine(value.into())
14092                    } else {
14093                        CompletionDocumentation::MultiLinePlainText(value.into())
14094                    }
14095                }
14096
14097                lsp::MarkupKind::Markdown => {
14098                    CompletionDocumentation::MultiLineMarkdown(value.into())
14099                }
14100            },
14101        }
14102    }
14103}
14104
14105pub enum ResolvedHint {
14106    Resolved(InlayHint),
14107    Resolving(Shared<Task<()>>),
14108}
14109
14110pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14111    glob.components()
14112        .take_while(|component| match component {
14113            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14114            _ => true,
14115        })
14116        .collect()
14117}
14118
14119pub struct SshLspAdapter {
14120    name: LanguageServerName,
14121    binary: LanguageServerBinary,
14122    initialization_options: Option<String>,
14123    code_action_kinds: Option<Vec<CodeActionKind>>,
14124}
14125
14126impl SshLspAdapter {
14127    pub fn new(
14128        name: LanguageServerName,
14129        binary: LanguageServerBinary,
14130        initialization_options: Option<String>,
14131        code_action_kinds: Option<String>,
14132    ) -> Self {
14133        Self {
14134            name,
14135            binary,
14136            initialization_options,
14137            code_action_kinds: code_action_kinds
14138                .as_ref()
14139                .and_then(|c| serde_json::from_str(c).ok()),
14140        }
14141    }
14142}
14143
14144impl LspInstaller for SshLspAdapter {
14145    type BinaryVersion = ();
14146    async fn check_if_user_installed(
14147        &self,
14148        _: &dyn LspAdapterDelegate,
14149        _: Option<Toolchain>,
14150        _: &AsyncApp,
14151    ) -> Option<LanguageServerBinary> {
14152        Some(self.binary.clone())
14153    }
14154
14155    async fn cached_server_binary(
14156        &self,
14157        _: PathBuf,
14158        _: &dyn LspAdapterDelegate,
14159    ) -> Option<LanguageServerBinary> {
14160        None
14161    }
14162
14163    async fn fetch_latest_server_version(
14164        &self,
14165        _: &dyn LspAdapterDelegate,
14166        _: bool,
14167        _: &mut AsyncApp,
14168    ) -> Result<()> {
14169        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14170    }
14171
14172    async fn fetch_server_binary(
14173        &self,
14174        _: (),
14175        _: PathBuf,
14176        _: &dyn LspAdapterDelegate,
14177    ) -> Result<LanguageServerBinary> {
14178        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14179    }
14180}
14181
14182#[async_trait(?Send)]
14183impl LspAdapter for SshLspAdapter {
14184    fn name(&self) -> LanguageServerName {
14185        self.name.clone()
14186    }
14187
14188    async fn initialization_options(
14189        self: Arc<Self>,
14190        _: &Arc<dyn LspAdapterDelegate>,
14191        _: &mut AsyncApp,
14192    ) -> Result<Option<serde_json::Value>> {
14193        let Some(options) = &self.initialization_options else {
14194            return Ok(None);
14195        };
14196        let result = serde_json::from_str(options)?;
14197        Ok(result)
14198    }
14199
14200    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14201        self.code_action_kinds.clone()
14202    }
14203}
14204
14205pub fn language_server_settings<'a>(
14206    delegate: &'a dyn LspAdapterDelegate,
14207    language: &LanguageServerName,
14208    cx: &'a App,
14209) -> Option<&'a LspSettings> {
14210    language_server_settings_for(
14211        SettingsLocation {
14212            worktree_id: delegate.worktree_id(),
14213            path: RelPath::empty(),
14214        },
14215        language,
14216        cx,
14217    )
14218}
14219
14220pub fn language_server_settings_for<'a>(
14221    location: SettingsLocation<'a>,
14222    language: &LanguageServerName,
14223    cx: &'a App,
14224) -> Option<&'a LspSettings> {
14225    ProjectSettings::get(Some(location), cx).lsp.get(language)
14226}
14227
14228pub struct LocalLspAdapterDelegate {
14229    lsp_store: WeakEntity<LspStore>,
14230    worktree: worktree::Snapshot,
14231    fs: Arc<dyn Fs>,
14232    http_client: Arc<dyn HttpClient>,
14233    language_registry: Arc<LanguageRegistry>,
14234    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14235}
14236
14237impl LocalLspAdapterDelegate {
14238    pub fn new(
14239        language_registry: Arc<LanguageRegistry>,
14240        environment: &Entity<ProjectEnvironment>,
14241        lsp_store: WeakEntity<LspStore>,
14242        worktree: &Entity<Worktree>,
14243        http_client: Arc<dyn HttpClient>,
14244        fs: Arc<dyn Fs>,
14245        cx: &mut App,
14246    ) -> Arc<Self> {
14247        let load_shell_env_task =
14248            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14249
14250        Arc::new(Self {
14251            lsp_store,
14252            worktree: worktree.read(cx).snapshot(),
14253            fs,
14254            http_client,
14255            language_registry,
14256            load_shell_env_task,
14257        })
14258    }
14259
14260    pub fn from_local_lsp(
14261        local: &LocalLspStore,
14262        worktree: &Entity<Worktree>,
14263        cx: &mut App,
14264    ) -> Arc<Self> {
14265        Self::new(
14266            local.languages.clone(),
14267            &local.environment,
14268            local.weak.clone(),
14269            worktree,
14270            local.http_client.clone(),
14271            local.fs.clone(),
14272            cx,
14273        )
14274    }
14275}
14276
14277#[async_trait]
14278impl LspAdapterDelegate for LocalLspAdapterDelegate {
14279    fn show_notification(&self, message: &str, cx: &mut App) {
14280        self.lsp_store
14281            .update(cx, |_, cx| {
14282                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14283            })
14284            .ok();
14285    }
14286
14287    fn http_client(&self) -> Arc<dyn HttpClient> {
14288        self.http_client.clone()
14289    }
14290
14291    fn worktree_id(&self) -> WorktreeId {
14292        self.worktree.id()
14293    }
14294
14295    fn worktree_root_path(&self) -> &Path {
14296        self.worktree.abs_path().as_ref()
14297    }
14298
14299    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14300        self.worktree.resolve_relative_path(path)
14301    }
14302
14303    async fn shell_env(&self) -> HashMap<String, String> {
14304        let task = self.load_shell_env_task.clone();
14305        task.await.unwrap_or_default()
14306    }
14307
14308    async fn npm_package_installed_version(
14309        &self,
14310        package_name: &str,
14311    ) -> Result<Option<(PathBuf, Version)>> {
14312        let local_package_directory = self.worktree_root_path();
14313        let node_modules_directory = local_package_directory.join("node_modules");
14314
14315        if let Some(version) =
14316            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14317        {
14318            return Ok(Some((node_modules_directory, version)));
14319        }
14320        let Some(npm) = self.which("npm".as_ref()).await else {
14321            log::warn!(
14322                "Failed to find npm executable for {:?}",
14323                local_package_directory
14324            );
14325            return Ok(None);
14326        };
14327
14328        let env = self.shell_env().await;
14329        let output = util::command::new_command(&npm)
14330            .args(["root", "-g"])
14331            .envs(env)
14332            .current_dir(local_package_directory)
14333            .output()
14334            .await?;
14335        let global_node_modules =
14336            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14337
14338        if let Some(version) =
14339            read_package_installed_version(global_node_modules.clone(), package_name).await?
14340        {
14341            return Ok(Some((global_node_modules, version)));
14342        }
14343        return Ok(None);
14344    }
14345
14346    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14347        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14348        if self.fs.is_file(&worktree_abs_path).await {
14349            worktree_abs_path.pop();
14350        }
14351
14352        let env = self.shell_env().await;
14353
14354        let shell_path = env.get("PATH").cloned();
14355
14356        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14357    }
14358
14359    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14360        let mut working_dir = self.worktree_root_path().to_path_buf();
14361        if self.fs.is_file(&working_dir).await {
14362            working_dir.pop();
14363        }
14364        let output = util::command::new_command(&command.path)
14365            .args(command.arguments)
14366            .envs(command.env.clone().unwrap_or_default())
14367            .current_dir(working_dir)
14368            .output()
14369            .await?;
14370
14371        anyhow::ensure!(
14372            output.status.success(),
14373            "{}, stdout: {:?}, stderr: {:?}",
14374            output.status,
14375            String::from_utf8_lossy(&output.stdout),
14376            String::from_utf8_lossy(&output.stderr)
14377        );
14378        Ok(())
14379    }
14380
14381    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14382        self.language_registry
14383            .update_lsp_binary_status(server_name, status);
14384    }
14385
14386    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14387        self.language_registry
14388            .all_lsp_adapters()
14389            .into_iter()
14390            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14391            .collect()
14392    }
14393
14394    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14395        let dir = self.language_registry.language_server_download_dir(name)?;
14396
14397        if !dir.exists() {
14398            smol::fs::create_dir_all(&dir)
14399                .await
14400                .context("failed to create container directory")
14401                .log_err()?;
14402        }
14403
14404        Some(dir)
14405    }
14406
14407    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14408        let entry = self
14409            .worktree
14410            .entry_for_path(path)
14411            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14412        let abs_path = self.worktree.absolutize(&entry.path);
14413        self.fs.load(&abs_path).await
14414    }
14415}
14416
14417async fn populate_labels_for_symbols(
14418    symbols: Vec<CoreSymbol>,
14419    language_registry: &Arc<LanguageRegistry>,
14420    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14421    output: &mut Vec<Symbol>,
14422) {
14423    #[allow(clippy::mutable_key_type)]
14424    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14425
14426    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14427    for symbol in symbols {
14428        let Some(file_name) = symbol.path.file_name() else {
14429            continue;
14430        };
14431        let language = language_registry
14432            .load_language_for_file_path(Path::new(file_name))
14433            .await
14434            .ok()
14435            .or_else(|| {
14436                unknown_paths.insert(file_name.into());
14437                None
14438            });
14439        symbols_by_language
14440            .entry(language)
14441            .or_default()
14442            .push(symbol);
14443    }
14444
14445    for unknown_path in unknown_paths {
14446        log::info!("no language found for symbol in file {unknown_path:?}");
14447    }
14448
14449    let mut label_params = Vec::new();
14450    for (language, mut symbols) in symbols_by_language {
14451        label_params.clear();
14452        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14453            name: mem::take(&mut symbol.name),
14454            kind: symbol.kind,
14455            container_name: symbol.container_name.take(),
14456        }));
14457
14458        let mut labels = Vec::new();
14459        if let Some(language) = language {
14460            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14461                language_registry
14462                    .lsp_adapters(&language.name())
14463                    .first()
14464                    .cloned()
14465            });
14466            if let Some(lsp_adapter) = lsp_adapter {
14467                labels = lsp_adapter
14468                    .labels_for_symbols(&label_params, &language)
14469                    .await
14470                    .log_err()
14471                    .unwrap_or_default();
14472            }
14473        }
14474
14475        for (
14476            (
14477                symbol,
14478                language::Symbol {
14479                    name,
14480                    container_name,
14481                    ..
14482                },
14483            ),
14484            label,
14485        ) in symbols
14486            .into_iter()
14487            .zip(label_params.drain(..))
14488            .zip(labels.into_iter().chain(iter::repeat(None)))
14489        {
14490            output.push(Symbol {
14491                language_server_name: symbol.language_server_name,
14492                source_worktree_id: symbol.source_worktree_id,
14493                source_language_server_id: symbol.source_language_server_id,
14494                path: symbol.path,
14495                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14496                name,
14497                kind: symbol.kind,
14498                range: symbol.range,
14499                container_name,
14500            });
14501        }
14502    }
14503}
14504
14505pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14506    text.lines()
14507        .map(|line| line.trim())
14508        .filter(|line| !line.is_empty())
14509        .join(separator)
14510}
14511
14512fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14513    match server.capabilities().text_document_sync.as_ref()? {
14514        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14515            // Server wants didSave but didn't specify includeText.
14516            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14517            // Server doesn't want didSave at all.
14518            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14519            // Server provided SaveOptions.
14520            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14521                Some(save_options.include_text.unwrap_or(false))
14522            }
14523        },
14524        // We do not have any save info. Kind affects didChange only.
14525        lsp::TextDocumentSyncCapability::Kind(_) => None,
14526    }
14527}
14528
14529/// Completion items are displayed in a `UniformList`.
14530/// Usually, those items are single-line strings, but in LSP responses,
14531/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14532/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14533/// 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,
14534/// breaking the completions menu presentation.
14535///
14536/// 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.
14537pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14538    let mut new_text = String::with_capacity(label.text.len());
14539    let mut offset_map = vec![0; label.text.len() + 1];
14540    let mut last_char_was_space = false;
14541    let mut new_idx = 0;
14542    let chars = label.text.char_indices().fuse();
14543    let mut newlines_removed = false;
14544
14545    for (idx, c) in chars {
14546        offset_map[idx] = new_idx;
14547
14548        match c {
14549            '\n' if last_char_was_space => {
14550                newlines_removed = true;
14551            }
14552            '\t' | ' ' if last_char_was_space => {}
14553            '\n' if !last_char_was_space => {
14554                new_text.push(' ');
14555                new_idx += 1;
14556                last_char_was_space = true;
14557                newlines_removed = true;
14558            }
14559            ' ' | '\t' => {
14560                new_text.push(' ');
14561                new_idx += 1;
14562                last_char_was_space = true;
14563            }
14564            _ => {
14565                new_text.push(c);
14566                new_idx += c.len_utf8();
14567                last_char_was_space = false;
14568            }
14569        }
14570    }
14571    offset_map[label.text.len()] = new_idx;
14572
14573    // Only modify the label if newlines were removed.
14574    if !newlines_removed {
14575        return;
14576    }
14577
14578    let last_index = new_idx;
14579    let mut run_ranges_errors = Vec::new();
14580    label.runs.retain_mut(|(range, _)| {
14581        match offset_map.get(range.start) {
14582            Some(&start) => range.start = start,
14583            None => {
14584                run_ranges_errors.push(range.clone());
14585                return false;
14586            }
14587        }
14588
14589        match offset_map.get(range.end) {
14590            Some(&end) => range.end = end,
14591            None => {
14592                run_ranges_errors.push(range.clone());
14593                range.end = last_index;
14594            }
14595        }
14596        true
14597    });
14598    if !run_ranges_errors.is_empty() {
14599        log::error!(
14600            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14601            label.text
14602        );
14603    }
14604
14605    let mut wrong_filter_range = None;
14606    if label.filter_range == (0..label.text.len()) {
14607        label.filter_range = 0..new_text.len();
14608    } else {
14609        let mut original_filter_range = Some(label.filter_range.clone());
14610        match offset_map.get(label.filter_range.start) {
14611            Some(&start) => label.filter_range.start = start,
14612            None => {
14613                wrong_filter_range = original_filter_range.take();
14614                label.filter_range.start = last_index;
14615            }
14616        }
14617
14618        match offset_map.get(label.filter_range.end) {
14619            Some(&end) => label.filter_range.end = end,
14620            None => {
14621                wrong_filter_range = original_filter_range.take();
14622                label.filter_range.end = last_index;
14623            }
14624        }
14625    }
14626    if let Some(wrong_filter_range) = wrong_filter_range {
14627        log::error!(
14628            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14629            label.text
14630        );
14631    }
14632
14633    label.text = new_text;
14634}
14635
14636/// Apply edits to the buffer that will become part of the formatting transaction.
14637/// Fails if the buffer has been edited since the start of that transaction.
14638fn extend_formatting_transaction(
14639    buffer: &FormattableBuffer,
14640    formatting_transaction_id: text::TransactionId,
14641    cx: &mut AsyncApp,
14642    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14643) -> anyhow::Result<()> {
14644    buffer.handle.update(cx, |buffer, cx| {
14645        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14646        if last_transaction_id != Some(formatting_transaction_id) {
14647            anyhow::bail!("Buffer edited while formatting. Aborting")
14648        }
14649        buffer.start_transaction();
14650        operation(buffer, cx);
14651        if let Some(transaction_id) = buffer.end_transaction(cx) {
14652            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14653        }
14654        Ok(())
14655    })
14656}