lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, all_language_settings,
   81    },
   82    modeline, point_to_lsp,
   83    proto::{
   84        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   85        serialize_anchor_range, serialize_version,
   86    },
   87    range_from_lsp, range_to_lsp,
   88    row_chunk::RowChunk,
   89};
   90use lsp::{
   91    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   92    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   93    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   94    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   95    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   96    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   97    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   98    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   99};
  100use node_runtime::read_package_installed_version;
  101use parking_lot::Mutex;
  102use postage::{mpsc, sink::Sink, stream::Stream, watch};
  103use rand::prelude::*;
  104use rpc::{
  105    AnyProtoClient, ErrorCode, ErrorExt as _,
  106    proto::{LspRequestId, LspRequestMessage as _},
  107};
  108use semver::Version;
  109use serde::Serialize;
  110use serde_json::Value;
  111use settings::{Settings, SettingsLocation, SettingsStore};
  112use sha2::{Digest, Sha256};
  113use snippet::Snippet;
  114use std::{
  115    any::TypeId,
  116    borrow::Cow,
  117    cell::RefCell,
  118    cmp::{Ordering, Reverse},
  119    collections::{VecDeque, hash_map},
  120    convert::TryInto,
  121    ffi::OsStr,
  122    future::ready,
  123    iter, mem,
  124    ops::{ControlFlow, Range},
  125    path::{self, Path, PathBuf},
  126    pin::pin,
  127    rc::Rc,
  128    sync::{
  129        Arc,
  130        atomic::{self, AtomicUsize},
  131    },
  132    time::{Duration, Instant},
  133    vec,
  134};
  135use sum_tree::Dimensions;
  136use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  137
  138use util::{
  139    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  140    paths::{PathStyle, SanitizedPath, UrlExt},
  141    post_inc,
  142    redact::redact_command,
  143    rel_path::RelPath,
  144};
  145
  146pub use document_colors::DocumentColors;
  147pub use folding_ranges::LspFoldingRange;
  148pub use fs::*;
  149pub use language::Location;
  150pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  151#[cfg(any(test, feature = "test-support"))]
  152pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  153#[cfg(any(test, feature = "test-support"))]
  154pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  155pub use semantic_tokens::{
  156    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  157};
  158
  159pub use worktree::{
  160    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  161    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  162};
  163
  164const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  165pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  166const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  167const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  168static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  169
  170#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  171pub enum ProgressToken {
  172    Number(i32),
  173    String(SharedString),
  174}
  175
  176impl std::fmt::Display for ProgressToken {
  177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  178        match self {
  179            Self::Number(number) => write!(f, "{number}"),
  180            Self::String(string) => write!(f, "{string}"),
  181        }
  182    }
  183}
  184
  185impl ProgressToken {
  186    fn from_lsp(value: lsp::NumberOrString) -> Self {
  187        match value {
  188            lsp::NumberOrString::Number(number) => Self::Number(number),
  189            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  190        }
  191    }
  192
  193    fn to_lsp(&self) -> lsp::NumberOrString {
  194        match self {
  195            Self::Number(number) => lsp::NumberOrString::Number(*number),
  196            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  197        }
  198    }
  199
  200    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  201        Some(match value.value? {
  202            proto::progress_token::Value::Number(number) => Self::Number(number),
  203            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  204        })
  205    }
  206
  207    fn to_proto(&self) -> proto::ProgressToken {
  208        proto::ProgressToken {
  209            value: Some(match self {
  210                Self::Number(number) => proto::progress_token::Value::Number(*number),
  211                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  212            }),
  213        }
  214    }
  215}
  216
  217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  218pub enum FormatTrigger {
  219    Save,
  220    Manual,
  221}
  222
  223pub enum LspFormatTarget {
  224    Buffers,
  225    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  226}
  227
  228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  229pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  230
  231struct OpenLspBuffer(Entity<Buffer>);
  232
  233impl FormatTrigger {
  234    fn from_proto(value: i32) -> FormatTrigger {
  235        match value {
  236            0 => FormatTrigger::Save,
  237            1 => FormatTrigger::Manual,
  238            _ => FormatTrigger::Save,
  239        }
  240    }
  241}
  242
  243#[derive(Clone)]
  244struct UnifiedLanguageServer {
  245    id: LanguageServerId,
  246    project_roots: HashSet<Arc<RelPath>>,
  247}
  248
  249/// Settings that affect language server identity.
  250///
  251/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  252/// updated via `workspace/didChangeConfiguration` without restarting the server.
  253#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  254struct LanguageServerSeedSettings {
  255    binary: Option<BinarySettings>,
  256    initialization_options: Option<serde_json::Value>,
  257}
  258
  259#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  260struct LanguageServerSeed {
  261    worktree_id: WorktreeId,
  262    name: LanguageServerName,
  263    toolchain: Option<Toolchain>,
  264    settings: LanguageServerSeedSettings,
  265}
  266
  267#[derive(Debug)]
  268pub struct DocumentDiagnosticsUpdate<'a, D> {
  269    pub diagnostics: D,
  270    pub result_id: Option<SharedString>,
  271    pub registration_id: Option<SharedString>,
  272    pub server_id: LanguageServerId,
  273    pub disk_based_sources: Cow<'a, [String]>,
  274}
  275
  276pub struct DocumentDiagnostics {
  277    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  278    document_abs_path: PathBuf,
  279    version: Option<i32>,
  280}
  281
  282#[derive(Default, Debug)]
  283struct DynamicRegistrations {
  284    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  285    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  286}
  287
  288pub struct LocalLspStore {
  289    weak: WeakEntity<LspStore>,
  290    pub worktree_store: Entity<WorktreeStore>,
  291    toolchain_store: Entity<LocalToolchainStore>,
  292    http_client: Arc<dyn HttpClient>,
  293    environment: Entity<ProjectEnvironment>,
  294    fs: Arc<dyn Fs>,
  295    languages: Arc<LanguageRegistry>,
  296    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  297    yarn: Entity<YarnPathStore>,
  298    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  299    buffers_being_formatted: HashSet<BufferId>,
  300    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  301    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  302    watched_manifest_filenames: HashSet<ManifestName>,
  303    language_server_paths_watched_for_rename:
  304        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  305    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  306    supplementary_language_servers:
  307        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  308    prettier_store: Entity<PrettierStore>,
  309    next_diagnostic_group_id: usize,
  310    diagnostics: HashMap<
  311        WorktreeId,
  312        HashMap<
  313            Arc<RelPath>,
  314            Vec<(
  315                LanguageServerId,
  316                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  317            )>,
  318        >,
  319    >,
  320    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  321    _subscription: gpui::Subscription,
  322    lsp_tree: LanguageServerTree,
  323    registered_buffers: HashMap<BufferId, usize>,
  324    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  325    buffer_pull_diagnostics_result_ids: HashMap<
  326        LanguageServerId,
  327        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  328    >,
  329    workspace_pull_diagnostics_result_ids: HashMap<
  330        LanguageServerId,
  331        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  332    >,
  333    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  334    all_language_servers_stopped: bool,
  335    stopped_language_servers: HashSet<LanguageServerName>,
  336
  337    buffers_to_refresh_hash_set: HashSet<BufferId>,
  338    buffers_to_refresh_queue: VecDeque<BufferId>,
  339    _background_diagnostics_worker: Shared<Task<()>>,
  340}
  341
  342impl LocalLspStore {
  343    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  344    pub fn running_language_server_for_id(
  345        &self,
  346        id: LanguageServerId,
  347    ) -> Option<&Arc<LanguageServer>> {
  348        let language_server_state = self.language_servers.get(&id)?;
  349
  350        match language_server_state {
  351            LanguageServerState::Running { server, .. } => Some(server),
  352            LanguageServerState::Starting { .. } => None,
  353        }
  354    }
  355
  356    fn get_or_insert_language_server(
  357        &mut self,
  358        worktree_handle: &Entity<Worktree>,
  359        delegate: Arc<LocalLspAdapterDelegate>,
  360        disposition: &Arc<LaunchDisposition>,
  361        language_name: &LanguageName,
  362        cx: &mut App,
  363    ) -> LanguageServerId {
  364        let key = LanguageServerSeed {
  365            worktree_id: worktree_handle.read(cx).id(),
  366            name: disposition.server_name.clone(),
  367            settings: LanguageServerSeedSettings {
  368                binary: disposition.settings.binary.clone(),
  369                initialization_options: disposition.settings.initialization_options.clone(),
  370            },
  371            toolchain: disposition.toolchain.clone(),
  372        };
  373        if let Some(state) = self.language_server_ids.get_mut(&key) {
  374            state.project_roots.insert(disposition.path.path.clone());
  375            state.id
  376        } else {
  377            let adapter = self
  378                .languages
  379                .lsp_adapters(language_name)
  380                .into_iter()
  381                .find(|adapter| adapter.name() == disposition.server_name)
  382                .expect("To find LSP adapter");
  383            let new_language_server_id = self.start_language_server(
  384                worktree_handle,
  385                delegate,
  386                adapter,
  387                disposition.settings.clone(),
  388                key.clone(),
  389                language_name.clone(),
  390                cx,
  391            );
  392            if let Some(state) = self.language_server_ids.get_mut(&key) {
  393                state.project_roots.insert(disposition.path.path.clone());
  394            } else {
  395                debug_assert!(
  396                    false,
  397                    "Expected `start_language_server` to ensure that `key` exists in a map"
  398                );
  399            }
  400            new_language_server_id
  401        }
  402    }
  403
  404    fn start_language_server(
  405        &mut self,
  406        worktree_handle: &Entity<Worktree>,
  407        delegate: Arc<LocalLspAdapterDelegate>,
  408        adapter: Arc<CachedLspAdapter>,
  409        settings: Arc<LspSettings>,
  410        key: LanguageServerSeed,
  411        language_name: LanguageName,
  412        cx: &mut App,
  413    ) -> LanguageServerId {
  414        let worktree = worktree_handle.read(cx);
  415
  416        let worktree_id = worktree.id();
  417        let worktree_abs_path = worktree.abs_path();
  418        let toolchain = key.toolchain.clone();
  419        let override_options = settings.initialization_options.clone();
  420
  421        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  422
  423        let server_id = self.languages.next_language_server_id();
  424        log::trace!(
  425            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  426            adapter.name.0
  427        );
  428
  429        let wait_until_worktree_trust =
  430            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  431                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  432                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  433                });
  434                if can_trust {
  435                    self.restricted_worktrees_tasks.remove(&worktree_id);
  436                    None
  437                } else {
  438                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  439                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  440                        hash_map::Entry::Vacant(v) => {
  441                            let (mut tx, rx) = watch::channel::<bool>();
  442                            let lsp_store = self.weak.clone();
  443                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  444                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  445                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  446                                        tx.blocking_send(true).ok();
  447                                        lsp_store
  448                                            .update(cx, |lsp_store, _| {
  449                                                if let Some(local_lsp_store) =
  450                                                    lsp_store.as_local_mut()
  451                                                {
  452                                                    local_lsp_store
  453                                                        .restricted_worktrees_tasks
  454                                                        .remove(&worktree_id);
  455                                                }
  456                                            })
  457                                            .ok();
  458                                    }
  459                                }
  460                            });
  461                            v.insert((subscription, rx.clone()));
  462                            Some(rx)
  463                        }
  464                    }
  465                }
  466            });
  467        let update_binary_status = wait_until_worktree_trust.is_none();
  468
  469        let binary = self.get_language_server_binary(
  470            worktree_abs_path.clone(),
  471            adapter.clone(),
  472            settings,
  473            toolchain.clone(),
  474            delegate.clone(),
  475            true,
  476            wait_until_worktree_trust,
  477            cx,
  478        );
  479        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  480
  481        let pending_server = cx.spawn({
  482            let adapter = adapter.clone();
  483            let server_name = adapter.name.clone();
  484            let stderr_capture = stderr_capture.clone();
  485            #[cfg(any(test, feature = "test-support"))]
  486            let lsp_store = self.weak.clone();
  487            let pending_workspace_folders = pending_workspace_folders.clone();
  488            async move |cx| {
  489                let binary = binary.await?;
  490                #[cfg(any(test, feature = "test-support"))]
  491                if let Some(server) = lsp_store
  492                    .update(&mut cx.clone(), |this, cx| {
  493                        this.languages.create_fake_language_server(
  494                            server_id,
  495                            &server_name,
  496                            binary.clone(),
  497                            &mut cx.to_async(),
  498                        )
  499                    })
  500                    .ok()
  501                    .flatten()
  502                {
  503                    return Ok(server);
  504                }
  505
  506                let code_action_kinds = adapter.code_action_kinds();
  507                lsp::LanguageServer::new(
  508                    stderr_capture,
  509                    server_id,
  510                    server_name,
  511                    binary,
  512                    &worktree_abs_path,
  513                    code_action_kinds,
  514                    Some(pending_workspace_folders),
  515                    cx,
  516                )
  517            }
  518        });
  519
  520        let startup = {
  521            let server_name = adapter.name.0.clone();
  522            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  523            let key = key.clone();
  524            let adapter = adapter.clone();
  525            let lsp_store = self.weak.clone();
  526            let pending_workspace_folders = pending_workspace_folders.clone();
  527            let pull_diagnostics = ProjectSettings::get_global(cx)
  528                .diagnostics
  529                .lsp_pull_diagnostics
  530                .enabled;
  531            let settings_location = SettingsLocation {
  532                worktree_id,
  533                path: RelPath::empty(),
  534            };
  535            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  536                .language(Some(settings_location), Some(&language_name), cx)
  537                .semantic_tokens
  538                .use_tree_sitter();
  539            cx.spawn(async move |cx| {
  540                let result = async {
  541                    let language_server = pending_server.await?;
  542
  543                    let workspace_config = Self::workspace_configuration_for_adapter(
  544                        adapter.adapter.clone(),
  545                        &delegate,
  546                        toolchain,
  547                        None,
  548                        cx,
  549                    )
  550                    .await?;
  551
  552                    let mut initialization_options = Self::initialization_options_for_adapter(
  553                        adapter.adapter.clone(),
  554                        &delegate,
  555                        cx,
  556                    )
  557                    .await?;
  558
  559                    match (&mut initialization_options, override_options) {
  560                        (Some(initialization_options), Some(override_options)) => {
  561                            merge_json_value_into(override_options, initialization_options);
  562                        }
  563                        (None, override_options) => initialization_options = override_options,
  564                        _ => {}
  565                    }
  566
  567                    let initialization_params = cx.update(|cx| {
  568                        let mut params = language_server.default_initialize_params(
  569                            pull_diagnostics,
  570                            augments_syntax_tokens,
  571                            cx,
  572                        );
  573                        params.initialization_options = initialization_options;
  574                        adapter.adapter.prepare_initialize_params(params, cx)
  575                    })?;
  576
  577                    Self::setup_lsp_messages(
  578                        lsp_store.clone(),
  579                        &language_server,
  580                        delegate.clone(),
  581                        adapter.clone(),
  582                    );
  583
  584                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  585                        settings: workspace_config,
  586                    };
  587                    let language_server = cx
  588                        .update(|cx| {
  589                            let request_timeout = ProjectSettings::get_global(cx)
  590                                .global_lsp_settings
  591                                .get_request_timeout();
  592
  593                            language_server.initialize(
  594                                initialization_params,
  595                                Arc::new(did_change_configuration_params.clone()),
  596                                request_timeout,
  597                                cx,
  598                            )
  599                        })
  600                        .await
  601                        .inspect_err(|_| {
  602                            if let Some(lsp_store) = lsp_store.upgrade() {
  603                                lsp_store.update(cx, |lsp_store, cx| {
  604                                    lsp_store.cleanup_lsp_data(server_id);
  605                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  606                                });
  607                            }
  608                        })?;
  609
  610                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  611                        did_change_configuration_params,
  612                    )?;
  613
  614                    anyhow::Ok(language_server)
  615                }
  616                .await;
  617
  618                match result {
  619                    Ok(server) => {
  620                        lsp_store
  621                            .update(cx, |lsp_store, cx| {
  622                                lsp_store.insert_newly_running_language_server(
  623                                    adapter,
  624                                    server.clone(),
  625                                    server_id,
  626                                    key,
  627                                    pending_workspace_folders,
  628                                    cx,
  629                                );
  630                            })
  631                            .ok();
  632                        stderr_capture.lock().take();
  633                        Some(server)
  634                    }
  635
  636                    Err(err) => {
  637                        let log = stderr_capture.lock().take().unwrap_or_default();
  638                        delegate.update_status(
  639                            adapter.name(),
  640                            BinaryStatus::Failed {
  641                                error: if log.is_empty() {
  642                                    format!("{err:#}")
  643                                } else {
  644                                    format!("{err:#}\n-- stderr --\n{log}")
  645                                },
  646                            },
  647                        );
  648                        log::error!(
  649                            "Failed to start language server {server_name:?}: {}",
  650                            redact_command(&format!("{err:?}"))
  651                        );
  652                        if !log.is_empty() {
  653                            log::error!("server stderr: {}", redact_command(&log));
  654                        }
  655                        None
  656                    }
  657                }
  658            })
  659        };
  660        let state = LanguageServerState::Starting {
  661            startup,
  662            pending_workspace_folders,
  663        };
  664
  665        if update_binary_status {
  666            self.languages
  667                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  668        }
  669
  670        self.language_servers.insert(server_id, state);
  671        self.language_server_ids
  672            .entry(key)
  673            .or_insert(UnifiedLanguageServer {
  674                id: server_id,
  675                project_roots: Default::default(),
  676            });
  677        server_id
  678    }
  679
  680    fn get_language_server_binary(
  681        &self,
  682        worktree_abs_path: Arc<Path>,
  683        adapter: Arc<CachedLspAdapter>,
  684        settings: Arc<LspSettings>,
  685        toolchain: Option<Toolchain>,
  686        delegate: Arc<dyn LspAdapterDelegate>,
  687        allow_binary_download: bool,
  688        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  689        cx: &mut App,
  690    ) -> Task<Result<LanguageServerBinary>> {
  691        if let Some(settings) = &settings.binary
  692            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  693        {
  694            let settings = settings.clone();
  695            let languages = self.languages.clone();
  696            return cx.background_spawn(async move {
  697                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  698                    let already_trusted =  *wait_until_worktree_trust.borrow();
  699                    if !already_trusted {
  700                        log::info!(
  701                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  702                            adapter.name(),
  703                        );
  704                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  705                            if worktree_trusted {
  706                                break;
  707                            }
  708                        }
  709                        log::info!(
  710                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  711                            adapter.name(),
  712                        );
  713                    }
  714                    languages
  715                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  716                }
  717                let mut env = delegate.shell_env().await;
  718                env.extend(settings.env.unwrap_or_default());
  719
  720                Ok(LanguageServerBinary {
  721                    path: delegate.resolve_relative_path(path),
  722                    env: Some(env),
  723                    arguments: settings
  724                        .arguments
  725                        .unwrap_or_default()
  726                        .iter()
  727                        .map(Into::into)
  728                        .collect(),
  729                })
  730            });
  731        }
  732        let lsp_binary_options = LanguageServerBinaryOptions {
  733            allow_path_lookup: !settings
  734                .binary
  735                .as_ref()
  736                .and_then(|b| b.ignore_system_version)
  737                .unwrap_or_default(),
  738            allow_binary_download,
  739            pre_release: settings
  740                .fetch
  741                .as_ref()
  742                .and_then(|f| f.pre_release)
  743                .unwrap_or(false),
  744        };
  745
  746        cx.spawn(async move |cx| {
  747            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  748                let already_trusted =  *wait_until_worktree_trust.borrow();
  749                if !already_trusted {
  750                    log::info!(
  751                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  752                        adapter.name(),
  753                    );
  754                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  755                        if worktree_trusted {
  756                            break;
  757                        }
  758                    }
  759                    log::info!(
  760                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  761                            adapter.name(),
  762                    );
  763                }
  764            }
  765
  766            let (existing_binary, maybe_download_binary) = adapter
  767                .clone()
  768                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  769                .await
  770                .await;
  771
  772            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  773
  774            let mut binary = match (existing_binary, maybe_download_binary) {
  775                (binary, None) => binary?,
  776                (Err(_), Some(downloader)) => downloader.await?,
  777                (Ok(existing_binary), Some(downloader)) => {
  778                    let mut download_timeout = cx
  779                        .background_executor()
  780                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  781                        .fuse();
  782                    let mut downloader = downloader.fuse();
  783                    futures::select! {
  784                        _ = download_timeout => {
  785                            // Return existing binary and kick the existing work to the background.
  786                            cx.spawn(async move |_| downloader.await).detach();
  787                            Ok(existing_binary)
  788                        },
  789                        downloaded_or_existing_binary = downloader => {
  790                            // If download fails, this results in the existing binary.
  791                            downloaded_or_existing_binary
  792                        }
  793                    }?
  794                }
  795            };
  796            let mut shell_env = delegate.shell_env().await;
  797
  798            shell_env.extend(binary.env.unwrap_or_default());
  799
  800            if let Some(settings) = settings.binary.as_ref() {
  801                if let Some(arguments) = &settings.arguments {
  802                    binary.arguments = arguments.iter().map(Into::into).collect();
  803                }
  804                if let Some(env) = &settings.env {
  805                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  806                }
  807            }
  808
  809            binary.env = Some(shell_env);
  810            Ok(binary)
  811        })
  812    }
  813
  814    fn setup_lsp_messages(
  815        lsp_store: WeakEntity<LspStore>,
  816        language_server: &LanguageServer,
  817        delegate: Arc<dyn LspAdapterDelegate>,
  818        adapter: Arc<CachedLspAdapter>,
  819    ) {
  820        let name = language_server.name();
  821        let server_id = language_server.server_id();
  822        language_server
  823            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  824                let adapter = adapter.clone();
  825                let this = lsp_store.clone();
  826                move |mut params, cx| {
  827                    let adapter = adapter.clone();
  828                    if let Some(this) = this.upgrade() {
  829                        this.update(cx, |this, cx| {
  830                            adapter.process_diagnostics(&mut params, server_id);
  831
  832                            this.merge_lsp_diagnostics(
  833                                DiagnosticSourceKind::Pushed,
  834                                vec![DocumentDiagnosticsUpdate {
  835                                    server_id,
  836                                    diagnostics: params,
  837                                    result_id: None,
  838                                    disk_based_sources: Cow::Borrowed(
  839                                        &adapter.disk_based_diagnostic_sources,
  840                                    ),
  841                                    registration_id: None,
  842                                }],
  843                                |_, diagnostic, _cx| match diagnostic.source_kind {
  844                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  845                                        adapter.retain_old_diagnostic(diagnostic)
  846                                    }
  847                                    DiagnosticSourceKind::Pulled => true,
  848                                },
  849                                cx,
  850                            )
  851                            .log_err();
  852                        });
  853                    }
  854                }
  855            })
  856            .detach();
  857        language_server
  858            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  859                let adapter = adapter.adapter.clone();
  860                let delegate = delegate.clone();
  861                let this = lsp_store.clone();
  862                move |params, cx| {
  863                    let adapter = adapter.clone();
  864                    let delegate = delegate.clone();
  865                    let this = this.clone();
  866                    let mut cx = cx.clone();
  867                    async move {
  868                        let toolchain_for_id = this
  869                            .update(&mut cx, |this, _| {
  870                                this.as_local()?.language_server_ids.iter().find_map(
  871                                    |(seed, value)| {
  872                                        (value.id == server_id).then(|| seed.toolchain.clone())
  873                                    },
  874                                )
  875                            })?
  876                            .context("Expected the LSP store to be in a local mode")?;
  877
  878                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  879                        for item in &params.items {
  880                            let scope_uri = item.scope_uri.clone();
  881                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  882                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  883                            else {
  884                                // We've already queried workspace configuration of this URI.
  885                                continue;
  886                            };
  887                            let workspace_config = Self::workspace_configuration_for_adapter(
  888                                adapter.clone(),
  889                                &delegate,
  890                                toolchain_for_id.clone(),
  891                                scope_uri,
  892                                &mut cx,
  893                            )
  894                            .await?;
  895                            new_scope_uri.insert(workspace_config);
  896                        }
  897
  898                        Ok(params
  899                            .items
  900                            .into_iter()
  901                            .filter_map(|item| {
  902                                let workspace_config =
  903                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  904                                if let Some(section) = &item.section {
  905                                    Some(
  906                                        workspace_config
  907                                            .get(section)
  908                                            .cloned()
  909                                            .unwrap_or(serde_json::Value::Null),
  910                                    )
  911                                } else {
  912                                    Some(workspace_config.clone())
  913                                }
  914                            })
  915                            .collect())
  916                    }
  917                }
  918            })
  919            .detach();
  920
  921        language_server
  922            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  923                let this = lsp_store.clone();
  924                move |_, cx| {
  925                    let this = this.clone();
  926                    let cx = cx.clone();
  927                    async move {
  928                        let Some(server) =
  929                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  930                        else {
  931                            return Ok(None);
  932                        };
  933                        let root = server.workspace_folders();
  934                        Ok(Some(
  935                            root.into_iter()
  936                                .map(|uri| WorkspaceFolder {
  937                                    uri,
  938                                    name: Default::default(),
  939                                })
  940                                .collect(),
  941                        ))
  942                    }
  943                }
  944            })
  945            .detach();
  946        // Even though we don't have handling for these requests, respond to them to
  947        // avoid stalling any language server like `gopls` which waits for a response
  948        // to these requests when initializing.
  949        language_server
  950            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  951                let this = lsp_store.clone();
  952                move |params, cx| {
  953                    let this = this.clone();
  954                    let mut cx = cx.clone();
  955                    async move {
  956                        this.update(&mut cx, |this, _| {
  957                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  958                            {
  959                                status
  960                                    .progress_tokens
  961                                    .insert(ProgressToken::from_lsp(params.token));
  962                            }
  963                        })?;
  964
  965                        Ok(())
  966                    }
  967                }
  968            })
  969            .detach();
  970
  971        language_server
  972            .on_request::<lsp::request::RegisterCapability, _, _>({
  973                let lsp_store = lsp_store.clone();
  974                move |params, cx| {
  975                    let lsp_store = lsp_store.clone();
  976                    let mut cx = cx.clone();
  977                    async move {
  978                        lsp_store
  979                            .update(&mut cx, |lsp_store, cx| {
  980                                if lsp_store.as_local().is_some() {
  981                                    match lsp_store
  982                                        .register_server_capabilities(server_id, params, cx)
  983                                    {
  984                                        Ok(()) => {}
  985                                        Err(e) => {
  986                                            log::error!(
  987                                                "Failed to register server capabilities: {e:#}"
  988                                            );
  989                                        }
  990                                    };
  991                                }
  992                            })
  993                            .ok();
  994                        Ok(())
  995                    }
  996                }
  997            })
  998            .detach();
  999
 1000        language_server
 1001            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1002                let lsp_store = lsp_store.clone();
 1003                move |params, cx| {
 1004                    let lsp_store = lsp_store.clone();
 1005                    let mut cx = cx.clone();
 1006                    async move {
 1007                        lsp_store
 1008                            .update(&mut cx, |lsp_store, cx| {
 1009                                if lsp_store.as_local().is_some() {
 1010                                    match lsp_store
 1011                                        .unregister_server_capabilities(server_id, params, cx)
 1012                                    {
 1013                                        Ok(()) => {}
 1014                                        Err(e) => {
 1015                                            log::error!(
 1016                                                "Failed to unregister server capabilities: {e:#}"
 1017                                            );
 1018                                        }
 1019                                    }
 1020                                }
 1021                            })
 1022                            .ok();
 1023                        Ok(())
 1024                    }
 1025                }
 1026            })
 1027            .detach();
 1028
 1029        language_server
 1030            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1031                let this = lsp_store.clone();
 1032                move |params, cx| {
 1033                    let mut cx = cx.clone();
 1034                    let this = this.clone();
 1035                    async move {
 1036                        LocalLspStore::on_lsp_workspace_edit(
 1037                            this.clone(),
 1038                            params,
 1039                            server_id,
 1040                            &mut cx,
 1041                        )
 1042                        .await
 1043                    }
 1044                }
 1045            })
 1046            .detach();
 1047
 1048        language_server
 1049            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1050                let lsp_store = lsp_store.clone();
 1051                let request_id = Arc::new(AtomicUsize::new(0));
 1052                move |(), cx| {
 1053                    let lsp_store = lsp_store.clone();
 1054                    let request_id = request_id.clone();
 1055                    let mut cx = cx.clone();
 1056                    async move {
 1057                        lsp_store
 1058                            .update(&mut cx, |lsp_store, cx| {
 1059                                let request_id =
 1060                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1061                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1062                                    server_id,
 1063                                    request_id,
 1064                                });
 1065                                lsp_store
 1066                                    .downstream_client
 1067                                    .as_ref()
 1068                                    .map(|(client, project_id)| {
 1069                                        client.send(proto::RefreshInlayHints {
 1070                                            project_id: *project_id,
 1071                                            server_id: server_id.to_proto(),
 1072                                            request_id: request_id.map(|id| id as u64),
 1073                                        })
 1074                                    })
 1075                            })?
 1076                            .transpose()?;
 1077                        Ok(())
 1078                    }
 1079                }
 1080            })
 1081            .detach();
 1082
 1083        language_server
 1084            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1085                let this = lsp_store.clone();
 1086                move |(), cx| {
 1087                    let this = this.clone();
 1088                    let mut cx = cx.clone();
 1089                    async move {
 1090                        this.update(&mut cx, |this, cx| {
 1091                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1092                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1093                                client.send(proto::RefreshCodeLens {
 1094                                    project_id: *project_id,
 1095                                })
 1096                            })
 1097                        })?
 1098                        .transpose()?;
 1099                        Ok(())
 1100                    }
 1101                }
 1102            })
 1103            .detach();
 1104
 1105        language_server
 1106            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1107                let lsp_store = lsp_store.clone();
 1108                let request_id = Arc::new(AtomicUsize::new(0));
 1109                move |(), cx| {
 1110                    let lsp_store = lsp_store.clone();
 1111                    let request_id = request_id.clone();
 1112                    let mut cx = cx.clone();
 1113                    async move {
 1114                        lsp_store
 1115                            .update(&mut cx, |lsp_store, cx| {
 1116                                let request_id =
 1117                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1118                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1119                                    server_id,
 1120                                    request_id,
 1121                                });
 1122                                lsp_store
 1123                                    .downstream_client
 1124                                    .as_ref()
 1125                                    .map(|(client, project_id)| {
 1126                                        client.send(proto::RefreshSemanticTokens {
 1127                                            project_id: *project_id,
 1128                                            server_id: server_id.to_proto(),
 1129                                            request_id: request_id.map(|id| id as u64),
 1130                                        })
 1131                                    })
 1132                            })?
 1133                            .transpose()?;
 1134                        Ok(())
 1135                    }
 1136                }
 1137            })
 1138            .detach();
 1139
 1140        language_server
 1141            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1142                let this = lsp_store.clone();
 1143                move |(), cx| {
 1144                    let this = this.clone();
 1145                    let mut cx = cx.clone();
 1146                    async move {
 1147                        this.update(&mut cx, |lsp_store, cx| {
 1148                            lsp_store.pull_workspace_diagnostics(server_id);
 1149                            lsp_store
 1150                                .downstream_client
 1151                                .as_ref()
 1152                                .map(|(client, project_id)| {
 1153                                    client.send(proto::PullWorkspaceDiagnostics {
 1154                                        project_id: *project_id,
 1155                                        server_id: server_id.to_proto(),
 1156                                    })
 1157                                })
 1158                                .transpose()?;
 1159                            anyhow::Ok(
 1160                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1161                            )
 1162                        })??
 1163                        .await;
 1164                        Ok(())
 1165                    }
 1166                }
 1167            })
 1168            .detach();
 1169
 1170        language_server
 1171            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1172                let this = lsp_store.clone();
 1173                let name = name.to_string();
 1174                let adapter = adapter.clone();
 1175                move |params, cx| {
 1176                    let this = this.clone();
 1177                    let name = name.to_string();
 1178                    let adapter = adapter.clone();
 1179                    let mut cx = cx.clone();
 1180                    async move {
 1181                        let actions = params.actions.unwrap_or_default();
 1182                        let message = params.message.clone();
 1183                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1184                        let level = match params.typ {
 1185                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1186                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1187                            _ => PromptLevel::Info,
 1188                        };
 1189                        let request = LanguageServerPromptRequest::new(
 1190                            level,
 1191                            params.message,
 1192                            actions,
 1193                            name.clone(),
 1194                            tx,
 1195                        );
 1196
 1197                        let did_update = this
 1198                            .update(&mut cx, |_, cx| {
 1199                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1200                            })
 1201                            .is_ok();
 1202                        if did_update {
 1203                            let response = rx.recv().await.ok();
 1204                            if let Some(ref selected_action) = response {
 1205                                let context = language::PromptResponseContext {
 1206                                    message,
 1207                                    selected_action: selected_action.clone(),
 1208                                };
 1209                                adapter.process_prompt_response(&context, &mut cx)
 1210                            }
 1211
 1212                            Ok(response)
 1213                        } else {
 1214                            Ok(None)
 1215                        }
 1216                    }
 1217                }
 1218            })
 1219            .detach();
 1220        language_server
 1221            .on_notification::<lsp::notification::ShowMessage, _>({
 1222                let this = lsp_store.clone();
 1223                let name = name.to_string();
 1224                move |params, cx| {
 1225                    let this = this.clone();
 1226                    let name = name.to_string();
 1227                    let mut cx = cx.clone();
 1228
 1229                    let (tx, _) = smol::channel::bounded(1);
 1230                    let level = match params.typ {
 1231                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1232                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1233                        _ => PromptLevel::Info,
 1234                    };
 1235                    let request =
 1236                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1237
 1238                    let _ = this.update(&mut cx, |_, cx| {
 1239                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1240                    });
 1241                }
 1242            })
 1243            .detach();
 1244
 1245        let disk_based_diagnostics_progress_token =
 1246            adapter.disk_based_diagnostics_progress_token.clone();
 1247
 1248        language_server
 1249            .on_notification::<lsp::notification::Progress, _>({
 1250                let this = lsp_store.clone();
 1251                move |params, cx| {
 1252                    if let Some(this) = this.upgrade() {
 1253                        this.update(cx, |this, cx| {
 1254                            this.on_lsp_progress(
 1255                                params,
 1256                                server_id,
 1257                                disk_based_diagnostics_progress_token.clone(),
 1258                                cx,
 1259                            );
 1260                        });
 1261                    }
 1262                }
 1263            })
 1264            .detach();
 1265
 1266        language_server
 1267            .on_notification::<lsp::notification::LogMessage, _>({
 1268                let this = lsp_store.clone();
 1269                move |params, cx| {
 1270                    if let Some(this) = this.upgrade() {
 1271                        this.update(cx, |_, cx| {
 1272                            cx.emit(LspStoreEvent::LanguageServerLog(
 1273                                server_id,
 1274                                LanguageServerLogType::Log(params.typ),
 1275                                params.message,
 1276                            ));
 1277                        });
 1278                    }
 1279                }
 1280            })
 1281            .detach();
 1282
 1283        language_server
 1284            .on_notification::<lsp::notification::LogTrace, _>({
 1285                let this = lsp_store.clone();
 1286                move |params, cx| {
 1287                    let mut cx = cx.clone();
 1288                    if let Some(this) = this.upgrade() {
 1289                        this.update(&mut cx, |_, cx| {
 1290                            cx.emit(LspStoreEvent::LanguageServerLog(
 1291                                server_id,
 1292                                LanguageServerLogType::Trace {
 1293                                    verbose_info: params.verbose,
 1294                                },
 1295                                params.message,
 1296                            ));
 1297                        });
 1298                    }
 1299                }
 1300            })
 1301            .detach();
 1302
 1303        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1304        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1305        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1306        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1307    }
 1308
 1309    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1310        let shutdown_futures = self
 1311            .language_servers
 1312            .drain()
 1313            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1314            .collect::<Vec<_>>();
 1315
 1316        async move {
 1317            join_all(shutdown_futures).await;
 1318        }
 1319    }
 1320
 1321    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1322        match server_state {
 1323            LanguageServerState::Running { server, .. } => {
 1324                if let Some(shutdown) = server.shutdown() {
 1325                    shutdown.await;
 1326                }
 1327            }
 1328            LanguageServerState::Starting { startup, .. } => {
 1329                if let Some(server) = startup.await
 1330                    && let Some(shutdown) = server.shutdown()
 1331                {
 1332                    shutdown.await;
 1333                }
 1334            }
 1335        }
 1336        Ok(())
 1337    }
 1338
 1339    fn language_servers_for_worktree(
 1340        &self,
 1341        worktree_id: WorktreeId,
 1342    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1343        self.language_server_ids
 1344            .iter()
 1345            .filter_map(move |(seed, state)| {
 1346                if seed.worktree_id != worktree_id {
 1347                    return None;
 1348                }
 1349
 1350                if let Some(LanguageServerState::Running { server, .. }) =
 1351                    self.language_servers.get(&state.id)
 1352                {
 1353                    Some(server)
 1354                } else {
 1355                    None
 1356                }
 1357            })
 1358    }
 1359
 1360    fn language_server_ids_for_project_path(
 1361        &self,
 1362        project_path: ProjectPath,
 1363        language: &Language,
 1364        cx: &mut App,
 1365    ) -> Vec<LanguageServerId> {
 1366        let Some(worktree) = self
 1367            .worktree_store
 1368            .read(cx)
 1369            .worktree_for_id(project_path.worktree_id, cx)
 1370        else {
 1371            return Vec::new();
 1372        };
 1373        let delegate: Arc<dyn ManifestDelegate> =
 1374            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1375
 1376        self.lsp_tree
 1377            .get(
 1378                project_path,
 1379                language.name(),
 1380                language.manifest(),
 1381                &delegate,
 1382                cx,
 1383            )
 1384            .collect::<Vec<_>>()
 1385    }
 1386
 1387    fn language_server_ids_for_buffer(
 1388        &self,
 1389        buffer: &Buffer,
 1390        cx: &mut App,
 1391    ) -> Vec<LanguageServerId> {
 1392        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1393            let worktree_id = file.worktree_id(cx);
 1394
 1395            let path: Arc<RelPath> = file
 1396                .path()
 1397                .parent()
 1398                .map(Arc::from)
 1399                .unwrap_or_else(|| file.path().clone());
 1400            let worktree_path = ProjectPath { worktree_id, path };
 1401            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1402        } else {
 1403            Vec::new()
 1404        }
 1405    }
 1406
 1407    fn language_servers_for_buffer<'a>(
 1408        &'a self,
 1409        buffer: &'a Buffer,
 1410        cx: &'a mut App,
 1411    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1412        self.language_server_ids_for_buffer(buffer, cx)
 1413            .into_iter()
 1414            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1415                LanguageServerState::Running {
 1416                    adapter, server, ..
 1417                } => Some((adapter, server)),
 1418                _ => None,
 1419            })
 1420    }
 1421
 1422    async fn execute_code_action_kind_locally(
 1423        lsp_store: WeakEntity<LspStore>,
 1424        mut buffers: Vec<Entity<Buffer>>,
 1425        kind: CodeActionKind,
 1426        push_to_history: bool,
 1427        cx: &mut AsyncApp,
 1428    ) -> anyhow::Result<ProjectTransaction> {
 1429        // Do not allow multiple concurrent code actions requests for the
 1430        // same buffer.
 1431        lsp_store.update(cx, |this, cx| {
 1432            let this = this.as_local_mut().unwrap();
 1433            buffers.retain(|buffer| {
 1434                this.buffers_being_formatted
 1435                    .insert(buffer.read(cx).remote_id())
 1436            });
 1437        })?;
 1438        let _cleanup = defer({
 1439            let this = lsp_store.clone();
 1440            let mut cx = cx.clone();
 1441            let buffers = &buffers;
 1442            move || {
 1443                this.update(&mut cx, |this, cx| {
 1444                    let this = this.as_local_mut().unwrap();
 1445                    for buffer in buffers {
 1446                        this.buffers_being_formatted
 1447                            .remove(&buffer.read(cx).remote_id());
 1448                    }
 1449                })
 1450                .ok();
 1451            }
 1452        });
 1453        let mut project_transaction = ProjectTransaction::default();
 1454
 1455        for buffer in &buffers {
 1456            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1457                buffer.update(cx, |buffer, cx| {
 1458                    lsp_store
 1459                        .as_local()
 1460                        .unwrap()
 1461                        .language_servers_for_buffer(buffer, cx)
 1462                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1463                        .collect::<Vec<_>>()
 1464                })
 1465            })?;
 1466            for (_, language_server) in adapters_and_servers.iter() {
 1467                let actions = Self::get_server_code_actions_from_action_kinds(
 1468                    &lsp_store,
 1469                    language_server.server_id(),
 1470                    vec![kind.clone()],
 1471                    buffer,
 1472                    cx,
 1473                )
 1474                .await?;
 1475                Self::execute_code_actions_on_server(
 1476                    &lsp_store,
 1477                    language_server,
 1478                    actions,
 1479                    push_to_history,
 1480                    &mut project_transaction,
 1481                    cx,
 1482                )
 1483                .await?;
 1484            }
 1485        }
 1486        Ok(project_transaction)
 1487    }
 1488
 1489    async fn format_locally(
 1490        lsp_store: WeakEntity<LspStore>,
 1491        mut buffers: Vec<FormattableBuffer>,
 1492        push_to_history: bool,
 1493        trigger: FormatTrigger,
 1494        logger: zlog::Logger,
 1495        cx: &mut AsyncApp,
 1496    ) -> anyhow::Result<ProjectTransaction> {
 1497        // Do not allow multiple concurrent formatting requests for the
 1498        // same buffer.
 1499        lsp_store.update(cx, |this, cx| {
 1500            let this = this.as_local_mut().unwrap();
 1501            buffers.retain(|buffer| {
 1502                this.buffers_being_formatted
 1503                    .insert(buffer.handle.read(cx).remote_id())
 1504            });
 1505        })?;
 1506
 1507        let _cleanup = defer({
 1508            let this = lsp_store.clone();
 1509            let mut cx = cx.clone();
 1510            let buffers = &buffers;
 1511            move || {
 1512                this.update(&mut cx, |this, cx| {
 1513                    let this = this.as_local_mut().unwrap();
 1514                    for buffer in buffers {
 1515                        this.buffers_being_formatted
 1516                            .remove(&buffer.handle.read(cx).remote_id());
 1517                    }
 1518                })
 1519                .ok();
 1520            }
 1521        });
 1522
 1523        let mut project_transaction = ProjectTransaction::default();
 1524
 1525        for buffer in &buffers {
 1526            zlog::debug!(
 1527                logger =>
 1528                "formatting buffer '{:?}'",
 1529                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1530            );
 1531            // Create an empty transaction to hold all of the formatting edits.
 1532            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1533                // ensure no transactions created while formatting are
 1534                // grouped with the previous transaction in the history
 1535                // based on the transaction group interval
 1536                buffer.finalize_last_transaction();
 1537                buffer
 1538                    .start_transaction()
 1539                    .context("transaction already open")?;
 1540                buffer.end_transaction(cx);
 1541                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1542                buffer.finalize_last_transaction();
 1543                anyhow::Ok(transaction_id)
 1544            })?;
 1545
 1546            let result = Self::format_buffer_locally(
 1547                lsp_store.clone(),
 1548                buffer,
 1549                formatting_transaction_id,
 1550                trigger,
 1551                logger,
 1552                cx,
 1553            )
 1554            .await;
 1555
 1556            buffer.handle.update(cx, |buffer, cx| {
 1557                let Some(formatting_transaction) =
 1558                    buffer.get_transaction(formatting_transaction_id).cloned()
 1559                else {
 1560                    zlog::warn!(logger => "no formatting transaction");
 1561                    return;
 1562                };
 1563                if formatting_transaction.edit_ids.is_empty() {
 1564                    zlog::debug!(logger => "no changes made while formatting");
 1565                    buffer.forget_transaction(formatting_transaction_id);
 1566                    return;
 1567                }
 1568                if !push_to_history {
 1569                    zlog::trace!(logger => "forgetting format transaction");
 1570                    buffer.forget_transaction(formatting_transaction.id);
 1571                }
 1572                project_transaction
 1573                    .0
 1574                    .insert(cx.entity(), formatting_transaction);
 1575            });
 1576
 1577            result?;
 1578        }
 1579
 1580        Ok(project_transaction)
 1581    }
 1582
 1583    async fn format_buffer_locally(
 1584        lsp_store: WeakEntity<LspStore>,
 1585        buffer: &FormattableBuffer,
 1586        formatting_transaction_id: clock::Lamport,
 1587        trigger: FormatTrigger,
 1588        logger: zlog::Logger,
 1589        cx: &mut AsyncApp,
 1590    ) -> Result<()> {
 1591        let (adapters_and_servers, settings, request_timeout) =
 1592            lsp_store.update(cx, |lsp_store, cx| {
 1593                buffer.handle.update(cx, |buffer, cx| {
 1594                    let adapters_and_servers = lsp_store
 1595                        .as_local()
 1596                        .unwrap()
 1597                        .language_servers_for_buffer(buffer, cx)
 1598                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1599                        .collect::<Vec<_>>();
 1600                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1601                    let request_timeout = ProjectSettings::get_global(cx)
 1602                        .global_lsp_settings
 1603                        .get_request_timeout();
 1604                    (adapters_and_servers, settings, request_timeout)
 1605                })
 1606            })?;
 1607
 1608        // handle whitespace formatting
 1609        if settings.remove_trailing_whitespace_on_save {
 1610            zlog::trace!(logger => "removing trailing whitespace");
 1611            let diff = buffer
 1612                .handle
 1613                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1614                .await;
 1615            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1616                buffer.apply_diff(diff, cx);
 1617            })?;
 1618        }
 1619
 1620        if settings.ensure_final_newline_on_save {
 1621            zlog::trace!(logger => "ensuring final newline");
 1622            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1623                buffer.ensure_final_newline(cx);
 1624            })?;
 1625        }
 1626
 1627        // Formatter for `code_actions_on_format` that runs before
 1628        // the rest of the formatters
 1629        let mut code_actions_on_format_formatters = None;
 1630        let should_run_code_actions_on_format = !matches!(
 1631            (trigger, &settings.format_on_save),
 1632            (FormatTrigger::Save, &FormatOnSave::Off)
 1633        );
 1634        if should_run_code_actions_on_format {
 1635            let have_code_actions_to_run_on_format = settings
 1636                .code_actions_on_format
 1637                .values()
 1638                .any(|enabled| *enabled);
 1639            if have_code_actions_to_run_on_format {
 1640                zlog::trace!(logger => "going to run code actions on format");
 1641                code_actions_on_format_formatters = Some(
 1642                    settings
 1643                        .code_actions_on_format
 1644                        .iter()
 1645                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1646                        .cloned()
 1647                        .map(Formatter::CodeAction)
 1648                        .collect::<Vec<_>>(),
 1649                );
 1650            }
 1651        }
 1652
 1653        let formatters = match (trigger, &settings.format_on_save) {
 1654            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1655            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1656                settings.formatter.as_ref()
 1657            }
 1658        };
 1659
 1660        let formatters = code_actions_on_format_formatters
 1661            .iter()
 1662            .flatten()
 1663            .chain(formatters);
 1664
 1665        for formatter in formatters {
 1666            let formatter = if formatter == &Formatter::Auto {
 1667                if settings.prettier.allowed {
 1668                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1669                    &Formatter::Prettier
 1670                } else {
 1671                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1672                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1673                }
 1674            } else {
 1675                formatter
 1676            };
 1677            if let Err(err) = Self::apply_formatter(
 1678                formatter,
 1679                &lsp_store,
 1680                buffer,
 1681                formatting_transaction_id,
 1682                &adapters_and_servers,
 1683                &settings,
 1684                request_timeout,
 1685                logger,
 1686                cx,
 1687            )
 1688            .await
 1689            {
 1690                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1691            }
 1692        }
 1693
 1694        Ok(())
 1695    }
 1696
 1697    async fn apply_formatter(
 1698        formatter: &Formatter,
 1699        lsp_store: &WeakEntity<LspStore>,
 1700        buffer: &FormattableBuffer,
 1701        formatting_transaction_id: clock::Lamport,
 1702        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1703        settings: &LanguageSettings,
 1704        request_timeout: Duration,
 1705        logger: zlog::Logger,
 1706        cx: &mut AsyncApp,
 1707    ) -> anyhow::Result<()> {
 1708        match formatter {
 1709            Formatter::None => {
 1710                zlog::trace!(logger => "skipping formatter 'none'");
 1711                return Ok(());
 1712            }
 1713            Formatter::Auto => {
 1714                debug_panic!("Auto resolved above");
 1715                return Ok(());
 1716            }
 1717            Formatter::Prettier => {
 1718                let logger = zlog::scoped!(logger => "prettier");
 1719                zlog::trace!(logger => "formatting");
 1720                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1721
 1722                // When selection ranges are provided (via FormatSelections), we pass the
 1723                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1724                // After diffing, we filter the resulting edits to only keep those that
 1725                // overlap with the original byte-level selection ranges.
 1726                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1727                    Some(ranges) if !ranges.is_empty() => {
 1728                        let (utf16_range, byte_ranges) =
 1729                            buffer.handle.read_with(cx, |buffer, _cx| {
 1730                                let snapshot = buffer.snapshot();
 1731                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1732                                let mut max_end_utf16 = OffsetUtf16(0);
 1733                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1734                                for range in ranges {
 1735                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1736                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1737                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1738                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1739
 1740                                    let start_byte = range.start.to_offset(&snapshot);
 1741                                    let end_byte = range.end.to_offset(&snapshot);
 1742                                    byte_ranges.push(start_byte..end_byte);
 1743                                }
 1744                                (min_start_utf16..max_end_utf16, byte_ranges)
 1745                            });
 1746                        (Some(utf16_range), Some(byte_ranges))
 1747                    }
 1748                    _ => (None, None),
 1749                };
 1750
 1751                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1752                    lsp_store.prettier_store().unwrap().downgrade()
 1753                })?;
 1754                let diff = prettier_store::format_with_prettier(
 1755                    &prettier,
 1756                    &buffer.handle,
 1757                    range_utf16,
 1758                    cx,
 1759                )
 1760                .await
 1761                .transpose()?;
 1762                let Some(mut diff) = diff else {
 1763                    zlog::trace!(logger => "No changes");
 1764                    return Ok(());
 1765                };
 1766
 1767                if let Some(byte_ranges) = byte_ranges {
 1768                    diff.edits.retain(|(edit_range, _)| {
 1769                        byte_ranges.iter().any(|selection_range| {
 1770                            edit_range.start < selection_range.end
 1771                                && edit_range.end > selection_range.start
 1772                        })
 1773                    });
 1774                    if diff.edits.is_empty() {
 1775                        zlog::trace!(logger => "No changes within selection");
 1776                        return Ok(());
 1777                    }
 1778                }
 1779
 1780                extend_formatting_transaction(
 1781                    buffer,
 1782                    formatting_transaction_id,
 1783                    cx,
 1784                    |buffer, cx| {
 1785                        buffer.apply_diff(diff, cx);
 1786                    },
 1787                )?;
 1788            }
 1789            Formatter::External { command, arguments } => {
 1790                let logger = zlog::scoped!(logger => "command");
 1791
 1792                if buffer.ranges.is_some() {
 1793                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1794                    return Ok(());
 1795                }
 1796
 1797                zlog::trace!(logger => "formatting");
 1798                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1799
 1800                let diff =
 1801                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1802                        .await
 1803                        .with_context(|| {
 1804                            format!("Failed to format buffer via external command: {}", command)
 1805                        })?;
 1806                let Some(diff) = diff else {
 1807                    zlog::trace!(logger => "No changes");
 1808                    return Ok(());
 1809                };
 1810
 1811                extend_formatting_transaction(
 1812                    buffer,
 1813                    formatting_transaction_id,
 1814                    cx,
 1815                    |buffer, cx| {
 1816                        buffer.apply_diff(diff, cx);
 1817                    },
 1818                )?;
 1819            }
 1820            Formatter::LanguageServer(specifier) => {
 1821                let logger = zlog::scoped!(logger => "language-server");
 1822                zlog::trace!(logger => "formatting");
 1823                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1824
 1825                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1826                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1827                    return Ok(());
 1828                };
 1829
 1830                let language_server = match specifier {
 1831                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1832                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1833                            if adapter.name.0.as_ref() == name {
 1834                                Some(server.clone())
 1835                            } else {
 1836                                None
 1837                            }
 1838                        })
 1839                    }
 1840                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1841                        .iter()
 1842                        .find(|(_, server)| Self::server_supports_formatting(server))
 1843                        .map(|(_, server)| server.clone()),
 1844                };
 1845
 1846                let Some(language_server) = language_server else {
 1847                    log::debug!(
 1848                        "No language server found to format buffer '{:?}'. Skipping",
 1849                        buffer_path_abs.as_path().to_string_lossy()
 1850                    );
 1851                    return Ok(());
 1852                };
 1853
 1854                zlog::trace!(
 1855                    logger =>
 1856                    "Formatting buffer '{:?}' using language server '{:?}'",
 1857                    buffer_path_abs.as_path().to_string_lossy(),
 1858                    language_server.name()
 1859                );
 1860
 1861                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1862                    zlog::trace!(logger => "formatting ranges");
 1863                    Self::format_ranges_via_lsp(
 1864                        &lsp_store,
 1865                        &buffer.handle,
 1866                        ranges,
 1867                        buffer_path_abs,
 1868                        &language_server,
 1869                        &settings,
 1870                        cx,
 1871                    )
 1872                    .await
 1873                    .context("Failed to format ranges via language server")?
 1874                } else {
 1875                    zlog::trace!(logger => "formatting full");
 1876                    Self::format_via_lsp(
 1877                        &lsp_store,
 1878                        &buffer.handle,
 1879                        buffer_path_abs,
 1880                        &language_server,
 1881                        &settings,
 1882                        cx,
 1883                    )
 1884                    .await
 1885                    .context("failed to format via language server")?
 1886                };
 1887
 1888                if edits.is_empty() {
 1889                    zlog::trace!(logger => "No changes");
 1890                    return Ok(());
 1891                }
 1892                extend_formatting_transaction(
 1893                    buffer,
 1894                    formatting_transaction_id,
 1895                    cx,
 1896                    |buffer, cx| {
 1897                        buffer.edit(edits, None, cx);
 1898                    },
 1899                )?;
 1900            }
 1901            Formatter::CodeAction(code_action_name) => {
 1902                let logger = zlog::scoped!(logger => "code-actions");
 1903                zlog::trace!(logger => "formatting");
 1904                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1905
 1906                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1907                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1908                    return Ok(());
 1909                };
 1910
 1911                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1912                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1913
 1914                let mut actions_and_servers = Vec::new();
 1915
 1916                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1917                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1918                        &lsp_store,
 1919                        language_server.server_id(),
 1920                        vec![code_action_kind.clone()],
 1921                        &buffer.handle,
 1922                        cx,
 1923                    )
 1924                    .await
 1925                    .with_context(|| {
 1926                        format!(
 1927                            "Failed to resolve code action {:?} with language server {}",
 1928                            code_action_kind,
 1929                            language_server.name()
 1930                        )
 1931                    });
 1932                    let Ok(actions) = actions_result else {
 1933                        // note: it may be better to set result to the error and break formatters here
 1934                        // but for now we try to execute the actions that we can resolve and skip the rest
 1935                        zlog::error!(
 1936                            logger =>
 1937                            "Failed to resolve code action {:?} with language server {}",
 1938                            code_action_kind,
 1939                            language_server.name()
 1940                        );
 1941                        continue;
 1942                    };
 1943                    for action in actions {
 1944                        actions_and_servers.push((action, index));
 1945                    }
 1946                }
 1947
 1948                if actions_and_servers.is_empty() {
 1949                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1950                    return Ok(());
 1951                }
 1952
 1953                'actions: for (mut action, server_index) in actions_and_servers {
 1954                    let server = &adapters_and_servers[server_index].1;
 1955
 1956                    let describe_code_action = |action: &CodeAction| {
 1957                        format!(
 1958                            "code action '{}' with title \"{}\" on server {}",
 1959                            action
 1960                                .lsp_action
 1961                                .action_kind()
 1962                                .unwrap_or("unknown".into())
 1963                                .as_str(),
 1964                            action.lsp_action.title(),
 1965                            server.name(),
 1966                        )
 1967                    };
 1968
 1969                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1970
 1971                    if let Err(err) =
 1972                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 1973                    {
 1974                        zlog::error!(
 1975                            logger =>
 1976                            "Failed to resolve {}. Error: {}",
 1977                            describe_code_action(&action),
 1978                            err
 1979                        );
 1980                        continue;
 1981                    }
 1982
 1983                    if let Some(edit) = action.lsp_action.edit().cloned() {
 1984                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1985                        // but filters out and logs warnings for code actions that require unreasonably
 1986                        // difficult handling on our part, such as:
 1987                        // - applying edits that call commands
 1988                        //   which can result in arbitrary workspace edits being sent from the server that
 1989                        //   have no way of being tied back to the command that initiated them (i.e. we
 1990                        //   can't know which edits are part of the format request, or if the server is done sending
 1991                        //   actions in response to the command)
 1992                        // - actions that create/delete/modify/rename files other than the one we are formatting
 1993                        //   as we then would need to handle such changes correctly in the local history as well
 1994                        //   as the remote history through the ProjectTransaction
 1995                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1996                        // Supporting these actions is not impossible, but not supported as of yet.
 1997                        if edit.changes.is_none() && edit.document_changes.is_none() {
 1998                            zlog::trace!(
 1999                                logger =>
 2000                                "No changes for code action. Skipping {}",
 2001                                describe_code_action(&action),
 2002                            );
 2003                            continue;
 2004                        }
 2005
 2006                        let mut operations = Vec::new();
 2007                        if let Some(document_changes) = edit.document_changes {
 2008                            match document_changes {
 2009                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2010                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2011                                ),
 2012                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2013                            }
 2014                        } else if let Some(changes) = edit.changes {
 2015                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2016                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2017                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2018                                        uri,
 2019                                        version: None,
 2020                                    },
 2021                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2022                                })
 2023                            }));
 2024                        }
 2025
 2026                        let mut edits = Vec::with_capacity(operations.len());
 2027
 2028                        if operations.is_empty() {
 2029                            zlog::trace!(
 2030                                logger =>
 2031                                "No changes for code action. Skipping {}",
 2032                                describe_code_action(&action),
 2033                            );
 2034                            continue;
 2035                        }
 2036                        for operation in operations {
 2037                            let op = match operation {
 2038                                lsp::DocumentChangeOperation::Edit(op) => op,
 2039                                lsp::DocumentChangeOperation::Op(_) => {
 2040                                    zlog::warn!(
 2041                                        logger =>
 2042                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2043                                        describe_code_action(&action),
 2044                                    );
 2045                                    continue 'actions;
 2046                                }
 2047                            };
 2048                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2049                                zlog::warn!(
 2050                                    logger =>
 2051                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2052                                    &op.text_document.uri,
 2053                                    describe_code_action(&action),
 2054                                );
 2055                                continue 'actions;
 2056                            };
 2057                            if &file_path != buffer_path_abs {
 2058                                zlog::warn!(
 2059                                    logger =>
 2060                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2061                                    file_path,
 2062                                    buffer_path_abs,
 2063                                    describe_code_action(&action),
 2064                                );
 2065                                continue 'actions;
 2066                            }
 2067
 2068                            let mut lsp_edits = Vec::new();
 2069                            for edit in op.edits {
 2070                                match edit {
 2071                                    Edit::Plain(edit) => {
 2072                                        if !lsp_edits.contains(&edit) {
 2073                                            lsp_edits.push(edit);
 2074                                        }
 2075                                    }
 2076                                    Edit::Annotated(edit) => {
 2077                                        if !lsp_edits.contains(&edit.text_edit) {
 2078                                            lsp_edits.push(edit.text_edit);
 2079                                        }
 2080                                    }
 2081                                    Edit::Snippet(_) => {
 2082                                        zlog::warn!(
 2083                                            logger =>
 2084                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2085                                            describe_code_action(&action),
 2086                                        );
 2087                                        continue 'actions;
 2088                                    }
 2089                                }
 2090                            }
 2091                            let edits_result = lsp_store
 2092                                .update(cx, |lsp_store, cx| {
 2093                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2094                                        &buffer.handle,
 2095                                        lsp_edits,
 2096                                        server.server_id(),
 2097                                        op.text_document.version,
 2098                                        cx,
 2099                                    )
 2100                                })?
 2101                                .await;
 2102                            let Ok(resolved_edits) = edits_result else {
 2103                                zlog::warn!(
 2104                                    logger =>
 2105                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2106                                    buffer_path_abs.as_path(),
 2107                                    describe_code_action(&action),
 2108                                );
 2109                                continue 'actions;
 2110                            };
 2111                            edits.extend(resolved_edits);
 2112                        }
 2113
 2114                        if edits.is_empty() {
 2115                            zlog::warn!(logger => "No edits resolved from LSP");
 2116                            continue;
 2117                        }
 2118
 2119                        extend_formatting_transaction(
 2120                            buffer,
 2121                            formatting_transaction_id,
 2122                            cx,
 2123                            |buffer, cx| {
 2124                                zlog::info!(
 2125                                    "Applying edits {edits:?}. Content: {:?}",
 2126                                    buffer.text()
 2127                                );
 2128                                buffer.edit(edits, None, cx);
 2129                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2130                            },
 2131                        )?;
 2132                    }
 2133
 2134                    let Some(command) = action.lsp_action.command() else {
 2135                        continue;
 2136                    };
 2137
 2138                    zlog::warn!(
 2139                        logger =>
 2140                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2141                        &command.command,
 2142                    );
 2143
 2144                    let server_capabilities = server.capabilities();
 2145                    let available_commands = server_capabilities
 2146                        .execute_command_provider
 2147                        .as_ref()
 2148                        .map(|options| options.commands.as_slice())
 2149                        .unwrap_or_default();
 2150                    if !available_commands.contains(&command.command) {
 2151                        zlog::warn!(
 2152                            logger =>
 2153                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2154                            command.command,
 2155                            server.name(),
 2156                        );
 2157                        continue;
 2158                    }
 2159
 2160                    extend_formatting_transaction(
 2161                        buffer,
 2162                        formatting_transaction_id,
 2163                        cx,
 2164                        |_, _| {},
 2165                    )?;
 2166                    zlog::info!(logger => "Executing command {}", &command.command);
 2167
 2168                    lsp_store.update(cx, |this, _| {
 2169                        this.as_local_mut()
 2170                            .unwrap()
 2171                            .last_workspace_edits_by_language_server
 2172                            .remove(&server.server_id());
 2173                    })?;
 2174
 2175                    let execute_command_result = server
 2176                        .request::<lsp::request::ExecuteCommand>(
 2177                            lsp::ExecuteCommandParams {
 2178                                command: command.command.clone(),
 2179                                arguments: command.arguments.clone().unwrap_or_default(),
 2180                                ..Default::default()
 2181                            },
 2182                            request_timeout,
 2183                        )
 2184                        .await
 2185                        .into_response();
 2186
 2187                    if execute_command_result.is_err() {
 2188                        zlog::error!(
 2189                            logger =>
 2190                            "Failed to execute command '{}' as part of {}",
 2191                            &command.command,
 2192                            describe_code_action(&action),
 2193                        );
 2194                        continue 'actions;
 2195                    }
 2196
 2197                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2198                        this.as_local_mut()
 2199                            .unwrap()
 2200                            .last_workspace_edits_by_language_server
 2201                            .remove(&server.server_id())
 2202                            .unwrap_or_default()
 2203                    })?;
 2204
 2205                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2206                    {
 2207                        zlog::trace!(
 2208                            logger =>
 2209                            "Successfully captured {} edits that resulted from command {}",
 2210                            transaction.edit_ids.len(),
 2211                            &command.command,
 2212                        );
 2213                        let transaction_id_project_transaction = transaction.id;
 2214                        buffer.handle.update(cx, |buffer, _| {
 2215                            // it may have been removed from history if push_to_history was
 2216                            // false in deserialize_workspace_edit. If so push it so we
 2217                            // can merge it with the format transaction
 2218                            // and pop the combined transaction off the history stack
 2219                            // later if push_to_history is false
 2220                            if buffer.get_transaction(transaction.id).is_none() {
 2221                                buffer.push_transaction(transaction, Instant::now());
 2222                            }
 2223                            buffer.merge_transactions(
 2224                                transaction_id_project_transaction,
 2225                                formatting_transaction_id,
 2226                            );
 2227                        });
 2228                    }
 2229
 2230                    if project_transaction_command.0.is_empty() {
 2231                        continue;
 2232                    }
 2233
 2234                    let mut extra_buffers = String::new();
 2235                    for buffer in project_transaction_command.0.keys() {
 2236                        buffer.read_with(cx, |b, cx| {
 2237                            let Some(path) = b.project_path(cx) else {
 2238                                return;
 2239                            };
 2240
 2241                            if !extra_buffers.is_empty() {
 2242                                extra_buffers.push_str(", ");
 2243                            }
 2244                            extra_buffers.push_str(path.path.as_unix_str());
 2245                        });
 2246                    }
 2247                    zlog::warn!(
 2248                        logger =>
 2249                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2250                        &command.command,
 2251                        extra_buffers,
 2252                    );
 2253                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2254                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2255                    // add it so it's included, and merge it into the format transaction when its created later
 2256                }
 2257            }
 2258        }
 2259
 2260        Ok(())
 2261    }
 2262
 2263    pub async fn format_ranges_via_lsp(
 2264        this: &WeakEntity<LspStore>,
 2265        buffer_handle: &Entity<Buffer>,
 2266        ranges: &[Range<Anchor>],
 2267        abs_path: &Path,
 2268        language_server: &Arc<LanguageServer>,
 2269        settings: &LanguageSettings,
 2270        cx: &mut AsyncApp,
 2271    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2272        let capabilities = &language_server.capabilities();
 2273        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2274        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2275            anyhow::bail!(
 2276                "{} language server does not support range formatting",
 2277                language_server.name()
 2278            );
 2279        }
 2280
 2281        let uri = file_path_to_lsp_url(abs_path)?;
 2282        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2283
 2284        let request_timeout = cx.update(|app| {
 2285            ProjectSettings::get_global(app)
 2286                .global_lsp_settings
 2287                .get_request_timeout()
 2288        });
 2289        let lsp_edits = {
 2290            let mut lsp_ranges = Vec::new();
 2291            this.update(cx, |_this, cx| {
 2292                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2293                // not have been sent to the language server. This seems like a fairly systemic
 2294                // issue, though, the resolution probably is not specific to formatting.
 2295                //
 2296                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2297                // LSP.
 2298                let snapshot = buffer_handle.read(cx).snapshot();
 2299                for range in ranges {
 2300                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2301                }
 2302                anyhow::Ok(())
 2303            })??;
 2304
 2305            let mut edits = None;
 2306            for range in lsp_ranges {
 2307                if let Some(mut edit) = language_server
 2308                    .request::<lsp::request::RangeFormatting>(
 2309                        lsp::DocumentRangeFormattingParams {
 2310                            text_document: text_document.clone(),
 2311                            range,
 2312                            options: lsp_command::lsp_formatting_options(settings),
 2313                            work_done_progress_params: Default::default(),
 2314                        },
 2315                        request_timeout,
 2316                    )
 2317                    .await
 2318                    .into_response()?
 2319                {
 2320                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2321                }
 2322            }
 2323            edits
 2324        };
 2325
 2326        if let Some(lsp_edits) = lsp_edits {
 2327            this.update(cx, |this, cx| {
 2328                this.as_local_mut().unwrap().edits_from_lsp(
 2329                    buffer_handle,
 2330                    lsp_edits,
 2331                    language_server.server_id(),
 2332                    None,
 2333                    cx,
 2334                )
 2335            })?
 2336            .await
 2337        } else {
 2338            Ok(Vec::with_capacity(0))
 2339        }
 2340    }
 2341
 2342    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2343        let capabilities = server.capabilities();
 2344        let formatting = capabilities.document_formatting_provider.as_ref();
 2345        let range_formatting = capabilities.document_range_formatting_provider.as_ref();
 2346        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2347            || matches!(range_formatting, Some(p) if *p != OneOf::Left(false))
 2348    }
 2349
 2350    async fn format_via_lsp(
 2351        this: &WeakEntity<LspStore>,
 2352        buffer: &Entity<Buffer>,
 2353        abs_path: &Path,
 2354        language_server: &Arc<LanguageServer>,
 2355        settings: &LanguageSettings,
 2356        cx: &mut AsyncApp,
 2357    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2358        let logger = zlog::scoped!("lsp_format");
 2359        zlog::debug!(logger => "Formatting via LSP");
 2360
 2361        let uri = file_path_to_lsp_url(abs_path)?;
 2362        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2363        let capabilities = &language_server.capabilities();
 2364
 2365        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2366        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2367
 2368        let request_timeout = cx.update(|app| {
 2369            ProjectSettings::get_global(app)
 2370                .global_lsp_settings
 2371                .get_request_timeout()
 2372        });
 2373
 2374        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2375            let _timer = zlog::time!(logger => "format-full");
 2376            language_server
 2377                .request::<lsp::request::Formatting>(
 2378                    lsp::DocumentFormattingParams {
 2379                        text_document,
 2380                        options: lsp_command::lsp_formatting_options(settings),
 2381                        work_done_progress_params: Default::default(),
 2382                    },
 2383                    request_timeout,
 2384                )
 2385                .await
 2386                .into_response()?
 2387        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2388            let _timer = zlog::time!(logger => "format-range");
 2389            let buffer_start = lsp::Position::new(0, 0);
 2390            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2391            language_server
 2392                .request::<lsp::request::RangeFormatting>(
 2393                    lsp::DocumentRangeFormattingParams {
 2394                        text_document: text_document.clone(),
 2395                        range: lsp::Range::new(buffer_start, buffer_end),
 2396                        options: lsp_command::lsp_formatting_options(settings),
 2397                        work_done_progress_params: Default::default(),
 2398                    },
 2399                    request_timeout,
 2400                )
 2401                .await
 2402                .into_response()?
 2403        } else {
 2404            None
 2405        };
 2406
 2407        if let Some(lsp_edits) = lsp_edits {
 2408            this.update(cx, |this, cx| {
 2409                this.as_local_mut().unwrap().edits_from_lsp(
 2410                    buffer,
 2411                    lsp_edits,
 2412                    language_server.server_id(),
 2413                    None,
 2414                    cx,
 2415                )
 2416            })?
 2417            .await
 2418        } else {
 2419            Ok(Vec::with_capacity(0))
 2420        }
 2421    }
 2422
 2423    async fn format_via_external_command(
 2424        buffer: &FormattableBuffer,
 2425        command: &str,
 2426        arguments: Option<&[String]>,
 2427        cx: &mut AsyncApp,
 2428    ) -> Result<Option<Diff>> {
 2429        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2430            let file = File::from_dyn(buffer.file())?;
 2431            let worktree = file.worktree.read(cx);
 2432            let mut worktree_path = worktree.abs_path().to_path_buf();
 2433            if worktree.root_entry()?.is_file() {
 2434                worktree_path.pop();
 2435            }
 2436            Some(worktree_path)
 2437        });
 2438
 2439        use util::command::Stdio;
 2440        let mut child = util::command::new_command(command);
 2441
 2442        if let Some(buffer_env) = buffer.env.as_ref() {
 2443            child.envs(buffer_env);
 2444        }
 2445
 2446        if let Some(working_dir_path) = working_dir_path {
 2447            child.current_dir(working_dir_path);
 2448        }
 2449
 2450        if let Some(arguments) = arguments {
 2451            child.args(arguments.iter().map(|arg| {
 2452                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2453                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2454                } else {
 2455                    arg.replace("{buffer_path}", "Untitled")
 2456                }
 2457            }));
 2458        }
 2459
 2460        let mut child = child
 2461            .stdin(Stdio::piped())
 2462            .stdout(Stdio::piped())
 2463            .stderr(Stdio::piped())
 2464            .spawn()?;
 2465
 2466        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2467        let text = buffer
 2468            .handle
 2469            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2470        for chunk in text.chunks() {
 2471            stdin.write_all(chunk.as_bytes()).await?;
 2472        }
 2473        stdin.flush().await?;
 2474
 2475        let output = child.output().await?;
 2476        anyhow::ensure!(
 2477            output.status.success(),
 2478            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2479            output.status.code(),
 2480            String::from_utf8_lossy(&output.stdout),
 2481            String::from_utf8_lossy(&output.stderr),
 2482        );
 2483
 2484        let stdout = String::from_utf8(output.stdout)?;
 2485        Ok(Some(
 2486            buffer
 2487                .handle
 2488                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2489                .await,
 2490        ))
 2491    }
 2492
 2493    async fn try_resolve_code_action(
 2494        lang_server: &LanguageServer,
 2495        action: &mut CodeAction,
 2496        request_timeout: Duration,
 2497    ) -> anyhow::Result<()> {
 2498        match &mut action.lsp_action {
 2499            LspAction::Action(lsp_action) => {
 2500                if !action.resolved
 2501                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2502                    && lsp_action.data.is_some()
 2503                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2504                {
 2505                    **lsp_action = lang_server
 2506                        .request::<lsp::request::CodeActionResolveRequest>(
 2507                            *lsp_action.clone(),
 2508                            request_timeout,
 2509                        )
 2510                        .await
 2511                        .into_response()?;
 2512                }
 2513            }
 2514            LspAction::CodeLens(lens) => {
 2515                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2516                    *lens = lang_server
 2517                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2518                        .await
 2519                        .into_response()?;
 2520                }
 2521            }
 2522            LspAction::Command(_) => {}
 2523        }
 2524
 2525        action.resolved = true;
 2526        anyhow::Ok(())
 2527    }
 2528
 2529    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2530        let buffer = buffer_handle.read(cx);
 2531
 2532        let file = buffer.file().cloned();
 2533
 2534        let Some(file) = File::from_dyn(file.as_ref()) else {
 2535            return;
 2536        };
 2537        if !file.is_local() {
 2538            return;
 2539        }
 2540        let path = ProjectPath::from_file(file, cx);
 2541        let worktree_id = file.worktree_id(cx);
 2542        let language = buffer.language().cloned();
 2543
 2544        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2545            for (server_id, diagnostics) in
 2546                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2547            {
 2548                self.update_buffer_diagnostics(
 2549                    buffer_handle,
 2550                    server_id,
 2551                    None,
 2552                    None,
 2553                    None,
 2554                    Vec::new(),
 2555                    diagnostics,
 2556                    cx,
 2557                )
 2558                .log_err();
 2559            }
 2560        }
 2561        let Some(language) = language else {
 2562            return;
 2563        };
 2564        let Some(snapshot) = self
 2565            .worktree_store
 2566            .read(cx)
 2567            .worktree_for_id(worktree_id, cx)
 2568            .map(|worktree| worktree.read(cx).snapshot())
 2569        else {
 2570            return;
 2571        };
 2572        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2573
 2574        for server_id in
 2575            self.lsp_tree
 2576                .get(path, language.name(), language.manifest(), &delegate, cx)
 2577        {
 2578            let server = self
 2579                .language_servers
 2580                .get(&server_id)
 2581                .and_then(|server_state| {
 2582                    if let LanguageServerState::Running { server, .. } = server_state {
 2583                        Some(server.clone())
 2584                    } else {
 2585                        None
 2586                    }
 2587                });
 2588            let server = match server {
 2589                Some(server) => server,
 2590                None => continue,
 2591            };
 2592
 2593            buffer_handle.update(cx, |buffer, cx| {
 2594                buffer.set_completion_triggers(
 2595                    server.server_id(),
 2596                    server
 2597                        .capabilities()
 2598                        .completion_provider
 2599                        .as_ref()
 2600                        .and_then(|provider| {
 2601                            provider
 2602                                .trigger_characters
 2603                                .as_ref()
 2604                                .map(|characters| characters.iter().cloned().collect())
 2605                        })
 2606                        .unwrap_or_default(),
 2607                    cx,
 2608                );
 2609            });
 2610        }
 2611    }
 2612
 2613    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2614        buffer.update(cx, |buffer, cx| {
 2615            let Some(language) = buffer.language() else {
 2616                return;
 2617            };
 2618            let path = ProjectPath {
 2619                worktree_id: old_file.worktree_id(cx),
 2620                path: old_file.path.clone(),
 2621            };
 2622            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2623                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2624                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2625            }
 2626        });
 2627    }
 2628
 2629    fn update_buffer_diagnostics(
 2630        &mut self,
 2631        buffer: &Entity<Buffer>,
 2632        server_id: LanguageServerId,
 2633        registration_id: Option<Option<SharedString>>,
 2634        result_id: Option<SharedString>,
 2635        version: Option<i32>,
 2636        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2637        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2638        cx: &mut Context<LspStore>,
 2639    ) -> Result<()> {
 2640        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2641            Ordering::Equal
 2642                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2643                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2644                .then_with(|| a.severity.cmp(&b.severity))
 2645                .then_with(|| a.message.cmp(&b.message))
 2646        }
 2647
 2648        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2649        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2650        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2651
 2652        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2653            Ordering::Equal
 2654                .then_with(|| a.range.start.cmp(&b.range.start))
 2655                .then_with(|| b.range.end.cmp(&a.range.end))
 2656                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2657        });
 2658
 2659        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2660
 2661        let edits_since_save = std::cell::LazyCell::new(|| {
 2662            let saved_version = buffer.read(cx).saved_version();
 2663            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2664        });
 2665
 2666        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2667
 2668        for (new_diagnostic, entry) in diagnostics {
 2669            let start;
 2670            let end;
 2671            if new_diagnostic && entry.diagnostic.is_disk_based {
 2672                // Some diagnostics are based on files on disk instead of buffers'
 2673                // current contents. Adjust these diagnostics' ranges to reflect
 2674                // any unsaved edits.
 2675                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2676                // and were properly adjusted on reuse.
 2677                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2678                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2679            } else {
 2680                start = entry.range.start;
 2681                end = entry.range.end;
 2682            }
 2683
 2684            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2685                ..snapshot.clip_point_utf16(end, Bias::Right);
 2686
 2687            // Expand empty ranges by one codepoint
 2688            if range.start == range.end {
 2689                // This will be go to the next boundary when being clipped
 2690                range.end.column += 1;
 2691                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2692                if range.start == range.end && range.end.column > 0 {
 2693                    range.start.column -= 1;
 2694                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2695                }
 2696            }
 2697
 2698            sanitized_diagnostics.push(DiagnosticEntry {
 2699                range,
 2700                diagnostic: entry.diagnostic,
 2701            });
 2702        }
 2703        drop(edits_since_save);
 2704
 2705        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2706        buffer.update(cx, |buffer, cx| {
 2707            if let Some(registration_id) = registration_id {
 2708                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2709                    self.buffer_pull_diagnostics_result_ids
 2710                        .entry(server_id)
 2711                        .or_default()
 2712                        .entry(registration_id)
 2713                        .or_default()
 2714                        .insert(abs_path, result_id);
 2715                }
 2716            }
 2717
 2718            buffer.update_diagnostics(server_id, set, cx)
 2719        });
 2720
 2721        Ok(())
 2722    }
 2723
 2724    fn register_language_server_for_invisible_worktree(
 2725        &mut self,
 2726        worktree: &Entity<Worktree>,
 2727        language_server_id: LanguageServerId,
 2728        cx: &mut App,
 2729    ) {
 2730        let worktree = worktree.read(cx);
 2731        let worktree_id = worktree.id();
 2732        debug_assert!(!worktree.is_visible());
 2733        let Some(mut origin_seed) = self
 2734            .language_server_ids
 2735            .iter()
 2736            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2737        else {
 2738            return;
 2739        };
 2740        origin_seed.worktree_id = worktree_id;
 2741        self.language_server_ids
 2742            .entry(origin_seed)
 2743            .or_insert_with(|| UnifiedLanguageServer {
 2744                id: language_server_id,
 2745                project_roots: Default::default(),
 2746            });
 2747    }
 2748
 2749    fn register_buffer_with_language_servers(
 2750        &mut self,
 2751        buffer_handle: &Entity<Buffer>,
 2752        only_register_servers: HashSet<LanguageServerSelector>,
 2753        cx: &mut Context<LspStore>,
 2754    ) {
 2755        if self.all_language_servers_stopped {
 2756            return;
 2757        }
 2758        let buffer = buffer_handle.read(cx);
 2759        let buffer_id = buffer.remote_id();
 2760
 2761        let Some(file) = File::from_dyn(buffer.file()) else {
 2762            return;
 2763        };
 2764        if !file.is_local() {
 2765            return;
 2766        }
 2767
 2768        let abs_path = file.abs_path(cx);
 2769        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2770            return;
 2771        };
 2772        let initial_snapshot = buffer.text_snapshot();
 2773        let worktree_id = file.worktree_id(cx);
 2774
 2775        let Some(language) = buffer.language().cloned() else {
 2776            return;
 2777        };
 2778        let path: Arc<RelPath> = file
 2779            .path()
 2780            .parent()
 2781            .map(Arc::from)
 2782            .unwrap_or_else(|| file.path().clone());
 2783        let Some(worktree) = self
 2784            .worktree_store
 2785            .read(cx)
 2786            .worktree_for_id(worktree_id, cx)
 2787        else {
 2788            return;
 2789        };
 2790        let language_name = language.name();
 2791        let (reused, delegate, servers) = self
 2792            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2793            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2794            .unwrap_or_else(|| {
 2795                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2796                let delegate: Arc<dyn ManifestDelegate> =
 2797                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2798
 2799                let servers = self
 2800                    .lsp_tree
 2801                    .walk(
 2802                        ProjectPath { worktree_id, path },
 2803                        language.name(),
 2804                        language.manifest(),
 2805                        &delegate,
 2806                        cx,
 2807                    )
 2808                    .collect::<Vec<_>>();
 2809                (false, lsp_delegate, servers)
 2810            });
 2811        let servers_and_adapters = servers
 2812            .into_iter()
 2813            .filter_map(|server_node| {
 2814                if reused && server_node.server_id().is_none() {
 2815                    return None;
 2816                }
 2817                if let Some(name) = server_node.name()
 2818                    && self.stopped_language_servers.contains(&name)
 2819                {
 2820                    return None;
 2821                }
 2822                if !only_register_servers.is_empty() {
 2823                    if let Some(server_id) = server_node.server_id()
 2824                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2825                    {
 2826                        return None;
 2827                    }
 2828                    if let Some(name) = server_node.name()
 2829                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2830                    {
 2831                        return None;
 2832                    }
 2833                }
 2834
 2835                let server_id = server_node.server_id_or_init(|disposition| {
 2836                    let path = &disposition.path;
 2837
 2838                    {
 2839                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2840
 2841                        let server_id = self.get_or_insert_language_server(
 2842                            &worktree,
 2843                            delegate.clone(),
 2844                            disposition,
 2845                            &language_name,
 2846                            cx,
 2847                        );
 2848
 2849                        if let Some(state) = self.language_servers.get(&server_id)
 2850                            && let Ok(uri) = uri
 2851                        {
 2852                            state.add_workspace_folder(uri);
 2853                        };
 2854                        server_id
 2855                    }
 2856                })?;
 2857                let server_state = self.language_servers.get(&server_id)?;
 2858                if let LanguageServerState::Running {
 2859                    server, adapter, ..
 2860                } = server_state
 2861                {
 2862                    Some((server.clone(), adapter.clone()))
 2863                } else {
 2864                    None
 2865                }
 2866            })
 2867            .collect::<Vec<_>>();
 2868        for (server, adapter) in servers_and_adapters {
 2869            buffer_handle.update(cx, |buffer, cx| {
 2870                buffer.set_completion_triggers(
 2871                    server.server_id(),
 2872                    server
 2873                        .capabilities()
 2874                        .completion_provider
 2875                        .as_ref()
 2876                        .and_then(|provider| {
 2877                            provider
 2878                                .trigger_characters
 2879                                .as_ref()
 2880                                .map(|characters| characters.iter().cloned().collect())
 2881                        })
 2882                        .unwrap_or_default(),
 2883                    cx,
 2884                );
 2885            });
 2886
 2887            let snapshot = LspBufferSnapshot {
 2888                version: 0,
 2889                snapshot: initial_snapshot.clone(),
 2890            };
 2891
 2892            let mut registered = false;
 2893            self.buffer_snapshots
 2894                .entry(buffer_id)
 2895                .or_default()
 2896                .entry(server.server_id())
 2897                .or_insert_with(|| {
 2898                    registered = true;
 2899                    server.register_buffer(
 2900                        uri.clone(),
 2901                        adapter.language_id(&language.name()),
 2902                        0,
 2903                        initial_snapshot.text(),
 2904                    );
 2905
 2906                    vec![snapshot]
 2907                });
 2908
 2909            self.buffers_opened_in_servers
 2910                .entry(buffer_id)
 2911                .or_default()
 2912                .insert(server.server_id());
 2913            if registered {
 2914                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2915                    language_server_id: server.server_id(),
 2916                    name: None,
 2917                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2918                        proto::RegisteredForBuffer {
 2919                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2920                            buffer_id: buffer_id.to_proto(),
 2921                        },
 2922                    ),
 2923                });
 2924            }
 2925        }
 2926    }
 2927
 2928    fn reuse_existing_language_server<'lang_name>(
 2929        &self,
 2930        server_tree: &LanguageServerTree,
 2931        worktree: &Entity<Worktree>,
 2932        language_name: &'lang_name LanguageName,
 2933        cx: &mut App,
 2934    ) -> Option<(
 2935        Arc<LocalLspAdapterDelegate>,
 2936        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2937    )> {
 2938        if worktree.read(cx).is_visible() {
 2939            return None;
 2940        }
 2941
 2942        let worktree_store = self.worktree_store.read(cx);
 2943        let servers = server_tree
 2944            .instances
 2945            .iter()
 2946            .filter(|(worktree_id, _)| {
 2947                worktree_store
 2948                    .worktree_for_id(**worktree_id, cx)
 2949                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2950            })
 2951            .flat_map(|(worktree_id, servers)| {
 2952                servers
 2953                    .roots
 2954                    .iter()
 2955                    .flat_map(|(_, language_servers)| language_servers)
 2956                    .map(move |(_, (server_node, server_languages))| {
 2957                        (worktree_id, server_node, server_languages)
 2958                    })
 2959                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2960                    .map(|(worktree_id, server_node, _)| {
 2961                        (
 2962                            *worktree_id,
 2963                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2964                        )
 2965                    })
 2966            })
 2967            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2968                acc.entry(worktree_id)
 2969                    .or_insert_with(Vec::new)
 2970                    .push(server_node);
 2971                acc
 2972            })
 2973            .into_values()
 2974            .max_by_key(|servers| servers.len())?;
 2975
 2976        let worktree_id = worktree.read(cx).id();
 2977        let apply = move |tree: &mut LanguageServerTree| {
 2978            for server_node in &servers {
 2979                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2980            }
 2981            servers
 2982        };
 2983
 2984        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2985        Some((delegate, apply))
 2986    }
 2987
 2988    pub(crate) fn unregister_old_buffer_from_language_servers(
 2989        &mut self,
 2990        buffer: &Entity<Buffer>,
 2991        old_file: &File,
 2992        cx: &mut App,
 2993    ) {
 2994        let old_path = match old_file.as_local() {
 2995            Some(local) => local.abs_path(cx),
 2996            None => return,
 2997        };
 2998
 2999        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 3000            debug_panic!("{old_path:?} is not parseable as an URI");
 3001            return;
 3002        };
 3003        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 3004    }
 3005
 3006    pub(crate) fn unregister_buffer_from_language_servers(
 3007        &mut self,
 3008        buffer: &Entity<Buffer>,
 3009        file_url: &lsp::Uri,
 3010        cx: &mut App,
 3011    ) {
 3012        buffer.update(cx, |buffer, cx| {
 3013            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3014
 3015            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3016                if snapshots
 3017                    .as_mut()
 3018                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3019                {
 3020                    language_server.unregister_buffer(file_url.clone());
 3021                }
 3022            }
 3023        });
 3024    }
 3025
 3026    fn buffer_snapshot_for_lsp_version(
 3027        &mut self,
 3028        buffer: &Entity<Buffer>,
 3029        server_id: LanguageServerId,
 3030        version: Option<i32>,
 3031        cx: &App,
 3032    ) -> Result<TextBufferSnapshot> {
 3033        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3034
 3035        if let Some(version) = version {
 3036            let buffer_id = buffer.read(cx).remote_id();
 3037            let snapshots = if let Some(snapshots) = self
 3038                .buffer_snapshots
 3039                .get_mut(&buffer_id)
 3040                .and_then(|m| m.get_mut(&server_id))
 3041            {
 3042                snapshots
 3043            } else if version == 0 {
 3044                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3045                // We detect this case and treat it as if the version was `None`.
 3046                return Ok(buffer.read(cx).text_snapshot());
 3047            } else {
 3048                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3049            };
 3050
 3051            let found_snapshot = snapshots
 3052                    .binary_search_by_key(&version, |e| e.version)
 3053                    .map(|ix| snapshots[ix].snapshot.clone())
 3054                    .map_err(|_| {
 3055                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3056                    })?;
 3057
 3058            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3059            Ok(found_snapshot)
 3060        } else {
 3061            Ok((buffer.read(cx)).text_snapshot())
 3062        }
 3063    }
 3064
 3065    async fn get_server_code_actions_from_action_kinds(
 3066        lsp_store: &WeakEntity<LspStore>,
 3067        language_server_id: LanguageServerId,
 3068        code_action_kinds: Vec<lsp::CodeActionKind>,
 3069        buffer: &Entity<Buffer>,
 3070        cx: &mut AsyncApp,
 3071    ) -> Result<Vec<CodeAction>> {
 3072        let actions = lsp_store
 3073            .update(cx, move |this, cx| {
 3074                let request = GetCodeActions {
 3075                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3076                    kinds: Some(code_action_kinds),
 3077                };
 3078                let server = LanguageServerToQuery::Other(language_server_id);
 3079                this.request_lsp(buffer.clone(), server, request, cx)
 3080            })?
 3081            .await?;
 3082        Ok(actions)
 3083    }
 3084
 3085    pub async fn execute_code_actions_on_server(
 3086        lsp_store: &WeakEntity<LspStore>,
 3087        language_server: &Arc<LanguageServer>,
 3088        actions: Vec<CodeAction>,
 3089        push_to_history: bool,
 3090        project_transaction: &mut ProjectTransaction,
 3091        cx: &mut AsyncApp,
 3092    ) -> anyhow::Result<()> {
 3093        let request_timeout = cx.update(|app| {
 3094            ProjectSettings::get_global(app)
 3095                .global_lsp_settings
 3096                .get_request_timeout()
 3097        });
 3098
 3099        for mut action in actions {
 3100            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3101                .await
 3102                .context("resolving a formatting code action")?;
 3103
 3104            if let Some(edit) = action.lsp_action.edit() {
 3105                if edit.changes.is_none() && edit.document_changes.is_none() {
 3106                    continue;
 3107                }
 3108
 3109                let new = Self::deserialize_workspace_edit(
 3110                    lsp_store.upgrade().context("project dropped")?,
 3111                    edit.clone(),
 3112                    push_to_history,
 3113                    language_server.clone(),
 3114                    cx,
 3115                )
 3116                .await?;
 3117                project_transaction.0.extend(new.0);
 3118            }
 3119
 3120            let Some(command) = action.lsp_action.command() else {
 3121                continue;
 3122            };
 3123
 3124            let server_capabilities = language_server.capabilities();
 3125            let available_commands = server_capabilities
 3126                .execute_command_provider
 3127                .as_ref()
 3128                .map(|options| options.commands.as_slice())
 3129                .unwrap_or_default();
 3130            if !available_commands.contains(&command.command) {
 3131                log::warn!(
 3132                    "Cannot execute a command {} not listed in the language server capabilities",
 3133                    command.command
 3134                );
 3135                continue;
 3136            }
 3137
 3138            lsp_store.update(cx, |lsp_store, _| {
 3139                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3140                    mode.last_workspace_edits_by_language_server
 3141                        .remove(&language_server.server_id());
 3142                }
 3143            })?;
 3144
 3145            language_server
 3146                .request::<lsp::request::ExecuteCommand>(
 3147                    lsp::ExecuteCommandParams {
 3148                        command: command.command.clone(),
 3149                        arguments: command.arguments.clone().unwrap_or_default(),
 3150                        ..Default::default()
 3151                    },
 3152                    request_timeout,
 3153                )
 3154                .await
 3155                .into_response()
 3156                .context("execute command")?;
 3157
 3158            lsp_store.update(cx, |this, _| {
 3159                if let LspStoreMode::Local(mode) = &mut this.mode {
 3160                    project_transaction.0.extend(
 3161                        mode.last_workspace_edits_by_language_server
 3162                            .remove(&language_server.server_id())
 3163                            .unwrap_or_default()
 3164                            .0,
 3165                    )
 3166                }
 3167            })?;
 3168        }
 3169        Ok(())
 3170    }
 3171
 3172    pub async fn deserialize_text_edits(
 3173        this: Entity<LspStore>,
 3174        buffer_to_edit: Entity<Buffer>,
 3175        edits: Vec<lsp::TextEdit>,
 3176        push_to_history: bool,
 3177        _: Arc<CachedLspAdapter>,
 3178        language_server: Arc<LanguageServer>,
 3179        cx: &mut AsyncApp,
 3180    ) -> Result<Option<Transaction>> {
 3181        let edits = this
 3182            .update(cx, |this, cx| {
 3183                this.as_local_mut().unwrap().edits_from_lsp(
 3184                    &buffer_to_edit,
 3185                    edits,
 3186                    language_server.server_id(),
 3187                    None,
 3188                    cx,
 3189                )
 3190            })
 3191            .await?;
 3192
 3193        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3194            buffer.finalize_last_transaction();
 3195            buffer.start_transaction();
 3196            for (range, text) in edits {
 3197                buffer.edit([(range, text)], None, cx);
 3198            }
 3199
 3200            if buffer.end_transaction(cx).is_some() {
 3201                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3202                if !push_to_history {
 3203                    buffer.forget_transaction(transaction.id);
 3204                }
 3205                Some(transaction)
 3206            } else {
 3207                None
 3208            }
 3209        });
 3210
 3211        Ok(transaction)
 3212    }
 3213
 3214    #[allow(clippy::type_complexity)]
 3215    pub fn edits_from_lsp(
 3216        &mut self,
 3217        buffer: &Entity<Buffer>,
 3218        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3219        server_id: LanguageServerId,
 3220        version: Option<i32>,
 3221        cx: &mut Context<LspStore>,
 3222    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3223        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3224        cx.background_spawn(async move {
 3225            let snapshot = snapshot?;
 3226            let mut lsp_edits = lsp_edits
 3227                .into_iter()
 3228                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3229                .collect::<Vec<_>>();
 3230
 3231            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3232
 3233            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3234            let mut edits = Vec::new();
 3235            while let Some((range, mut new_text)) = lsp_edits.next() {
 3236                // Clip invalid ranges provided by the language server.
 3237                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3238                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3239
 3240                // Combine any LSP edits that are adjacent.
 3241                //
 3242                // Also, combine LSP edits that are separated from each other by only
 3243                // a newline. This is important because for some code actions,
 3244                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3245                // are separated by unchanged newline characters.
 3246                //
 3247                // In order for the diffing logic below to work properly, any edits that
 3248                // cancel each other out must be combined into one.
 3249                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3250                    if next_range.start.0 > range.end {
 3251                        if next_range.start.0.row > range.end.row + 1
 3252                            || next_range.start.0.column > 0
 3253                            || snapshot.clip_point_utf16(
 3254                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3255                                Bias::Left,
 3256                            ) > range.end
 3257                        {
 3258                            break;
 3259                        }
 3260                        new_text.push('\n');
 3261                    }
 3262                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3263                    new_text.push_str(next_text);
 3264                    lsp_edits.next();
 3265                }
 3266
 3267                // For multiline edits, perform a diff of the old and new text so that
 3268                // we can identify the changes more precisely, preserving the locations
 3269                // of any anchors positioned in the unchanged regions.
 3270                if range.end.row > range.start.row {
 3271                    let offset = range.start.to_offset(&snapshot);
 3272                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3273                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3274                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3275                        (
 3276                            snapshot.anchor_after(offset + range.start)
 3277                                ..snapshot.anchor_before(offset + range.end),
 3278                            replacement,
 3279                        )
 3280                    }));
 3281                } else if range.end == range.start {
 3282                    let anchor = snapshot.anchor_after(range.start);
 3283                    edits.push((anchor..anchor, new_text.into()));
 3284                } else {
 3285                    let edit_start = snapshot.anchor_after(range.start);
 3286                    let edit_end = snapshot.anchor_before(range.end);
 3287                    edits.push((edit_start..edit_end, new_text.into()));
 3288                }
 3289            }
 3290
 3291            Ok(edits)
 3292        })
 3293    }
 3294
 3295    pub(crate) async fn deserialize_workspace_edit(
 3296        this: Entity<LspStore>,
 3297        edit: lsp::WorkspaceEdit,
 3298        push_to_history: bool,
 3299        language_server: Arc<LanguageServer>,
 3300        cx: &mut AsyncApp,
 3301    ) -> Result<ProjectTransaction> {
 3302        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3303
 3304        let mut operations = Vec::new();
 3305        if let Some(document_changes) = edit.document_changes {
 3306            match document_changes {
 3307                lsp::DocumentChanges::Edits(edits) => {
 3308                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3309                }
 3310                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3311            }
 3312        } else if let Some(changes) = edit.changes {
 3313            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3314                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3315                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3316                        uri,
 3317                        version: None,
 3318                    },
 3319                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3320                })
 3321            }));
 3322        }
 3323
 3324        let mut project_transaction = ProjectTransaction::default();
 3325        for operation in operations {
 3326            match operation {
 3327                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3328                    let abs_path = op
 3329                        .uri
 3330                        .to_file_path()
 3331                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3332
 3333                    if let Some(parent_path) = abs_path.parent() {
 3334                        fs.create_dir(parent_path).await?;
 3335                    }
 3336                    if abs_path.ends_with("/") {
 3337                        fs.create_dir(&abs_path).await?;
 3338                    } else {
 3339                        fs.create_file(
 3340                            &abs_path,
 3341                            op.options
 3342                                .map(|options| fs::CreateOptions {
 3343                                    overwrite: options.overwrite.unwrap_or(false),
 3344                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3345                                })
 3346                                .unwrap_or_default(),
 3347                        )
 3348                        .await?;
 3349                    }
 3350                }
 3351
 3352                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3353                    let source_abs_path = op
 3354                        .old_uri
 3355                        .to_file_path()
 3356                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3357                    let target_abs_path = op
 3358                        .new_uri
 3359                        .to_file_path()
 3360                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3361
 3362                    let options = fs::RenameOptions {
 3363                        overwrite: op
 3364                            .options
 3365                            .as_ref()
 3366                            .and_then(|options| options.overwrite)
 3367                            .unwrap_or(false),
 3368                        ignore_if_exists: op
 3369                            .options
 3370                            .as_ref()
 3371                            .and_then(|options| options.ignore_if_exists)
 3372                            .unwrap_or(false),
 3373                        create_parents: true,
 3374                    };
 3375
 3376                    fs.rename(&source_abs_path, &target_abs_path, options)
 3377                        .await?;
 3378                }
 3379
 3380                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3381                    let abs_path = op
 3382                        .uri
 3383                        .to_file_path()
 3384                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3385                    let options = op
 3386                        .options
 3387                        .map(|options| fs::RemoveOptions {
 3388                            recursive: options.recursive.unwrap_or(false),
 3389                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3390                        })
 3391                        .unwrap_or_default();
 3392                    if abs_path.ends_with("/") {
 3393                        fs.remove_dir(&abs_path, options).await?;
 3394                    } else {
 3395                        fs.remove_file(&abs_path, options).await?;
 3396                    }
 3397                }
 3398
 3399                lsp::DocumentChangeOperation::Edit(op) => {
 3400                    let buffer_to_edit = this
 3401                        .update(cx, |this, cx| {
 3402                            this.open_local_buffer_via_lsp(
 3403                                op.text_document.uri.clone(),
 3404                                language_server.server_id(),
 3405                                cx,
 3406                            )
 3407                        })
 3408                        .await?;
 3409
 3410                    let edits = this
 3411                        .update(cx, |this, cx| {
 3412                            let path = buffer_to_edit.read(cx).project_path(cx);
 3413                            let active_entry = this.active_entry;
 3414                            let is_active_entry = path.is_some_and(|project_path| {
 3415                                this.worktree_store
 3416                                    .read(cx)
 3417                                    .entry_for_path(&project_path, cx)
 3418                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3419                            });
 3420                            let local = this.as_local_mut().unwrap();
 3421
 3422                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3423                            for edit in op.edits {
 3424                                match edit {
 3425                                    Edit::Plain(edit) => {
 3426                                        if !edits.contains(&edit) {
 3427                                            edits.push(edit)
 3428                                        }
 3429                                    }
 3430                                    Edit::Annotated(edit) => {
 3431                                        if !edits.contains(&edit.text_edit) {
 3432                                            edits.push(edit.text_edit)
 3433                                        }
 3434                                    }
 3435                                    Edit::Snippet(edit) => {
 3436                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3437                                        else {
 3438                                            continue;
 3439                                        };
 3440
 3441                                        if is_active_entry {
 3442                                            snippet_edits.push((edit.range, snippet));
 3443                                        } else {
 3444                                            // Since this buffer is not focused, apply a normal edit.
 3445                                            let new_edit = TextEdit {
 3446                                                range: edit.range,
 3447                                                new_text: snippet.text,
 3448                                            };
 3449                                            if !edits.contains(&new_edit) {
 3450                                                edits.push(new_edit);
 3451                                            }
 3452                                        }
 3453                                    }
 3454                                }
 3455                            }
 3456                            if !snippet_edits.is_empty() {
 3457                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3458                                let version = if let Some(buffer_version) = op.text_document.version
 3459                                {
 3460                                    local
 3461                                        .buffer_snapshot_for_lsp_version(
 3462                                            &buffer_to_edit,
 3463                                            language_server.server_id(),
 3464                                            Some(buffer_version),
 3465                                            cx,
 3466                                        )
 3467                                        .ok()
 3468                                        .map(|snapshot| snapshot.version)
 3469                                } else {
 3470                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3471                                };
 3472
 3473                                let most_recent_edit =
 3474                                    version.and_then(|version| version.most_recent());
 3475                                // Check if the edit that triggered that edit has been made by this participant.
 3476
 3477                                if let Some(most_recent_edit) = most_recent_edit {
 3478                                    cx.emit(LspStoreEvent::SnippetEdit {
 3479                                        buffer_id,
 3480                                        edits: snippet_edits,
 3481                                        most_recent_edit,
 3482                                    });
 3483                                }
 3484                            }
 3485
 3486                            local.edits_from_lsp(
 3487                                &buffer_to_edit,
 3488                                edits,
 3489                                language_server.server_id(),
 3490                                op.text_document.version,
 3491                                cx,
 3492                            )
 3493                        })
 3494                        .await?;
 3495
 3496                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3497                        buffer.finalize_last_transaction();
 3498                        buffer.start_transaction();
 3499                        for (range, text) in edits {
 3500                            buffer.edit([(range, text)], None, cx);
 3501                        }
 3502
 3503                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3504                            if push_to_history {
 3505                                buffer.finalize_last_transaction();
 3506                                buffer.get_transaction(transaction_id).cloned()
 3507                            } else {
 3508                                buffer.forget_transaction(transaction_id)
 3509                            }
 3510                        })
 3511                    });
 3512                    if let Some(transaction) = transaction {
 3513                        project_transaction.0.insert(buffer_to_edit, transaction);
 3514                    }
 3515                }
 3516            }
 3517        }
 3518
 3519        Ok(project_transaction)
 3520    }
 3521
 3522    async fn on_lsp_workspace_edit(
 3523        this: WeakEntity<LspStore>,
 3524        params: lsp::ApplyWorkspaceEditParams,
 3525        server_id: LanguageServerId,
 3526        cx: &mut AsyncApp,
 3527    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3528        let this = this.upgrade().context("project project closed")?;
 3529        let language_server = this
 3530            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3531            .context("language server not found")?;
 3532        let transaction = Self::deserialize_workspace_edit(
 3533            this.clone(),
 3534            params.edit,
 3535            true,
 3536            language_server.clone(),
 3537            cx,
 3538        )
 3539        .await
 3540        .log_err();
 3541        this.update(cx, |this, cx| {
 3542            if let Some(transaction) = transaction {
 3543                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3544
 3545                this.as_local_mut()
 3546                    .unwrap()
 3547                    .last_workspace_edits_by_language_server
 3548                    .insert(server_id, transaction);
 3549            }
 3550        });
 3551        Ok(lsp::ApplyWorkspaceEditResponse {
 3552            applied: true,
 3553            failed_change: None,
 3554            failure_reason: None,
 3555        })
 3556    }
 3557
 3558    fn remove_worktree(
 3559        &mut self,
 3560        id_to_remove: WorktreeId,
 3561        cx: &mut Context<LspStore>,
 3562    ) -> Vec<LanguageServerId> {
 3563        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3564        self.diagnostics.remove(&id_to_remove);
 3565        self.prettier_store.update(cx, |prettier_store, cx| {
 3566            prettier_store.remove_worktree(id_to_remove, cx);
 3567        });
 3568
 3569        let mut servers_to_remove = BTreeSet::default();
 3570        let mut servers_to_preserve = HashSet::default();
 3571        for (seed, state) in &self.language_server_ids {
 3572            if seed.worktree_id == id_to_remove {
 3573                servers_to_remove.insert(state.id);
 3574            } else {
 3575                servers_to_preserve.insert(state.id);
 3576            }
 3577        }
 3578        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3579        self.language_server_ids
 3580            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3581        for server_id_to_remove in &servers_to_remove {
 3582            self.language_server_watched_paths
 3583                .remove(server_id_to_remove);
 3584            self.language_server_paths_watched_for_rename
 3585                .remove(server_id_to_remove);
 3586            self.last_workspace_edits_by_language_server
 3587                .remove(server_id_to_remove);
 3588            self.language_servers.remove(server_id_to_remove);
 3589            self.buffer_pull_diagnostics_result_ids
 3590                .remove(server_id_to_remove);
 3591            self.workspace_pull_diagnostics_result_ids
 3592                .remove(server_id_to_remove);
 3593            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3594                buffer_servers.remove(server_id_to_remove);
 3595            }
 3596            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3597        }
 3598        servers_to_remove.into_iter().collect()
 3599    }
 3600
 3601    fn rebuild_watched_paths_inner<'a>(
 3602        &'a self,
 3603        language_server_id: LanguageServerId,
 3604        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3605        cx: &mut Context<LspStore>,
 3606    ) -> LanguageServerWatchedPathsBuilder {
 3607        let worktrees = self
 3608            .worktree_store
 3609            .read(cx)
 3610            .worktrees()
 3611            .filter_map(|worktree| {
 3612                self.language_servers_for_worktree(worktree.read(cx).id())
 3613                    .find(|server| server.server_id() == language_server_id)
 3614                    .map(|_| worktree)
 3615            })
 3616            .collect::<Vec<_>>();
 3617
 3618        let mut worktree_globs = HashMap::default();
 3619        let mut abs_globs = HashMap::default();
 3620        log::trace!(
 3621            "Processing new watcher paths for language server with id {}",
 3622            language_server_id
 3623        );
 3624
 3625        for watcher in watchers {
 3626            if let Some((worktree, literal_prefix, pattern)) =
 3627                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3628            {
 3629                worktree.update(cx, |worktree, _| {
 3630                    if let Some((tree, glob)) =
 3631                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3632                    {
 3633                        tree.add_path_prefix_to_scan(literal_prefix);
 3634                        worktree_globs
 3635                            .entry(tree.id())
 3636                            .or_insert_with(GlobSetBuilder::new)
 3637                            .add(glob);
 3638                    }
 3639                });
 3640            } else {
 3641                let (path, pattern) = match &watcher.glob_pattern {
 3642                    lsp::GlobPattern::String(s) => {
 3643                        let watcher_path = SanitizedPath::new(s);
 3644                        let path = glob_literal_prefix(watcher_path.as_path());
 3645                        let pattern = watcher_path
 3646                            .as_path()
 3647                            .strip_prefix(&path)
 3648                            .map(|p| p.to_string_lossy().into_owned())
 3649                            .unwrap_or_else(|e| {
 3650                                debug_panic!(
 3651                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3652                                    s,
 3653                                    path.display(),
 3654                                    e
 3655                                );
 3656                                watcher_path.as_path().to_string_lossy().into_owned()
 3657                            });
 3658                        (path, pattern)
 3659                    }
 3660                    lsp::GlobPattern::Relative(rp) => {
 3661                        let Ok(mut base_uri) = match &rp.base_uri {
 3662                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3663                            lsp::OneOf::Right(base_uri) => base_uri,
 3664                        }
 3665                        .to_file_path() else {
 3666                            continue;
 3667                        };
 3668
 3669                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3670                        let pattern = Path::new(&rp.pattern)
 3671                            .strip_prefix(&path)
 3672                            .map(|p| p.to_string_lossy().into_owned())
 3673                            .unwrap_or_else(|e| {
 3674                                debug_panic!(
 3675                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3676                                    rp.pattern,
 3677                                    path.display(),
 3678                                    e
 3679                                );
 3680                                rp.pattern.clone()
 3681                            });
 3682                        base_uri.push(path);
 3683                        (base_uri, pattern)
 3684                    }
 3685                };
 3686
 3687                if let Some(glob) = Glob::new(&pattern).log_err() {
 3688                    if !path
 3689                        .components()
 3690                        .any(|c| matches!(c, path::Component::Normal(_)))
 3691                    {
 3692                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3693                        // rather than adding a new watcher for `/`.
 3694                        for worktree in &worktrees {
 3695                            worktree_globs
 3696                                .entry(worktree.read(cx).id())
 3697                                .or_insert_with(GlobSetBuilder::new)
 3698                                .add(glob.clone());
 3699                        }
 3700                    } else {
 3701                        abs_globs
 3702                            .entry(path.into())
 3703                            .or_insert_with(GlobSetBuilder::new)
 3704                            .add(glob);
 3705                    }
 3706                }
 3707            }
 3708        }
 3709
 3710        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3711        for (worktree_id, builder) in worktree_globs {
 3712            if let Ok(globset) = builder.build() {
 3713                watch_builder.watch_worktree(worktree_id, globset);
 3714            }
 3715        }
 3716        for (abs_path, builder) in abs_globs {
 3717            if let Ok(globset) = builder.build() {
 3718                watch_builder.watch_abs_path(abs_path, globset);
 3719            }
 3720        }
 3721        watch_builder
 3722    }
 3723
 3724    fn worktree_and_path_for_file_watcher(
 3725        worktrees: &[Entity<Worktree>],
 3726        watcher: &FileSystemWatcher,
 3727        cx: &App,
 3728    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3729        worktrees.iter().find_map(|worktree| {
 3730            let tree = worktree.read(cx);
 3731            let worktree_root_path = tree.abs_path();
 3732            let path_style = tree.path_style();
 3733            match &watcher.glob_pattern {
 3734                lsp::GlobPattern::String(s) => {
 3735                    let watcher_path = SanitizedPath::new(s);
 3736                    let relative = watcher_path
 3737                        .as_path()
 3738                        .strip_prefix(&worktree_root_path)
 3739                        .ok()?;
 3740                    let literal_prefix = glob_literal_prefix(relative);
 3741                    Some((
 3742                        worktree.clone(),
 3743                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3744                        relative.to_string_lossy().into_owned(),
 3745                    ))
 3746                }
 3747                lsp::GlobPattern::Relative(rp) => {
 3748                    let base_uri = match &rp.base_uri {
 3749                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3750                        lsp::OneOf::Right(base_uri) => base_uri,
 3751                    }
 3752                    .to_file_path()
 3753                    .ok()?;
 3754                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3755                    let mut literal_prefix = relative.to_owned();
 3756                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3757                    Some((
 3758                        worktree.clone(),
 3759                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3760                        rp.pattern.clone(),
 3761                    ))
 3762                }
 3763            }
 3764        })
 3765    }
 3766
 3767    fn rebuild_watched_paths(
 3768        &mut self,
 3769        language_server_id: LanguageServerId,
 3770        cx: &mut Context<LspStore>,
 3771    ) {
 3772        let Some(registrations) = self
 3773            .language_server_dynamic_registrations
 3774            .get(&language_server_id)
 3775        else {
 3776            return;
 3777        };
 3778
 3779        let watch_builder = self.rebuild_watched_paths_inner(
 3780            language_server_id,
 3781            registrations.did_change_watched_files.values().flatten(),
 3782            cx,
 3783        );
 3784        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3785        self.language_server_watched_paths
 3786            .insert(language_server_id, watcher);
 3787
 3788        cx.notify();
 3789    }
 3790
 3791    fn on_lsp_did_change_watched_files(
 3792        &mut self,
 3793        language_server_id: LanguageServerId,
 3794        registration_id: &str,
 3795        params: DidChangeWatchedFilesRegistrationOptions,
 3796        cx: &mut Context<LspStore>,
 3797    ) {
 3798        let registrations = self
 3799            .language_server_dynamic_registrations
 3800            .entry(language_server_id)
 3801            .or_default();
 3802
 3803        registrations
 3804            .did_change_watched_files
 3805            .insert(registration_id.to_string(), params.watchers);
 3806
 3807        self.rebuild_watched_paths(language_server_id, cx);
 3808    }
 3809
 3810    fn on_lsp_unregister_did_change_watched_files(
 3811        &mut self,
 3812        language_server_id: LanguageServerId,
 3813        registration_id: &str,
 3814        cx: &mut Context<LspStore>,
 3815    ) {
 3816        let registrations = self
 3817            .language_server_dynamic_registrations
 3818            .entry(language_server_id)
 3819            .or_default();
 3820
 3821        if registrations
 3822            .did_change_watched_files
 3823            .remove(registration_id)
 3824            .is_some()
 3825        {
 3826            log::info!(
 3827                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3828                language_server_id,
 3829                registration_id
 3830            );
 3831        } else {
 3832            log::warn!(
 3833                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3834                language_server_id,
 3835                registration_id
 3836            );
 3837        }
 3838
 3839        self.rebuild_watched_paths(language_server_id, cx);
 3840    }
 3841
 3842    async fn initialization_options_for_adapter(
 3843        adapter: Arc<dyn LspAdapter>,
 3844        delegate: &Arc<dyn LspAdapterDelegate>,
 3845        cx: &mut AsyncApp,
 3846    ) -> Result<Option<serde_json::Value>> {
 3847        let Some(mut initialization_config) =
 3848            adapter.clone().initialization_options(delegate, cx).await?
 3849        else {
 3850            return Ok(None);
 3851        };
 3852
 3853        for other_adapter in delegate.registered_lsp_adapters() {
 3854            if other_adapter.name() == adapter.name() {
 3855                continue;
 3856            }
 3857            if let Ok(Some(target_config)) = other_adapter
 3858                .clone()
 3859                .additional_initialization_options(adapter.name(), delegate)
 3860                .await
 3861            {
 3862                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3863            }
 3864        }
 3865
 3866        Ok(Some(initialization_config))
 3867    }
 3868
 3869    async fn workspace_configuration_for_adapter(
 3870        adapter: Arc<dyn LspAdapter>,
 3871        delegate: &Arc<dyn LspAdapterDelegate>,
 3872        toolchain: Option<Toolchain>,
 3873        requested_uri: Option<Uri>,
 3874        cx: &mut AsyncApp,
 3875    ) -> Result<serde_json::Value> {
 3876        let mut workspace_config = adapter
 3877            .clone()
 3878            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3879            .await?;
 3880
 3881        for other_adapter in delegate.registered_lsp_adapters() {
 3882            if other_adapter.name() == adapter.name() {
 3883                continue;
 3884            }
 3885            if let Ok(Some(target_config)) = other_adapter
 3886                .clone()
 3887                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3888                .await
 3889            {
 3890                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3891            }
 3892        }
 3893
 3894        Ok(workspace_config)
 3895    }
 3896
 3897    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3898        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3899            Some(server.clone())
 3900        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3901            Some(Arc::clone(server))
 3902        } else {
 3903            None
 3904        }
 3905    }
 3906}
 3907
 3908fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3909    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3910        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3911            language_server_id: server.server_id(),
 3912            name: Some(server.name()),
 3913            message: proto::update_language_server::Variant::MetadataUpdated(
 3914                proto::ServerMetadataUpdated {
 3915                    capabilities: Some(capabilities),
 3916                    binary: Some(proto::LanguageServerBinaryInfo {
 3917                        path: server.binary().path.to_string_lossy().into_owned(),
 3918                        arguments: server
 3919                            .binary()
 3920                            .arguments
 3921                            .iter()
 3922                            .map(|arg| arg.to_string_lossy().into_owned())
 3923                            .collect(),
 3924                    }),
 3925                    configuration: serde_json::to_string(server.configuration()).ok(),
 3926                    workspace_folders: server
 3927                        .workspace_folders()
 3928                        .iter()
 3929                        .map(|uri| uri.to_string())
 3930                        .collect(),
 3931                },
 3932            ),
 3933        });
 3934    }
 3935}
 3936
 3937#[derive(Debug)]
 3938pub struct FormattableBuffer {
 3939    handle: Entity<Buffer>,
 3940    abs_path: Option<PathBuf>,
 3941    env: Option<HashMap<String, String>>,
 3942    ranges: Option<Vec<Range<Anchor>>>,
 3943}
 3944
 3945pub struct RemoteLspStore {
 3946    upstream_client: Option<AnyProtoClient>,
 3947    upstream_project_id: u64,
 3948}
 3949
 3950pub(crate) enum LspStoreMode {
 3951    Local(LocalLspStore),   // ssh host and collab host
 3952    Remote(RemoteLspStore), // collab guest
 3953}
 3954
 3955impl LspStoreMode {
 3956    fn is_local(&self) -> bool {
 3957        matches!(self, LspStoreMode::Local(_))
 3958    }
 3959}
 3960
 3961pub struct LspStore {
 3962    mode: LspStoreMode,
 3963    last_formatting_failure: Option<String>,
 3964    downstream_client: Option<(AnyProtoClient, u64)>,
 3965    nonce: u128,
 3966    buffer_store: Entity<BufferStore>,
 3967    worktree_store: Entity<WorktreeStore>,
 3968    pub languages: Arc<LanguageRegistry>,
 3969    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3970    active_entry: Option<ProjectEntryId>,
 3971    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3972    _maintain_buffer_languages: Task<()>,
 3973    diagnostic_summaries:
 3974        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3975    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3976    semantic_token_config: SemanticTokenConfig,
 3977    lsp_data: HashMap<BufferId, BufferLspData>,
 3978    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3979    next_hint_id: Arc<AtomicUsize>,
 3980}
 3981
 3982#[derive(Debug)]
 3983pub struct BufferLspData {
 3984    buffer_version: Global,
 3985    document_colors: Option<DocumentColorData>,
 3986    code_lens: Option<CodeLensData>,
 3987    semantic_tokens: Option<SemanticTokensData>,
 3988    folding_ranges: Option<FoldingRangeData>,
 3989    document_symbols: Option<DocumentSymbolsData>,
 3990    inlay_hints: BufferInlayHints,
 3991    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3992    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3993}
 3994
 3995#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3996struct LspKey {
 3997    request_type: TypeId,
 3998    server_queried: Option<LanguageServerId>,
 3999}
 4000
 4001impl BufferLspData {
 4002    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 4003        Self {
 4004            buffer_version: buffer.read(cx).version(),
 4005            document_colors: None,
 4006            code_lens: None,
 4007            semantic_tokens: None,
 4008            folding_ranges: None,
 4009            document_symbols: None,
 4010            inlay_hints: BufferInlayHints::new(buffer, cx),
 4011            lsp_requests: HashMap::default(),
 4012            chunk_lsp_requests: HashMap::default(),
 4013        }
 4014    }
 4015
 4016    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4017        if let Some(document_colors) = &mut self.document_colors {
 4018            document_colors.remove_server_data(for_server);
 4019        }
 4020
 4021        if let Some(code_lens) = &mut self.code_lens {
 4022            code_lens.remove_server_data(for_server);
 4023        }
 4024
 4025        self.inlay_hints.remove_server_data(for_server);
 4026
 4027        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4028            semantic_tokens.remove_server_data(for_server);
 4029        }
 4030
 4031        if let Some(folding_ranges) = &mut self.folding_ranges {
 4032            folding_ranges.ranges.remove(&for_server);
 4033        }
 4034
 4035        if let Some(document_symbols) = &mut self.document_symbols {
 4036            document_symbols.remove_server_data(for_server);
 4037        }
 4038    }
 4039
 4040    #[cfg(any(test, feature = "test-support"))]
 4041    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4042        &self.inlay_hints
 4043    }
 4044}
 4045
 4046#[derive(Debug)]
 4047pub enum LspStoreEvent {
 4048    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4049    LanguageServerRemoved(LanguageServerId),
 4050    LanguageServerUpdate {
 4051        language_server_id: LanguageServerId,
 4052        name: Option<LanguageServerName>,
 4053        message: proto::update_language_server::Variant,
 4054    },
 4055    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4056    LanguageServerPrompt(LanguageServerPromptRequest),
 4057    LanguageDetected {
 4058        buffer: Entity<Buffer>,
 4059        new_language: Option<Arc<Language>>,
 4060    },
 4061    Notification(String),
 4062    RefreshInlayHints {
 4063        server_id: LanguageServerId,
 4064        request_id: Option<usize>,
 4065    },
 4066    RefreshSemanticTokens {
 4067        server_id: LanguageServerId,
 4068        request_id: Option<usize>,
 4069    },
 4070    RefreshCodeLens,
 4071    DiagnosticsUpdated {
 4072        server_id: LanguageServerId,
 4073        paths: Vec<ProjectPath>,
 4074    },
 4075    DiskBasedDiagnosticsStarted {
 4076        language_server_id: LanguageServerId,
 4077    },
 4078    DiskBasedDiagnosticsFinished {
 4079        language_server_id: LanguageServerId,
 4080    },
 4081    SnippetEdit {
 4082        buffer_id: BufferId,
 4083        edits: Vec<(lsp::Range, Snippet)>,
 4084        most_recent_edit: clock::Lamport,
 4085    },
 4086    WorkspaceEditApplied(ProjectTransaction),
 4087}
 4088
 4089#[derive(Clone, Debug, Serialize)]
 4090pub struct LanguageServerStatus {
 4091    pub name: LanguageServerName,
 4092    pub server_version: Option<SharedString>,
 4093    pub server_readable_version: Option<SharedString>,
 4094    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4095    pub has_pending_diagnostic_updates: bool,
 4096    pub progress_tokens: HashSet<ProgressToken>,
 4097    pub worktree: Option<WorktreeId>,
 4098    pub binary: Option<LanguageServerBinary>,
 4099    pub configuration: Option<Value>,
 4100    pub workspace_folders: BTreeSet<Uri>,
 4101    pub process_id: Option<u32>,
 4102}
 4103
 4104#[derive(Clone, Debug)]
 4105struct CoreSymbol {
 4106    pub language_server_name: LanguageServerName,
 4107    pub source_worktree_id: WorktreeId,
 4108    pub source_language_server_id: LanguageServerId,
 4109    pub path: SymbolLocation,
 4110    pub name: String,
 4111    pub kind: lsp::SymbolKind,
 4112    pub range: Range<Unclipped<PointUtf16>>,
 4113    pub container_name: Option<String>,
 4114}
 4115
 4116#[derive(Clone, Debug, PartialEq, Eq)]
 4117pub enum SymbolLocation {
 4118    InProject(ProjectPath),
 4119    OutsideProject {
 4120        abs_path: Arc<Path>,
 4121        signature: [u8; 32],
 4122    },
 4123}
 4124
 4125impl SymbolLocation {
 4126    fn file_name(&self) -> Option<&str> {
 4127        match self {
 4128            Self::InProject(path) => path.path.file_name(),
 4129            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4130        }
 4131    }
 4132}
 4133
 4134impl LspStore {
 4135    pub fn init(client: &AnyProtoClient) {
 4136        client.add_entity_request_handler(Self::handle_lsp_query);
 4137        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4138        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4139        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4140        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4141        client.add_entity_message_handler(Self::handle_start_language_server);
 4142        client.add_entity_message_handler(Self::handle_update_language_server);
 4143        client.add_entity_message_handler(Self::handle_language_server_log);
 4144        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4145        client.add_entity_request_handler(Self::handle_format_buffers);
 4146        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4147        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4148        client.add_entity_request_handler(Self::handle_apply_code_action);
 4149        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4150        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4151        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4152        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4153        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4154        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4155        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4156        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4157        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4158        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4159        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4160        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4161        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4162        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4163        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4164        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4165        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4166        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4167
 4168        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4169        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4170        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4171        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4172        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4173        client.add_entity_request_handler(
 4174            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4175        );
 4176        client.add_entity_request_handler(
 4177            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4178        );
 4179        client.add_entity_request_handler(
 4180            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4181        );
 4182    }
 4183
 4184    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4185        match &self.mode {
 4186            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4187            _ => None,
 4188        }
 4189    }
 4190
 4191    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4192        match &self.mode {
 4193            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4194            _ => None,
 4195        }
 4196    }
 4197
 4198    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4199        match &mut self.mode {
 4200            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4201            _ => None,
 4202        }
 4203    }
 4204
 4205    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4206        match &self.mode {
 4207            LspStoreMode::Remote(RemoteLspStore {
 4208                upstream_client: Some(upstream_client),
 4209                upstream_project_id,
 4210                ..
 4211            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4212
 4213            LspStoreMode::Remote(RemoteLspStore {
 4214                upstream_client: None,
 4215                ..
 4216            }) => None,
 4217            LspStoreMode::Local(_) => None,
 4218        }
 4219    }
 4220
 4221    pub fn new_local(
 4222        buffer_store: Entity<BufferStore>,
 4223        worktree_store: Entity<WorktreeStore>,
 4224        prettier_store: Entity<PrettierStore>,
 4225        toolchain_store: Entity<LocalToolchainStore>,
 4226        environment: Entity<ProjectEnvironment>,
 4227        manifest_tree: Entity<ManifestTree>,
 4228        languages: Arc<LanguageRegistry>,
 4229        http_client: Arc<dyn HttpClient>,
 4230        fs: Arc<dyn Fs>,
 4231        cx: &mut Context<Self>,
 4232    ) -> Self {
 4233        let yarn = YarnPathStore::new(fs.clone(), cx);
 4234        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4235            .detach();
 4236        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4237            .detach();
 4238        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4239            .detach();
 4240        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4241            .detach();
 4242        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4243            .detach();
 4244        subscribe_to_binary_statuses(&languages, cx).detach();
 4245
 4246        let _maintain_workspace_config = {
 4247            let (sender, receiver) = watch::channel();
 4248            (Self::maintain_workspace_config(receiver, cx), sender)
 4249        };
 4250
 4251        Self {
 4252            mode: LspStoreMode::Local(LocalLspStore {
 4253                weak: cx.weak_entity(),
 4254                worktree_store: worktree_store.clone(),
 4255
 4256                supplementary_language_servers: Default::default(),
 4257                languages: languages.clone(),
 4258                language_server_ids: Default::default(),
 4259                language_servers: Default::default(),
 4260                last_workspace_edits_by_language_server: Default::default(),
 4261                language_server_watched_paths: Default::default(),
 4262                language_server_paths_watched_for_rename: Default::default(),
 4263                language_server_dynamic_registrations: Default::default(),
 4264                buffers_being_formatted: Default::default(),
 4265                buffers_to_refresh_hash_set: HashSet::default(),
 4266                buffers_to_refresh_queue: VecDeque::new(),
 4267                _background_diagnostics_worker: Task::ready(()).shared(),
 4268                buffer_snapshots: Default::default(),
 4269                prettier_store,
 4270                environment,
 4271                http_client,
 4272                fs,
 4273                yarn,
 4274                next_diagnostic_group_id: Default::default(),
 4275                diagnostics: Default::default(),
 4276                _subscription: cx.on_app_quit(|this, _| {
 4277                    this.as_local_mut()
 4278                        .unwrap()
 4279                        .shutdown_language_servers_on_quit()
 4280                }),
 4281                lsp_tree: LanguageServerTree::new(
 4282                    manifest_tree,
 4283                    languages.clone(),
 4284                    toolchain_store.clone(),
 4285                ),
 4286                toolchain_store,
 4287                registered_buffers: HashMap::default(),
 4288                buffers_opened_in_servers: HashMap::default(),
 4289                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4290                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4291                restricted_worktrees_tasks: HashMap::default(),
 4292                all_language_servers_stopped: false,
 4293                stopped_language_servers: HashSet::default(),
 4294                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4295                    .manifest_file_names(),
 4296            }),
 4297            last_formatting_failure: None,
 4298            downstream_client: None,
 4299            buffer_store,
 4300            worktree_store,
 4301            languages: languages.clone(),
 4302            language_server_statuses: Default::default(),
 4303            nonce: StdRng::from_os_rng().random(),
 4304            diagnostic_summaries: HashMap::default(),
 4305            lsp_server_capabilities: HashMap::default(),
 4306            semantic_token_config: SemanticTokenConfig::new(cx),
 4307            lsp_data: HashMap::default(),
 4308            buffer_reload_tasks: HashMap::default(),
 4309            next_hint_id: Arc::default(),
 4310            active_entry: None,
 4311            _maintain_workspace_config,
 4312            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4313        }
 4314    }
 4315
 4316    fn send_lsp_proto_request<R: LspCommand>(
 4317        &self,
 4318        buffer: Entity<Buffer>,
 4319        client: AnyProtoClient,
 4320        upstream_project_id: u64,
 4321        request: R,
 4322        cx: &mut Context<LspStore>,
 4323    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4324        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4325            return Task::ready(Ok(R::Response::default()));
 4326        }
 4327        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4328        cx.spawn(async move |this, cx| {
 4329            let response = client.request(message).await?;
 4330            let this = this.upgrade().context("project dropped")?;
 4331            request
 4332                .response_from_proto(response, this, buffer, cx.clone())
 4333                .await
 4334        })
 4335    }
 4336
 4337    pub(super) fn new_remote(
 4338        buffer_store: Entity<BufferStore>,
 4339        worktree_store: Entity<WorktreeStore>,
 4340        languages: Arc<LanguageRegistry>,
 4341        upstream_client: AnyProtoClient,
 4342        project_id: u64,
 4343        cx: &mut Context<Self>,
 4344    ) -> Self {
 4345        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4346            .detach();
 4347        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4348            .detach();
 4349        subscribe_to_binary_statuses(&languages, cx).detach();
 4350        let _maintain_workspace_config = {
 4351            let (sender, receiver) = watch::channel();
 4352            (Self::maintain_workspace_config(receiver, cx), sender)
 4353        };
 4354        Self {
 4355            mode: LspStoreMode::Remote(RemoteLspStore {
 4356                upstream_client: Some(upstream_client),
 4357                upstream_project_id: project_id,
 4358            }),
 4359            downstream_client: None,
 4360            last_formatting_failure: None,
 4361            buffer_store,
 4362            worktree_store,
 4363            languages: languages.clone(),
 4364            language_server_statuses: Default::default(),
 4365            nonce: StdRng::from_os_rng().random(),
 4366            diagnostic_summaries: HashMap::default(),
 4367            lsp_server_capabilities: HashMap::default(),
 4368            semantic_token_config: SemanticTokenConfig::new(cx),
 4369            next_hint_id: Arc::default(),
 4370            lsp_data: HashMap::default(),
 4371            buffer_reload_tasks: HashMap::default(),
 4372            active_entry: None,
 4373
 4374            _maintain_workspace_config,
 4375            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4376        }
 4377    }
 4378
 4379    fn on_buffer_store_event(
 4380        &mut self,
 4381        _: Entity<BufferStore>,
 4382        event: &BufferStoreEvent,
 4383        cx: &mut Context<Self>,
 4384    ) {
 4385        match event {
 4386            BufferStoreEvent::BufferAdded(buffer) => {
 4387                self.on_buffer_added(buffer, cx).log_err();
 4388            }
 4389            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4390                let buffer_id = buffer.read(cx).remote_id();
 4391                if let Some(local) = self.as_local_mut()
 4392                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4393                {
 4394                    local.reset_buffer(buffer, old_file, cx);
 4395
 4396                    if local.registered_buffers.contains_key(&buffer_id) {
 4397                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4398                    }
 4399                }
 4400
 4401                self.detect_language_for_buffer(buffer, cx);
 4402                if let Some(local) = self.as_local_mut() {
 4403                    local.initialize_buffer(buffer, cx);
 4404                    if local.registered_buffers.contains_key(&buffer_id) {
 4405                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4406                    }
 4407                }
 4408            }
 4409            _ => {}
 4410        }
 4411    }
 4412
 4413    fn on_worktree_store_event(
 4414        &mut self,
 4415        _: Entity<WorktreeStore>,
 4416        event: &WorktreeStoreEvent,
 4417        cx: &mut Context<Self>,
 4418    ) {
 4419        match event {
 4420            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4421                if !worktree.read(cx).is_local() {
 4422                    return;
 4423                }
 4424                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4425                    worktree::Event::UpdatedEntries(changes) => {
 4426                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4427                    }
 4428                    worktree::Event::UpdatedGitRepositories(_)
 4429                    | worktree::Event::DeletedEntry(_)
 4430                    | worktree::Event::Deleted
 4431                    | worktree::Event::UpdatedRootRepoCommonDir => {}
 4432                })
 4433                .detach()
 4434            }
 4435            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4436            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4437                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4438            }
 4439            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4440                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4441            }
 4442            WorktreeStoreEvent::WorktreeReleased(..)
 4443            | WorktreeStoreEvent::WorktreeOrderChanged
 4444            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4445            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4446        }
 4447    }
 4448
 4449    fn on_prettier_store_event(
 4450        &mut self,
 4451        _: Entity<PrettierStore>,
 4452        event: &PrettierStoreEvent,
 4453        cx: &mut Context<Self>,
 4454    ) {
 4455        match event {
 4456            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4457                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4458            }
 4459            PrettierStoreEvent::LanguageServerAdded {
 4460                new_server_id,
 4461                name,
 4462                prettier_server,
 4463            } => {
 4464                self.register_supplementary_language_server(
 4465                    *new_server_id,
 4466                    name.clone(),
 4467                    prettier_server.clone(),
 4468                    cx,
 4469                );
 4470            }
 4471        }
 4472    }
 4473
 4474    fn on_toolchain_store_event(
 4475        &mut self,
 4476        _: Entity<LocalToolchainStore>,
 4477        event: &ToolchainStoreEvent,
 4478        _: &mut Context<Self>,
 4479    ) {
 4480        if let ToolchainStoreEvent::ToolchainActivated = event {
 4481            self.request_workspace_config_refresh()
 4482        }
 4483    }
 4484
 4485    fn request_workspace_config_refresh(&mut self) {
 4486        *self._maintain_workspace_config.1.borrow_mut() = ();
 4487    }
 4488
 4489    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4490        self.as_local().map(|local| local.prettier_store.clone())
 4491    }
 4492
 4493    fn on_buffer_event(
 4494        &mut self,
 4495        buffer: Entity<Buffer>,
 4496        event: &language::BufferEvent,
 4497        cx: &mut Context<Self>,
 4498    ) {
 4499        match event {
 4500            language::BufferEvent::Edited { .. } => {
 4501                self.on_buffer_edited(buffer, cx);
 4502            }
 4503
 4504            language::BufferEvent::Saved => {
 4505                self.on_buffer_saved(buffer, cx);
 4506            }
 4507
 4508            language::BufferEvent::Reloaded => {
 4509                self.on_buffer_reloaded(buffer, cx);
 4510            }
 4511
 4512            _ => {}
 4513        }
 4514    }
 4515
 4516    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4517        buffer
 4518            .read(cx)
 4519            .set_language_registry(self.languages.clone());
 4520
 4521        cx.subscribe(buffer, |this, buffer, event, cx| {
 4522            this.on_buffer_event(buffer, event, cx);
 4523        })
 4524        .detach();
 4525
 4526        self.parse_modeline(buffer, cx);
 4527        self.detect_language_for_buffer(buffer, cx);
 4528        if let Some(local) = self.as_local_mut() {
 4529            local.initialize_buffer(buffer, cx);
 4530        }
 4531
 4532        Ok(())
 4533    }
 4534
 4535    pub fn refresh_background_diagnostics_for_buffers(
 4536        &mut self,
 4537        buffers: HashSet<BufferId>,
 4538        cx: &mut Context<Self>,
 4539    ) -> Shared<Task<()>> {
 4540        let Some(local) = self.as_local_mut() else {
 4541            return Task::ready(()).shared();
 4542        };
 4543        for buffer in buffers {
 4544            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4545                local.buffers_to_refresh_queue.push_back(buffer);
 4546                if local.buffers_to_refresh_queue.len() == 1 {
 4547                    local._background_diagnostics_worker =
 4548                        Self::background_diagnostics_worker(cx).shared();
 4549                }
 4550            }
 4551        }
 4552
 4553        local._background_diagnostics_worker.clone()
 4554    }
 4555
 4556    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4557        let buffer_store = self.buffer_store.clone();
 4558        let local = self.as_local_mut()?;
 4559        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4560            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4561            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4562                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4563            }
 4564        }
 4565        None
 4566    }
 4567
 4568    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4569        cx.spawn(async move |this, cx| {
 4570            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4571                task.await.log_err();
 4572            }
 4573        })
 4574    }
 4575
 4576    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4577        if self.parse_modeline(&buffer, cx) {
 4578            self.detect_language_for_buffer(&buffer, cx);
 4579        }
 4580
 4581        let buffer_id = buffer.read(cx).remote_id();
 4582        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4583        self.buffer_reload_tasks.insert(buffer_id, task);
 4584    }
 4585
 4586    pub(crate) fn register_buffer_with_language_servers(
 4587        &mut self,
 4588        buffer: &Entity<Buffer>,
 4589        only_register_servers: HashSet<LanguageServerSelector>,
 4590        ignore_refcounts: bool,
 4591        cx: &mut Context<Self>,
 4592    ) -> OpenLspBufferHandle {
 4593        let buffer_id = buffer.read(cx).remote_id();
 4594        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4595        if let Some(local) = self.as_local_mut() {
 4596            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4597            if !ignore_refcounts {
 4598                *refcount += 1;
 4599            }
 4600
 4601            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4602            // 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
 4603            // 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
 4604            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4605            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4606                return handle;
 4607            };
 4608            if !file.is_local() {
 4609                return handle;
 4610            }
 4611
 4612            if ignore_refcounts || *refcount == 1 {
 4613                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4614            }
 4615            if !ignore_refcounts {
 4616                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4617                    let refcount = {
 4618                        let local = lsp_store.as_local_mut().unwrap();
 4619                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4620                            debug_panic!("bad refcounting");
 4621                            return;
 4622                        };
 4623
 4624                        *refcount -= 1;
 4625                        *refcount
 4626                    };
 4627                    if refcount == 0 {
 4628                        lsp_store.lsp_data.remove(&buffer_id);
 4629                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4630                        let local = lsp_store.as_local_mut().unwrap();
 4631                        local.registered_buffers.remove(&buffer_id);
 4632
 4633                        local.buffers_opened_in_servers.remove(&buffer_id);
 4634                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4635                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4636
 4637                            let buffer_abs_path = file.abs_path(cx);
 4638                            for (_, buffer_pull_diagnostics_result_ids) in
 4639                                &mut local.buffer_pull_diagnostics_result_ids
 4640                            {
 4641                                buffer_pull_diagnostics_result_ids.retain(
 4642                                    |_, buffer_result_ids| {
 4643                                        buffer_result_ids.remove(&buffer_abs_path);
 4644                                        !buffer_result_ids.is_empty()
 4645                                    },
 4646                                );
 4647                            }
 4648
 4649                            let diagnostic_updates = local
 4650                                .language_servers
 4651                                .keys()
 4652                                .cloned()
 4653                                .map(|server_id| DocumentDiagnosticsUpdate {
 4654                                    diagnostics: DocumentDiagnostics {
 4655                                        document_abs_path: buffer_abs_path.clone(),
 4656                                        version: None,
 4657                                        diagnostics: Vec::new(),
 4658                                    },
 4659                                    result_id: None,
 4660                                    registration_id: None,
 4661                                    server_id,
 4662                                    disk_based_sources: Cow::Borrowed(&[]),
 4663                                })
 4664                                .collect::<Vec<_>>();
 4665
 4666                            lsp_store
 4667                                .merge_diagnostic_entries(
 4668                                    diagnostic_updates,
 4669                                    |_, diagnostic, _| {
 4670                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4671                                    },
 4672                                    cx,
 4673                                )
 4674                                .context("Clearing diagnostics for the closed buffer")
 4675                                .log_err();
 4676                        }
 4677                    }
 4678                })
 4679                .detach();
 4680            }
 4681        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4682            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4683            cx.background_spawn(async move {
 4684                upstream_client
 4685                    .request(proto::RegisterBufferWithLanguageServers {
 4686                        project_id: upstream_project_id,
 4687                        buffer_id,
 4688                        only_servers: only_register_servers
 4689                            .into_iter()
 4690                            .map(|selector| {
 4691                                let selector = match selector {
 4692                                    LanguageServerSelector::Id(language_server_id) => {
 4693                                        proto::language_server_selector::Selector::ServerId(
 4694                                            language_server_id.to_proto(),
 4695                                        )
 4696                                    }
 4697                                    LanguageServerSelector::Name(language_server_name) => {
 4698                                        proto::language_server_selector::Selector::Name(
 4699                                            language_server_name.to_string(),
 4700                                        )
 4701                                    }
 4702                                };
 4703                                proto::LanguageServerSelector {
 4704                                    selector: Some(selector),
 4705                                }
 4706                            })
 4707                            .collect(),
 4708                    })
 4709                    .await
 4710            })
 4711            .detach();
 4712        } else {
 4713            // Our remote connection got closed
 4714        }
 4715        handle
 4716    }
 4717
 4718    fn maintain_buffer_languages(
 4719        languages: Arc<LanguageRegistry>,
 4720        cx: &mut Context<Self>,
 4721    ) -> Task<()> {
 4722        let mut subscription = languages.subscribe();
 4723        let mut prev_reload_count = languages.reload_count();
 4724        cx.spawn(async move |this, cx| {
 4725            while let Some(()) = subscription.next().await {
 4726                if let Some(this) = this.upgrade() {
 4727                    // If the language registry has been reloaded, then remove and
 4728                    // re-assign the languages on all open buffers.
 4729                    let reload_count = languages.reload_count();
 4730                    if reload_count > prev_reload_count {
 4731                        prev_reload_count = reload_count;
 4732                        this.update(cx, |this, cx| {
 4733                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4734                                for buffer in buffer_store.buffers() {
 4735                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4736                                    {
 4737                                        buffer.update(cx, |buffer, cx| {
 4738                                            buffer.set_language_async(None, cx)
 4739                                        });
 4740                                        if let Some(local) = this.as_local_mut() {
 4741                                            local.reset_buffer(&buffer, &f, cx);
 4742
 4743                                            if local
 4744                                                .registered_buffers
 4745                                                .contains_key(&buffer.read(cx).remote_id())
 4746                                                && let Some(file_url) =
 4747                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4748                                            {
 4749                                                local.unregister_buffer_from_language_servers(
 4750                                                    &buffer, &file_url, cx,
 4751                                                );
 4752                                            }
 4753                                        }
 4754                                    }
 4755                                }
 4756                            });
 4757                        });
 4758                    }
 4759
 4760                    this.update(cx, |this, cx| {
 4761                        let mut plain_text_buffers = Vec::new();
 4762                        let mut buffers_with_unknown_injections = Vec::new();
 4763                        for handle in this.buffer_store.read(cx).buffers() {
 4764                            let buffer = handle.read(cx);
 4765                            if buffer.language().is_none()
 4766                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4767                            {
 4768                                plain_text_buffers.push(handle);
 4769                            } else if buffer.contains_unknown_injections() {
 4770                                buffers_with_unknown_injections.push(handle);
 4771                            }
 4772                        }
 4773
 4774                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4775                        // and reused later in the invisible worktrees.
 4776                        plain_text_buffers.sort_by_key(|buffer| {
 4777                            Reverse(
 4778                                File::from_dyn(buffer.read(cx).file())
 4779                                    .map(|file| file.worktree.read(cx).is_visible()),
 4780                            )
 4781                        });
 4782
 4783                        for buffer in plain_text_buffers {
 4784                            this.detect_language_for_buffer(&buffer, cx);
 4785                            if let Some(local) = this.as_local_mut() {
 4786                                local.initialize_buffer(&buffer, cx);
 4787                                if local
 4788                                    .registered_buffers
 4789                                    .contains_key(&buffer.read(cx).remote_id())
 4790                                {
 4791                                    local.register_buffer_with_language_servers(
 4792                                        &buffer,
 4793                                        HashSet::default(),
 4794                                        cx,
 4795                                    );
 4796                                }
 4797                            }
 4798                        }
 4799
 4800                        for buffer in buffers_with_unknown_injections {
 4801                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4802                        }
 4803                    });
 4804                }
 4805            }
 4806        })
 4807    }
 4808
 4809    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4810        let buffer = buffer_handle.read(cx);
 4811        let content = buffer.as_rope();
 4812
 4813        let modeline_settings = {
 4814            let settings_store = cx.global::<SettingsStore>();
 4815            let modeline_lines = settings_store
 4816                .raw_user_settings()
 4817                .and_then(|s| s.content.modeline_lines)
 4818                .or(settings_store.raw_default_settings().modeline_lines)
 4819                .unwrap_or(5);
 4820
 4821            const MAX_MODELINE_BYTES: usize = 1024;
 4822
 4823            let first_bytes =
 4824                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4825            let mut first_lines = Vec::new();
 4826            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4827            for _ in 0..modeline_lines {
 4828                if let Some(line) = lines.next() {
 4829                    first_lines.push(line.to_string());
 4830                } else {
 4831                    break;
 4832                }
 4833            }
 4834            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4835
 4836            let last_start =
 4837                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4838            let mut last_lines = Vec::new();
 4839            let mut lines = content
 4840                .reversed_chunks_in_range(last_start..content.len())
 4841                .lines();
 4842            for _ in 0..modeline_lines {
 4843                if let Some(line) = lines.next() {
 4844                    last_lines.push(line.to_string());
 4845                } else {
 4846                    break;
 4847                }
 4848            }
 4849            let last_lines_ref: Vec<_> =
 4850                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4851            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4852        };
 4853
 4854        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4855
 4856        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4857    }
 4858
 4859    fn detect_language_for_buffer(
 4860        &mut self,
 4861        buffer_handle: &Entity<Buffer>,
 4862        cx: &mut Context<Self>,
 4863    ) -> Option<language::AvailableLanguage> {
 4864        // If the buffer has a language, set it and start the language server if we haven't already.
 4865        let buffer = buffer_handle.read(cx);
 4866        let file = buffer.file()?;
 4867        let content = buffer.as_rope();
 4868        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4869
 4870        let available_language = if let Some(ModelineSettings {
 4871            mode: Some(mode_name),
 4872            ..
 4873        }) = modeline_settings
 4874        {
 4875            self.languages
 4876                .available_language_for_modeline_name(mode_name)
 4877        } else {
 4878            self.languages.language_for_file(file, Some(content), cx)
 4879        };
 4880        if let Some(available_language) = &available_language {
 4881            if let Some(Ok(Ok(new_language))) = self
 4882                .languages
 4883                .load_language(available_language)
 4884                .now_or_never()
 4885            {
 4886                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4887            }
 4888        } else {
 4889            cx.emit(LspStoreEvent::LanguageDetected {
 4890                buffer: buffer_handle.clone(),
 4891                new_language: None,
 4892            });
 4893        }
 4894
 4895        available_language
 4896    }
 4897
 4898    pub(crate) fn set_language_for_buffer(
 4899        &mut self,
 4900        buffer_entity: &Entity<Buffer>,
 4901        new_language: Arc<Language>,
 4902        cx: &mut Context<Self>,
 4903    ) {
 4904        let buffer = buffer_entity.read(cx);
 4905        let buffer_file = buffer.file().cloned();
 4906        let buffer_id = buffer.remote_id();
 4907        if let Some(local_store) = self.as_local_mut()
 4908            && local_store.registered_buffers.contains_key(&buffer_id)
 4909            && let Some(abs_path) =
 4910                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4911            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4912        {
 4913            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4914        }
 4915        buffer_entity.update(cx, |buffer, cx| {
 4916            if buffer
 4917                .language()
 4918                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4919            {
 4920                buffer.set_language_async(Some(new_language.clone()), cx);
 4921            }
 4922        });
 4923
 4924        let settings = LanguageSettings::resolve(
 4925            Some(&buffer_entity.read(cx)),
 4926            Some(&new_language.name()),
 4927            cx,
 4928        )
 4929        .into_owned();
 4930        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4931
 4932        let worktree_id = if let Some(file) = buffer_file {
 4933            let worktree = file.worktree.clone();
 4934
 4935            if let Some(local) = self.as_local_mut()
 4936                && local.registered_buffers.contains_key(&buffer_id)
 4937            {
 4938                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4939            }
 4940            Some(worktree.read(cx).id())
 4941        } else {
 4942            None
 4943        };
 4944
 4945        if settings.prettier.allowed
 4946            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4947        {
 4948            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4949            if let Some(prettier_store) = prettier_store {
 4950                prettier_store.update(cx, |prettier_store, cx| {
 4951                    prettier_store.install_default_prettier(
 4952                        worktree_id,
 4953                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4954                        cx,
 4955                    )
 4956                })
 4957            }
 4958        }
 4959
 4960        cx.emit(LspStoreEvent::LanguageDetected {
 4961            buffer: buffer_entity.clone(),
 4962            new_language: Some(new_language),
 4963        })
 4964    }
 4965
 4966    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4967        self.buffer_store.clone()
 4968    }
 4969
 4970    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4971        self.active_entry = active_entry;
 4972    }
 4973
 4974    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4975        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4976            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4977        {
 4978            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4979                summaries
 4980                    .iter()
 4981                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4982            });
 4983            if let Some(summary) = summaries.next() {
 4984                client
 4985                    .send(proto::UpdateDiagnosticSummary {
 4986                        project_id: downstream_project_id,
 4987                        worktree_id: worktree.id().to_proto(),
 4988                        summary: Some(summary),
 4989                        more_summaries: summaries.collect(),
 4990                    })
 4991                    .log_err();
 4992            }
 4993        }
 4994    }
 4995
 4996    fn is_capable_for_proto_request<R>(
 4997        &self,
 4998        buffer: &Entity<Buffer>,
 4999        request: &R,
 5000        cx: &App,
 5001    ) -> bool
 5002    where
 5003        R: LspCommand,
 5004    {
 5005        self.check_if_capable_for_proto_request(
 5006            buffer,
 5007            |capabilities| {
 5008                request.check_capabilities(AdapterServerCapabilities {
 5009                    server_capabilities: capabilities.clone(),
 5010                    code_action_kinds: None,
 5011                })
 5012            },
 5013            cx,
 5014        )
 5015    }
 5016
 5017    fn check_if_capable_for_proto_request<F>(
 5018        &self,
 5019        buffer: &Entity<Buffer>,
 5020        check: F,
 5021        cx: &App,
 5022    ) -> bool
 5023    where
 5024        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5025    {
 5026        let Some(language) = buffer.read(cx).language().cloned() else {
 5027            return false;
 5028        };
 5029        let registered_language_servers = self
 5030            .languages
 5031            .lsp_adapters(&language.name())
 5032            .into_iter()
 5033            .map(|lsp_adapter| lsp_adapter.name())
 5034            .collect::<HashSet<_>>();
 5035        self.language_server_statuses
 5036            .iter()
 5037            .filter_map(|(server_id, server_status)| {
 5038                // Include servers that are either registered for this language OR
 5039                // available to be loaded (for SSH remote mode where adapters like
 5040                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5041                // but only loaded on the server side)
 5042                let is_relevant = registered_language_servers.contains(&server_status.name)
 5043                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5044                is_relevant.then_some(server_id)
 5045            })
 5046            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 5047            .any(check)
 5048    }
 5049
 5050    fn all_capable_for_proto_request<F>(
 5051        &self,
 5052        buffer: &Entity<Buffer>,
 5053        mut check: F,
 5054        cx: &App,
 5055    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5056    where
 5057        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5058    {
 5059        let Some(language) = buffer.read(cx).language().cloned() else {
 5060            return Vec::default();
 5061        };
 5062        let registered_language_servers = self
 5063            .languages
 5064            .lsp_adapters(&language.name())
 5065            .into_iter()
 5066            .map(|lsp_adapter| lsp_adapter.name())
 5067            .collect::<HashSet<_>>();
 5068        self.language_server_statuses
 5069            .iter()
 5070            .filter_map(|(server_id, server_status)| {
 5071                // Include servers that are either registered for this language OR
 5072                // available to be loaded (for SSH remote mode where adapters like
 5073                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5074                // but only loaded on the server side)
 5075                let is_relevant = registered_language_servers.contains(&server_status.name)
 5076                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5077                is_relevant.then_some((server_id, &server_status.name))
 5078            })
 5079            .filter_map(|(server_id, server_name)| {
 5080                self.lsp_server_capabilities
 5081                    .get(server_id)
 5082                    .map(|c| (server_id, server_name, c))
 5083            })
 5084            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5085            .map(|(server_id, server_name, _)| (*server_id, server_name.clone()))
 5086            .collect()
 5087    }
 5088
 5089    pub fn request_lsp<R>(
 5090        &mut self,
 5091        buffer: Entity<Buffer>,
 5092        server: LanguageServerToQuery,
 5093        request: R,
 5094        cx: &mut Context<Self>,
 5095    ) -> Task<Result<R::Response>>
 5096    where
 5097        R: LspCommand,
 5098        <R::LspRequest as lsp::request::Request>::Result: Send,
 5099        <R::LspRequest as lsp::request::Request>::Params: Send,
 5100    {
 5101        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5102            return self.send_lsp_proto_request(
 5103                buffer,
 5104                upstream_client,
 5105                upstream_project_id,
 5106                request,
 5107                cx,
 5108            );
 5109        }
 5110
 5111        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5112            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5113                local
 5114                    .language_servers_for_buffer(buffer, cx)
 5115                    .find(|(_, server)| {
 5116                        request.check_capabilities(server.adapter_server_capabilities())
 5117                    })
 5118                    .map(|(_, server)| server.clone())
 5119            }),
 5120            LanguageServerToQuery::Other(id) => self
 5121                .language_server_for_local_buffer(buffer, id, cx)
 5122                .and_then(|(_, server)| {
 5123                    request
 5124                        .check_capabilities(server.adapter_server_capabilities())
 5125                        .then(|| Arc::clone(server))
 5126                }),
 5127        }) else {
 5128            return Task::ready(Ok(Default::default()));
 5129        };
 5130
 5131        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5132
 5133        let Some(file) = file else {
 5134            return Task::ready(Ok(Default::default()));
 5135        };
 5136
 5137        let lsp_params = match request.to_lsp_params_or_response(
 5138            &file.abs_path(cx),
 5139            buffer.read(cx),
 5140            &language_server,
 5141            cx,
 5142        ) {
 5143            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5144            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5145            Err(err) => {
 5146                let message = format!(
 5147                    "{} via {} failed: {}",
 5148                    request.display_name(),
 5149                    language_server.name(),
 5150                    err
 5151                );
 5152                // rust-analyzer likes to error with this when its still loading up
 5153                if !message.ends_with("content modified") {
 5154                    log::warn!("{message}");
 5155                }
 5156                return Task::ready(Err(anyhow!(message)));
 5157            }
 5158        };
 5159
 5160        let status = request.status();
 5161        let request_timeout = ProjectSettings::get_global(cx)
 5162            .global_lsp_settings
 5163            .get_request_timeout();
 5164
 5165        cx.spawn(async move |this, cx| {
 5166            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5167
 5168            let id = lsp_request.id();
 5169            let _cleanup = if status.is_some() {
 5170                cx.update(|cx| {
 5171                    this.update(cx, |this, cx| {
 5172                        this.on_lsp_work_start(
 5173                            language_server.server_id(),
 5174                            ProgressToken::Number(id),
 5175                            LanguageServerProgress {
 5176                                is_disk_based_diagnostics_progress: false,
 5177                                is_cancellable: false,
 5178                                title: None,
 5179                                message: status.clone(),
 5180                                percentage: None,
 5181                                last_update_at: cx.background_executor().now(),
 5182                            },
 5183                            cx,
 5184                        );
 5185                    })
 5186                })
 5187                .log_err();
 5188
 5189                Some(defer(|| {
 5190                    cx.update(|cx| {
 5191                        this.update(cx, |this, cx| {
 5192                            this.on_lsp_work_end(
 5193                                language_server.server_id(),
 5194                                ProgressToken::Number(id),
 5195                                cx,
 5196                            );
 5197                        })
 5198                    })
 5199                    .log_err();
 5200                }))
 5201            } else {
 5202                None
 5203            };
 5204
 5205            let result = lsp_request.await.into_response();
 5206
 5207            let response = result.map_err(|err| {
 5208                let message = format!(
 5209                    "{} via {} failed: {}",
 5210                    request.display_name(),
 5211                    language_server.name(),
 5212                    err
 5213                );
 5214                // rust-analyzer likes to error with this when its still loading up
 5215                if !message.ends_with("content modified") {
 5216                    log::warn!("{message}");
 5217                }
 5218                anyhow::anyhow!(message)
 5219            })?;
 5220
 5221            request
 5222                .response_from_lsp(
 5223                    response,
 5224                    this.upgrade().context("no app context")?,
 5225                    buffer,
 5226                    language_server.server_id(),
 5227                    cx.clone(),
 5228                )
 5229                .await
 5230        })
 5231    }
 5232
 5233    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5234        let mut language_formatters_to_check = Vec::new();
 5235        for buffer in self.buffer_store.read(cx).buffers() {
 5236            let buffer = buffer.read(cx);
 5237            let settings = LanguageSettings::for_buffer(buffer, cx);
 5238            if buffer.language().is_some() {
 5239                let buffer_file = File::from_dyn(buffer.file());
 5240                language_formatters_to_check.push((
 5241                    buffer_file.map(|f| f.worktree_id(cx)),
 5242                    settings.into_owned(),
 5243                ));
 5244            }
 5245        }
 5246
 5247        self.request_workspace_config_refresh();
 5248
 5249        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5250            prettier_store.update(cx, |prettier_store, cx| {
 5251                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5252            })
 5253        }
 5254
 5255        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5256            .global_lsp_settings
 5257            .semantic_token_rules
 5258            .clone();
 5259        self.semantic_token_config
 5260            .update_rules(new_semantic_token_rules);
 5261        // Always clear cached stylizers so that changes to language-specific
 5262        // semantic token rules (e.g. from extension install/uninstall) are
 5263        // picked up. Stylizers are recreated lazily, so this is cheap.
 5264        self.semantic_token_config.clear_stylizers();
 5265
 5266        let new_global_semantic_tokens_mode =
 5267            all_language_settings(None, cx).defaults.semantic_tokens;
 5268        if self
 5269            .semantic_token_config
 5270            .update_global_mode(new_global_semantic_tokens_mode)
 5271        {
 5272            let all_stopped = self
 5273                .as_local()
 5274                .is_some_and(|local| local.all_language_servers_stopped);
 5275            if !all_stopped {
 5276                // Restart servers without clearing per-server stopped status.
 5277                // Individually-stopped servers will be skipped by the guard in
 5278                // register_buffer_with_language_servers.
 5279                let buffers = self.buffer_store.read(cx).buffers().collect();
 5280                self.restart_language_servers_for_buffers(buffers, HashSet::default(), false, cx);
 5281            }
 5282        }
 5283
 5284        cx.notify();
 5285    }
 5286
 5287    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5288        let buffer_store = self.buffer_store.clone();
 5289        let Some(local) = self.as_local_mut() else {
 5290            return;
 5291        };
 5292        if local.all_language_servers_stopped {
 5293            return;
 5294        }
 5295        let stopped_language_servers = local.stopped_language_servers.clone();
 5296        let mut adapters = BTreeMap::default();
 5297        let get_adapter = {
 5298            let languages = local.languages.clone();
 5299            let environment = local.environment.clone();
 5300            let weak = local.weak.clone();
 5301            let worktree_store = local.worktree_store.clone();
 5302            let http_client = local.http_client.clone();
 5303            let fs = local.fs.clone();
 5304            move |worktree_id, cx: &mut App| {
 5305                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5306                Some(LocalLspAdapterDelegate::new(
 5307                    languages.clone(),
 5308                    &environment,
 5309                    weak.clone(),
 5310                    &worktree,
 5311                    http_client.clone(),
 5312                    fs.clone(),
 5313                    cx,
 5314                ))
 5315            }
 5316        };
 5317
 5318        let mut messages_to_report = Vec::new();
 5319        let (new_tree, to_stop) = {
 5320            let mut rebase = local.lsp_tree.rebase();
 5321            let buffers = buffer_store
 5322                .read(cx)
 5323                .buffers()
 5324                .filter_map(|buffer| {
 5325                    let raw_buffer = buffer.read(cx);
 5326                    if !local
 5327                        .registered_buffers
 5328                        .contains_key(&raw_buffer.remote_id())
 5329                    {
 5330                        return None;
 5331                    }
 5332                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5333                    let language = raw_buffer.language().cloned()?;
 5334                    Some((file, language, raw_buffer.remote_id()))
 5335                })
 5336                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5337            for (file, language, buffer_id) in buffers {
 5338                let worktree_id = file.worktree_id(cx);
 5339                let Some(worktree) = local
 5340                    .worktree_store
 5341                    .read(cx)
 5342                    .worktree_for_id(worktree_id, cx)
 5343                else {
 5344                    continue;
 5345                };
 5346
 5347                if let Some((_, apply)) = local.reuse_existing_language_server(
 5348                    rebase.server_tree(),
 5349                    &worktree,
 5350                    &language.name(),
 5351                    cx,
 5352                ) {
 5353                    (apply)(rebase.server_tree());
 5354                } else if let Some(lsp_delegate) = adapters
 5355                    .entry(worktree_id)
 5356                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5357                    .clone()
 5358                {
 5359                    let delegate =
 5360                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5361                    let path = file
 5362                        .path()
 5363                        .parent()
 5364                        .map(Arc::from)
 5365                        .unwrap_or_else(|| file.path().clone());
 5366                    let worktree_path = ProjectPath { worktree_id, path };
 5367                    let abs_path = file.abs_path(cx);
 5368                    let nodes = rebase
 5369                        .walk(
 5370                            worktree_path,
 5371                            language.name(),
 5372                            language.manifest(),
 5373                            delegate.clone(),
 5374                            cx,
 5375                        )
 5376                        .collect::<Vec<_>>();
 5377                    for node in nodes {
 5378                        if let Some(name) = node.name()
 5379                            && stopped_language_servers.contains(&name)
 5380                        {
 5381                            continue;
 5382                        }
 5383                        let server_id = node.server_id_or_init(|disposition| {
 5384                            let path = &disposition.path;
 5385                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5386                            let key = LanguageServerSeed {
 5387                                worktree_id,
 5388                                name: disposition.server_name.clone(),
 5389                                settings: LanguageServerSeedSettings {
 5390                                    binary: disposition.settings.binary.clone(),
 5391                                    initialization_options: disposition
 5392                                        .settings
 5393                                        .initialization_options
 5394                                        .clone(),
 5395                                },
 5396                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5397                                    path.worktree_id,
 5398                                    &path.path,
 5399                                    language.name(),
 5400                                ),
 5401                            };
 5402                            local.language_server_ids.remove(&key);
 5403
 5404                            let server_id = local.get_or_insert_language_server(
 5405                                &worktree,
 5406                                lsp_delegate.clone(),
 5407                                disposition,
 5408                                &language.name(),
 5409                                cx,
 5410                            );
 5411                            if let Some(state) = local.language_servers.get(&server_id)
 5412                                && let Ok(uri) = uri
 5413                            {
 5414                                state.add_workspace_folder(uri);
 5415                            };
 5416                            server_id
 5417                        });
 5418
 5419                        if let Some(language_server_id) = server_id {
 5420                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5421                                language_server_id,
 5422                                name: node.name(),
 5423                                message:
 5424                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5425                                        proto::RegisteredForBuffer {
 5426                                            buffer_abs_path: abs_path
 5427                                                .to_string_lossy()
 5428                                                .into_owned(),
 5429                                            buffer_id: buffer_id.to_proto(),
 5430                                        },
 5431                                    ),
 5432                            });
 5433                        }
 5434                    }
 5435                } else {
 5436                    continue;
 5437                }
 5438            }
 5439            rebase.finish()
 5440        };
 5441        for message in messages_to_report {
 5442            cx.emit(message);
 5443        }
 5444        local.lsp_tree = new_tree;
 5445        for (id, _) in to_stop {
 5446            self.stop_local_language_server(id, cx).detach();
 5447        }
 5448    }
 5449
 5450    pub fn apply_code_action(
 5451        &self,
 5452        buffer_handle: Entity<Buffer>,
 5453        mut action: CodeAction,
 5454        push_to_history: bool,
 5455        cx: &mut Context<Self>,
 5456    ) -> Task<Result<ProjectTransaction>> {
 5457        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5458            let request = proto::ApplyCodeAction {
 5459                project_id,
 5460                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5461                action: Some(Self::serialize_code_action(&action)),
 5462            };
 5463            let buffer_store = self.buffer_store();
 5464            cx.spawn(async move |_, cx| {
 5465                let response = upstream_client
 5466                    .request(request)
 5467                    .await?
 5468                    .transaction
 5469                    .context("missing transaction")?;
 5470
 5471                buffer_store
 5472                    .update(cx, |buffer_store, cx| {
 5473                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5474                    })
 5475                    .await
 5476            })
 5477        } else if self.mode.is_local() {
 5478            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5479                let request_timeout = ProjectSettings::get_global(cx)
 5480                    .global_lsp_settings
 5481                    .get_request_timeout();
 5482                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5483                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5484            }) else {
 5485                return Task::ready(Ok(ProjectTransaction::default()));
 5486            };
 5487
 5488            cx.spawn(async move |this, cx| {
 5489                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5490                    .await
 5491                    .context("resolving a code action")?;
 5492                if let Some(edit) = action.lsp_action.edit()
 5493                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5494                        return LocalLspStore::deserialize_workspace_edit(
 5495                            this.upgrade().context("no app present")?,
 5496                            edit.clone(),
 5497                            push_to_history,
 5498
 5499                            lang_server.clone(),
 5500                            cx,
 5501                        )
 5502                        .await;
 5503                    }
 5504
 5505                let Some(command) = action.lsp_action.command() else {
 5506                    return Ok(ProjectTransaction::default())
 5507                };
 5508
 5509                let server_capabilities = lang_server.capabilities();
 5510                let available_commands = server_capabilities
 5511                    .execute_command_provider
 5512                    .as_ref()
 5513                    .map(|options| options.commands.as_slice())
 5514                    .unwrap_or_default();
 5515
 5516                if !available_commands.contains(&command.command) {
 5517                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5518                    return Ok(ProjectTransaction::default())
 5519                }
 5520
 5521                let request_timeout = cx.update(|app|
 5522                    ProjectSettings::get_global(app)
 5523                    .global_lsp_settings
 5524                    .get_request_timeout()
 5525                );
 5526
 5527                this.update(cx, |this, _| {
 5528                    this.as_local_mut()
 5529                        .unwrap()
 5530                        .last_workspace_edits_by_language_server
 5531                        .remove(&lang_server.server_id());
 5532                })?;
 5533
 5534                let _result = lang_server
 5535                    .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5536                        command: command.command.clone(),
 5537                        arguments: command.arguments.clone().unwrap_or_default(),
 5538                        ..lsp::ExecuteCommandParams::default()
 5539                    }, request_timeout)
 5540                    .await.into_response()
 5541                    .context("execute command")?;
 5542
 5543                return this.update(cx, |this, _| {
 5544                    this.as_local_mut()
 5545                        .unwrap()
 5546                        .last_workspace_edits_by_language_server
 5547                        .remove(&lang_server.server_id())
 5548                        .unwrap_or_default()
 5549                });
 5550            })
 5551        } else {
 5552            Task::ready(Err(anyhow!("no upstream client and not local")))
 5553        }
 5554    }
 5555
 5556    pub fn apply_code_action_kind(
 5557        &mut self,
 5558        buffers: HashSet<Entity<Buffer>>,
 5559        kind: CodeActionKind,
 5560        push_to_history: bool,
 5561        cx: &mut Context<Self>,
 5562    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5563        if self.as_local().is_some() {
 5564            cx.spawn(async move |lsp_store, cx| {
 5565                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5566                let result = LocalLspStore::execute_code_action_kind_locally(
 5567                    lsp_store.clone(),
 5568                    buffers,
 5569                    kind,
 5570                    push_to_history,
 5571                    cx,
 5572                )
 5573                .await;
 5574                lsp_store.update(cx, |lsp_store, _| {
 5575                    lsp_store.update_last_formatting_failure(&result);
 5576                })?;
 5577                result
 5578            })
 5579        } else if let Some((client, project_id)) = self.upstream_client() {
 5580            let buffer_store = self.buffer_store();
 5581            cx.spawn(async move |lsp_store, cx| {
 5582                let result = client
 5583                    .request(proto::ApplyCodeActionKind {
 5584                        project_id,
 5585                        kind: kind.as_str().to_owned(),
 5586                        buffer_ids: buffers
 5587                            .iter()
 5588                            .map(|buffer| {
 5589                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5590                            })
 5591                            .collect(),
 5592                    })
 5593                    .await
 5594                    .and_then(|result| result.transaction.context("missing transaction"));
 5595                lsp_store.update(cx, |lsp_store, _| {
 5596                    lsp_store.update_last_formatting_failure(&result);
 5597                })?;
 5598
 5599                let transaction_response = result?;
 5600                buffer_store
 5601                    .update(cx, |buffer_store, cx| {
 5602                        buffer_store.deserialize_project_transaction(
 5603                            transaction_response,
 5604                            push_to_history,
 5605                            cx,
 5606                        )
 5607                    })
 5608                    .await
 5609            })
 5610        } else {
 5611            Task::ready(Ok(ProjectTransaction::default()))
 5612        }
 5613    }
 5614
 5615    pub fn resolved_hint(
 5616        &mut self,
 5617        buffer_id: BufferId,
 5618        id: InlayId,
 5619        cx: &mut Context<Self>,
 5620    ) -> Option<ResolvedHint> {
 5621        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5622
 5623        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5624        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5625        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5626        let (server_id, resolve_data) = match &hint.resolve_state {
 5627            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5628            ResolveState::Resolving => {
 5629                return Some(ResolvedHint::Resolving(
 5630                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5631                ));
 5632            }
 5633            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5634        };
 5635
 5636        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5637        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5638        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5639            id,
 5640            cx.spawn(async move |lsp_store, cx| {
 5641                let resolved_hint = resolve_task.await;
 5642                lsp_store
 5643                    .update(cx, |lsp_store, _| {
 5644                        if let Some(old_inlay_hint) = lsp_store
 5645                            .lsp_data
 5646                            .get_mut(&buffer_id)
 5647                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5648                        {
 5649                            match resolved_hint {
 5650                                Ok(resolved_hint) => {
 5651                                    *old_inlay_hint = resolved_hint;
 5652                                }
 5653                                Err(e) => {
 5654                                    old_inlay_hint.resolve_state =
 5655                                        ResolveState::CanResolve(server_id, resolve_data);
 5656                                    log::error!("Inlay hint resolve failed: {e:#}");
 5657                                }
 5658                            }
 5659                        }
 5660                    })
 5661                    .ok();
 5662            })
 5663            .shared(),
 5664        );
 5665        debug_assert!(
 5666            previous_task.is_none(),
 5667            "Did not change hint's resolve state after spawning its resolve"
 5668        );
 5669        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5670        None
 5671    }
 5672
 5673    pub(crate) fn linked_edits(
 5674        &mut self,
 5675        buffer: &Entity<Buffer>,
 5676        position: Anchor,
 5677        cx: &mut Context<Self>,
 5678    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5679        let snapshot = buffer.read(cx).snapshot();
 5680        let scope = snapshot.language_scope_at(position);
 5681        let Some(server_id) = self
 5682            .as_local()
 5683            .and_then(|local| {
 5684                buffer.update(cx, |buffer, cx| {
 5685                    local
 5686                        .language_servers_for_buffer(buffer, cx)
 5687                        .filter(|(_, server)| {
 5688                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5689                        })
 5690                        .filter(|(adapter, _)| {
 5691                            scope
 5692                                .as_ref()
 5693                                .map(|scope| scope.language_allowed(&adapter.name))
 5694                                .unwrap_or(true)
 5695                        })
 5696                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5697                        .next()
 5698                })
 5699            })
 5700            .or_else(|| {
 5701                self.upstream_client()
 5702                    .is_some()
 5703                    .then_some(LanguageServerToQuery::FirstCapable)
 5704            })
 5705            .filter(|_| {
 5706                maybe!({
 5707                    buffer.read(cx).language_at(position)?;
 5708                    Some(
 5709                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5710                            .linked_edits,
 5711                    )
 5712                }) == Some(true)
 5713            })
 5714        else {
 5715            return Task::ready(Ok(Vec::new()));
 5716        };
 5717
 5718        self.request_lsp(
 5719            buffer.clone(),
 5720            server_id,
 5721            LinkedEditingRange { position },
 5722            cx,
 5723        )
 5724    }
 5725
 5726    fn apply_on_type_formatting(
 5727        &mut self,
 5728        buffer: Entity<Buffer>,
 5729        position: Anchor,
 5730        trigger: String,
 5731        cx: &mut Context<Self>,
 5732    ) -> Task<Result<Option<Transaction>>> {
 5733        if let Some((client, project_id)) = self.upstream_client() {
 5734            if !self.check_if_capable_for_proto_request(
 5735                &buffer,
 5736                |capabilities| {
 5737                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5738                },
 5739                cx,
 5740            ) {
 5741                return Task::ready(Ok(None));
 5742            }
 5743            let request = proto::OnTypeFormatting {
 5744                project_id,
 5745                buffer_id: buffer.read(cx).remote_id().into(),
 5746                position: Some(serialize_anchor(&position)),
 5747                trigger,
 5748                version: serialize_version(&buffer.read(cx).version()),
 5749            };
 5750            cx.background_spawn(async move {
 5751                client
 5752                    .request(request)
 5753                    .await?
 5754                    .transaction
 5755                    .map(language::proto::deserialize_transaction)
 5756                    .transpose()
 5757            })
 5758        } else if let Some(local) = self.as_local_mut() {
 5759            let buffer_id = buffer.read(cx).remote_id();
 5760            local.buffers_being_formatted.insert(buffer_id);
 5761            cx.spawn(async move |this, cx| {
 5762                let _cleanup = defer({
 5763                    let this = this.clone();
 5764                    let mut cx = cx.clone();
 5765                    move || {
 5766                        this.update(&mut cx, |this, _| {
 5767                            if let Some(local) = this.as_local_mut() {
 5768                                local.buffers_being_formatted.remove(&buffer_id);
 5769                            }
 5770                        })
 5771                        .ok();
 5772                    }
 5773                });
 5774
 5775                buffer
 5776                    .update(cx, |buffer, _| {
 5777                        buffer.wait_for_edits(Some(position.timestamp()))
 5778                    })
 5779                    .await?;
 5780                this.update(cx, |this, cx| {
 5781                    let position = position.to_point_utf16(buffer.read(cx));
 5782                    this.on_type_format(buffer, position, trigger, false, cx)
 5783                })?
 5784                .await
 5785            })
 5786        } else {
 5787            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5788        }
 5789    }
 5790
 5791    pub fn on_type_format<T: ToPointUtf16>(
 5792        &mut self,
 5793        buffer: Entity<Buffer>,
 5794        position: T,
 5795        trigger: String,
 5796        push_to_history: bool,
 5797        cx: &mut Context<Self>,
 5798    ) -> Task<Result<Option<Transaction>>> {
 5799        let position = position.to_point_utf16(buffer.read(cx));
 5800        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5801    }
 5802
 5803    fn on_type_format_impl(
 5804        &mut self,
 5805        buffer: Entity<Buffer>,
 5806        position: PointUtf16,
 5807        trigger: String,
 5808        push_to_history: bool,
 5809        cx: &mut Context<Self>,
 5810    ) -> Task<Result<Option<Transaction>>> {
 5811        let options = buffer.update(cx, |buffer, cx| {
 5812            lsp_command::lsp_formatting_options(
 5813                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5814            )
 5815        });
 5816
 5817        cx.spawn(async move |this, cx| {
 5818            if let Some(waiter) =
 5819                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5820            {
 5821                waiter.await?;
 5822            }
 5823            cx.update(|cx| {
 5824                this.update(cx, |this, cx| {
 5825                    this.request_lsp(
 5826                        buffer.clone(),
 5827                        LanguageServerToQuery::FirstCapable,
 5828                        OnTypeFormatting {
 5829                            position,
 5830                            trigger,
 5831                            options,
 5832                            push_to_history,
 5833                        },
 5834                        cx,
 5835                    )
 5836                })
 5837            })?
 5838            .await
 5839        })
 5840    }
 5841
 5842    pub fn definitions(
 5843        &mut self,
 5844        buffer: &Entity<Buffer>,
 5845        position: PointUtf16,
 5846        cx: &mut Context<Self>,
 5847    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5848        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5849            let request = GetDefinitions { position };
 5850            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5851                return Task::ready(Ok(None));
 5852            }
 5853
 5854            let request_timeout = ProjectSettings::get_global(cx)
 5855                .global_lsp_settings
 5856                .get_request_timeout();
 5857
 5858            let request_task = upstream_client.request_lsp(
 5859                project_id,
 5860                None,
 5861                request_timeout,
 5862                cx.background_executor().clone(),
 5863                request.to_proto(project_id, buffer.read(cx)),
 5864            );
 5865            let buffer = buffer.clone();
 5866            cx.spawn(async move |weak_lsp_store, cx| {
 5867                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5868                    return Ok(None);
 5869                };
 5870                let Some(responses) = request_task.await? else {
 5871                    return Ok(None);
 5872                };
 5873                let actions = join_all(responses.payload.into_iter().map(|response| {
 5874                    GetDefinitions { position }.response_from_proto(
 5875                        response.response,
 5876                        lsp_store.clone(),
 5877                        buffer.clone(),
 5878                        cx.clone(),
 5879                    )
 5880                }))
 5881                .await;
 5882
 5883                Ok(Some(
 5884                    actions
 5885                        .into_iter()
 5886                        .collect::<Result<Vec<Vec<_>>>>()?
 5887                        .into_iter()
 5888                        .flatten()
 5889                        .dedup()
 5890                        .collect(),
 5891                ))
 5892            })
 5893        } else {
 5894            let definitions_task = self.request_multiple_lsp_locally(
 5895                buffer,
 5896                Some(position),
 5897                GetDefinitions { position },
 5898                cx,
 5899            );
 5900            cx.background_spawn(async move {
 5901                Ok(Some(
 5902                    definitions_task
 5903                        .await
 5904                        .into_iter()
 5905                        .flat_map(|(_, definitions)| definitions)
 5906                        .dedup()
 5907                        .collect(),
 5908                ))
 5909            })
 5910        }
 5911    }
 5912
 5913    pub fn declarations(
 5914        &mut self,
 5915        buffer: &Entity<Buffer>,
 5916        position: PointUtf16,
 5917        cx: &mut Context<Self>,
 5918    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5919        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5920            let request = GetDeclarations { position };
 5921            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5922                return Task::ready(Ok(None));
 5923            }
 5924            let request_timeout = ProjectSettings::get_global(cx)
 5925                .global_lsp_settings
 5926                .get_request_timeout();
 5927            let request_task = upstream_client.request_lsp(
 5928                project_id,
 5929                None,
 5930                request_timeout,
 5931                cx.background_executor().clone(),
 5932                request.to_proto(project_id, buffer.read(cx)),
 5933            );
 5934            let buffer = buffer.clone();
 5935            cx.spawn(async move |weak_lsp_store, cx| {
 5936                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5937                    return Ok(None);
 5938                };
 5939                let Some(responses) = request_task.await? else {
 5940                    return Ok(None);
 5941                };
 5942                let actions = join_all(responses.payload.into_iter().map(|response| {
 5943                    GetDeclarations { position }.response_from_proto(
 5944                        response.response,
 5945                        lsp_store.clone(),
 5946                        buffer.clone(),
 5947                        cx.clone(),
 5948                    )
 5949                }))
 5950                .await;
 5951
 5952                Ok(Some(
 5953                    actions
 5954                        .into_iter()
 5955                        .collect::<Result<Vec<Vec<_>>>>()?
 5956                        .into_iter()
 5957                        .flatten()
 5958                        .dedup()
 5959                        .collect(),
 5960                ))
 5961            })
 5962        } else {
 5963            let declarations_task = self.request_multiple_lsp_locally(
 5964                buffer,
 5965                Some(position),
 5966                GetDeclarations { position },
 5967                cx,
 5968            );
 5969            cx.background_spawn(async move {
 5970                Ok(Some(
 5971                    declarations_task
 5972                        .await
 5973                        .into_iter()
 5974                        .flat_map(|(_, declarations)| declarations)
 5975                        .dedup()
 5976                        .collect(),
 5977                ))
 5978            })
 5979        }
 5980    }
 5981
 5982    pub fn type_definitions(
 5983        &mut self,
 5984        buffer: &Entity<Buffer>,
 5985        position: PointUtf16,
 5986        cx: &mut Context<Self>,
 5987    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5988        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5989            let request = GetTypeDefinitions { position };
 5990            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5991                return Task::ready(Ok(None));
 5992            }
 5993            let request_timeout = ProjectSettings::get_global(cx)
 5994                .global_lsp_settings
 5995                .get_request_timeout();
 5996            let request_task = upstream_client.request_lsp(
 5997                project_id,
 5998                None,
 5999                request_timeout,
 6000                cx.background_executor().clone(),
 6001                request.to_proto(project_id, buffer.read(cx)),
 6002            );
 6003            let buffer = buffer.clone();
 6004            cx.spawn(async move |weak_lsp_store, cx| {
 6005                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6006                    return Ok(None);
 6007                };
 6008                let Some(responses) = request_task.await? else {
 6009                    return Ok(None);
 6010                };
 6011                let actions = join_all(responses.payload.into_iter().map(|response| {
 6012                    GetTypeDefinitions { position }.response_from_proto(
 6013                        response.response,
 6014                        lsp_store.clone(),
 6015                        buffer.clone(),
 6016                        cx.clone(),
 6017                    )
 6018                }))
 6019                .await;
 6020
 6021                Ok(Some(
 6022                    actions
 6023                        .into_iter()
 6024                        .collect::<Result<Vec<Vec<_>>>>()?
 6025                        .into_iter()
 6026                        .flatten()
 6027                        .dedup()
 6028                        .collect(),
 6029                ))
 6030            })
 6031        } else {
 6032            let type_definitions_task = self.request_multiple_lsp_locally(
 6033                buffer,
 6034                Some(position),
 6035                GetTypeDefinitions { position },
 6036                cx,
 6037            );
 6038            cx.background_spawn(async move {
 6039                Ok(Some(
 6040                    type_definitions_task
 6041                        .await
 6042                        .into_iter()
 6043                        .flat_map(|(_, type_definitions)| type_definitions)
 6044                        .dedup()
 6045                        .collect(),
 6046                ))
 6047            })
 6048        }
 6049    }
 6050
 6051    pub fn implementations(
 6052        &mut self,
 6053        buffer: &Entity<Buffer>,
 6054        position: PointUtf16,
 6055        cx: &mut Context<Self>,
 6056    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6057        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6058            let request = GetImplementations { position };
 6059            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6060                return Task::ready(Ok(None));
 6061            }
 6062
 6063            let request_timeout = ProjectSettings::get_global(cx)
 6064                .global_lsp_settings
 6065                .get_request_timeout();
 6066            let request_task = upstream_client.request_lsp(
 6067                project_id,
 6068                None,
 6069                request_timeout,
 6070                cx.background_executor().clone(),
 6071                request.to_proto(project_id, buffer.read(cx)),
 6072            );
 6073            let buffer = buffer.clone();
 6074            cx.spawn(async move |weak_lsp_store, cx| {
 6075                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6076                    return Ok(None);
 6077                };
 6078                let Some(responses) = request_task.await? else {
 6079                    return Ok(None);
 6080                };
 6081                let actions = join_all(responses.payload.into_iter().map(|response| {
 6082                    GetImplementations { position }.response_from_proto(
 6083                        response.response,
 6084                        lsp_store.clone(),
 6085                        buffer.clone(),
 6086                        cx.clone(),
 6087                    )
 6088                }))
 6089                .await;
 6090
 6091                Ok(Some(
 6092                    actions
 6093                        .into_iter()
 6094                        .collect::<Result<Vec<Vec<_>>>>()?
 6095                        .into_iter()
 6096                        .flatten()
 6097                        .dedup()
 6098                        .collect(),
 6099                ))
 6100            })
 6101        } else {
 6102            let implementations_task = self.request_multiple_lsp_locally(
 6103                buffer,
 6104                Some(position),
 6105                GetImplementations { position },
 6106                cx,
 6107            );
 6108            cx.background_spawn(async move {
 6109                Ok(Some(
 6110                    implementations_task
 6111                        .await
 6112                        .into_iter()
 6113                        .flat_map(|(_, implementations)| implementations)
 6114                        .dedup()
 6115                        .collect(),
 6116                ))
 6117            })
 6118        }
 6119    }
 6120
 6121    pub fn references(
 6122        &mut self,
 6123        buffer: &Entity<Buffer>,
 6124        position: PointUtf16,
 6125        cx: &mut Context<Self>,
 6126    ) -> Task<Result<Option<Vec<Location>>>> {
 6127        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6128            let request = GetReferences { position };
 6129            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6130                return Task::ready(Ok(None));
 6131            }
 6132
 6133            let request_timeout = ProjectSettings::get_global(cx)
 6134                .global_lsp_settings
 6135                .get_request_timeout();
 6136            let request_task = upstream_client.request_lsp(
 6137                project_id,
 6138                None,
 6139                request_timeout,
 6140                cx.background_executor().clone(),
 6141                request.to_proto(project_id, buffer.read(cx)),
 6142            );
 6143            let buffer = buffer.clone();
 6144            cx.spawn(async move |weak_lsp_store, cx| {
 6145                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6146                    return Ok(None);
 6147                };
 6148                let Some(responses) = request_task.await? else {
 6149                    return Ok(None);
 6150                };
 6151
 6152                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6153                    GetReferences { position }.response_from_proto(
 6154                        lsp_response.response,
 6155                        lsp_store.clone(),
 6156                        buffer.clone(),
 6157                        cx.clone(),
 6158                    )
 6159                }))
 6160                .await
 6161                .into_iter()
 6162                .collect::<Result<Vec<Vec<_>>>>()?
 6163                .into_iter()
 6164                .flatten()
 6165                .dedup()
 6166                .collect();
 6167                Ok(Some(locations))
 6168            })
 6169        } else {
 6170            let references_task = self.request_multiple_lsp_locally(
 6171                buffer,
 6172                Some(position),
 6173                GetReferences { position },
 6174                cx,
 6175            );
 6176            cx.background_spawn(async move {
 6177                Ok(Some(
 6178                    references_task
 6179                        .await
 6180                        .into_iter()
 6181                        .flat_map(|(_, references)| references)
 6182                        .dedup()
 6183                        .collect(),
 6184                ))
 6185            })
 6186        }
 6187    }
 6188
 6189    pub fn code_actions(
 6190        &mut self,
 6191        buffer: &Entity<Buffer>,
 6192        range: Range<Anchor>,
 6193        kinds: Option<Vec<CodeActionKind>>,
 6194        cx: &mut Context<Self>,
 6195    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6196        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6197            let request = GetCodeActions {
 6198                range: range.clone(),
 6199                kinds: kinds.clone(),
 6200            };
 6201            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6202                return Task::ready(Ok(None));
 6203            }
 6204            let request_timeout = ProjectSettings::get_global(cx)
 6205                .global_lsp_settings
 6206                .get_request_timeout();
 6207            let request_task = upstream_client.request_lsp(
 6208                project_id,
 6209                None,
 6210                request_timeout,
 6211                cx.background_executor().clone(),
 6212                request.to_proto(project_id, buffer.read(cx)),
 6213            );
 6214            let buffer = buffer.clone();
 6215            cx.spawn(async move |weak_lsp_store, cx| {
 6216                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6217                    return Ok(None);
 6218                };
 6219                let Some(responses) = request_task.await? else {
 6220                    return Ok(None);
 6221                };
 6222                let actions = join_all(responses.payload.into_iter().map(|response| {
 6223                    GetCodeActions {
 6224                        range: range.clone(),
 6225                        kinds: kinds.clone(),
 6226                    }
 6227                    .response_from_proto(
 6228                        response.response,
 6229                        lsp_store.clone(),
 6230                        buffer.clone(),
 6231                        cx.clone(),
 6232                    )
 6233                }))
 6234                .await;
 6235
 6236                Ok(Some(
 6237                    actions
 6238                        .into_iter()
 6239                        .collect::<Result<Vec<Vec<_>>>>()?
 6240                        .into_iter()
 6241                        .flatten()
 6242                        .collect(),
 6243                ))
 6244            })
 6245        } else {
 6246            let all_actions_task = self.request_multiple_lsp_locally(
 6247                buffer,
 6248                Some(range.start),
 6249                GetCodeActions { range, kinds },
 6250                cx,
 6251            );
 6252            cx.background_spawn(async move {
 6253                Ok(Some(
 6254                    all_actions_task
 6255                        .await
 6256                        .into_iter()
 6257                        .flat_map(|(_, actions)| actions)
 6258                        .collect(),
 6259                ))
 6260            })
 6261        }
 6262    }
 6263
 6264    #[inline(never)]
 6265    pub fn completions(
 6266        &self,
 6267        buffer: &Entity<Buffer>,
 6268        position: PointUtf16,
 6269        context: CompletionContext,
 6270        cx: &mut Context<Self>,
 6271    ) -> Task<Result<Vec<CompletionResponse>>> {
 6272        let language_registry = self.languages.clone();
 6273
 6274        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6275            let snapshot = buffer.read(cx).snapshot();
 6276            let offset = position.to_offset(&snapshot);
 6277            let scope = snapshot.language_scope_at(offset);
 6278            let capable_lsps = self.all_capable_for_proto_request(
 6279                buffer,
 6280                |server_name, capabilities| {
 6281                    capabilities.completion_provider.is_some()
 6282                        && scope
 6283                            .as_ref()
 6284                            .map(|scope| scope.language_allowed(server_name))
 6285                            .unwrap_or(true)
 6286                },
 6287                cx,
 6288            );
 6289            if capable_lsps.is_empty() {
 6290                return Task::ready(Ok(Vec::new()));
 6291            }
 6292
 6293            let language = buffer.read(cx).language().cloned();
 6294
 6295            let buffer = buffer.clone();
 6296
 6297            cx.spawn(async move |this, cx| {
 6298                let requests = join_all(
 6299                    capable_lsps
 6300                        .into_iter()
 6301                        .map(|(id, server_name)| {
 6302                            let request = GetCompletions {
 6303                                position,
 6304                                context: context.clone(),
 6305                                server_id: Some(id),
 6306                            };
 6307                            let buffer = buffer.clone();
 6308                            let language = language.clone();
 6309                            let lsp_adapter = language.as_ref().and_then(|language| {
 6310                                let adapters = language_registry.lsp_adapters(&language.name());
 6311                                adapters
 6312                                    .iter()
 6313                                    .find(|adapter| adapter.name() == server_name)
 6314                                    .or_else(|| adapters.first())
 6315                                    .cloned()
 6316                            });
 6317                            let upstream_client = upstream_client.clone();
 6318                            let response = this
 6319                                .update(cx, |this, cx| {
 6320                                    this.send_lsp_proto_request(
 6321                                        buffer,
 6322                                        upstream_client,
 6323                                        project_id,
 6324                                        request,
 6325                                        cx,
 6326                                    )
 6327                                })
 6328                                .log_err();
 6329                            async move {
 6330                                let response = response?.await.log_err()?;
 6331
 6332                                let completions = populate_labels_for_completions(
 6333                                    response.completions,
 6334                                    language,
 6335                                    lsp_adapter,
 6336                                )
 6337                                .await;
 6338
 6339                                Some(CompletionResponse {
 6340                                    completions,
 6341                                    display_options: CompletionDisplayOptions::default(),
 6342                                    is_incomplete: response.is_incomplete,
 6343                                })
 6344                            }
 6345                        })
 6346                        .collect::<Vec<_>>(),
 6347                );
 6348                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6349            })
 6350        } else if let Some(local) = self.as_local() {
 6351            let snapshot = buffer.read(cx).snapshot();
 6352            let offset = position.to_offset(&snapshot);
 6353            let scope = snapshot.language_scope_at(offset);
 6354            let language = snapshot.language().cloned();
 6355            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6356                .completions
 6357                .clone();
 6358            if !completion_settings.lsp {
 6359                return Task::ready(Ok(Vec::new()));
 6360            }
 6361
 6362            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6363                local
 6364                    .language_servers_for_buffer(buffer, cx)
 6365                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6366                    .filter(|(adapter, _)| {
 6367                        scope
 6368                            .as_ref()
 6369                            .map(|scope| scope.language_allowed(&adapter.name))
 6370                            .unwrap_or(true)
 6371                    })
 6372                    .map(|(_, server)| server.server_id())
 6373                    .collect()
 6374            });
 6375
 6376            let buffer = buffer.clone();
 6377            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6378            let lsp_timeout = if lsp_timeout > 0 {
 6379                Some(Duration::from_millis(lsp_timeout))
 6380            } else {
 6381                None
 6382            };
 6383            cx.spawn(async move |this,  cx| {
 6384                let mut tasks = Vec::with_capacity(server_ids.len());
 6385                this.update(cx, |lsp_store, cx| {
 6386                    for server_id in server_ids {
 6387                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6388                        let lsp_timeout = lsp_timeout
 6389                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6390                        let mut timeout = cx.background_spawn(async move {
 6391                            match lsp_timeout {
 6392                                Some(lsp_timeout) => {
 6393                                    lsp_timeout.await;
 6394                                    true
 6395                                },
 6396                                None => false,
 6397                            }
 6398                        }).fuse();
 6399                        let mut lsp_request = lsp_store.request_lsp(
 6400                            buffer.clone(),
 6401                            LanguageServerToQuery::Other(server_id),
 6402                            GetCompletions {
 6403                                position,
 6404                                context: context.clone(),
 6405                                server_id: Some(server_id),
 6406                            },
 6407                            cx,
 6408                        ).fuse();
 6409                        let new_task = cx.background_spawn(async move {
 6410                            select_biased! {
 6411                                response = lsp_request => anyhow::Ok(Some(response?)),
 6412                                timeout_happened = timeout => {
 6413                                    if timeout_happened {
 6414                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6415                                        Ok(None)
 6416                                    } else {
 6417                                        let completions = lsp_request.await?;
 6418                                        Ok(Some(completions))
 6419                                    }
 6420                                },
 6421                            }
 6422                        });
 6423                        tasks.push((lsp_adapter, new_task));
 6424                    }
 6425                })?;
 6426
 6427                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6428                    let completion_response = task.await.ok()??;
 6429                    let completions = populate_labels_for_completions(
 6430                            completion_response.completions,
 6431                            language.clone(),
 6432                            lsp_adapter,
 6433                        )
 6434                        .await;
 6435                    Some(CompletionResponse {
 6436                        completions,
 6437                        display_options: CompletionDisplayOptions::default(),
 6438                        is_incomplete: completion_response.is_incomplete,
 6439                    })
 6440                });
 6441
 6442                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6443
 6444                Ok(responses.into_iter().flatten().collect())
 6445            })
 6446        } else {
 6447            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6448        }
 6449    }
 6450
 6451    pub fn resolve_completions(
 6452        &self,
 6453        buffer: Entity<Buffer>,
 6454        completion_indices: Vec<usize>,
 6455        completions: Rc<RefCell<Box<[Completion]>>>,
 6456        cx: &mut Context<Self>,
 6457    ) -> Task<Result<bool>> {
 6458        let client = self.upstream_client();
 6459        let buffer_id = buffer.read(cx).remote_id();
 6460        let buffer_snapshot = buffer.read(cx).snapshot();
 6461
 6462        if !self.check_if_capable_for_proto_request(
 6463            &buffer,
 6464            GetCompletions::can_resolve_completions,
 6465            cx,
 6466        ) {
 6467            return Task::ready(Ok(false));
 6468        }
 6469        cx.spawn(async move |lsp_store, cx| {
 6470            let request_timeout = cx.update(|app| {
 6471                ProjectSettings::get_global(app)
 6472                    .global_lsp_settings
 6473                    .get_request_timeout()
 6474            });
 6475
 6476            let mut did_resolve = false;
 6477            if let Some((client, project_id)) = client {
 6478                for completion_index in completion_indices {
 6479                    let server_id = {
 6480                        let completion = &completions.borrow()[completion_index];
 6481                        completion.source.server_id()
 6482                    };
 6483                    if let Some(server_id) = server_id {
 6484                        if Self::resolve_completion_remote(
 6485                            project_id,
 6486                            server_id,
 6487                            buffer_id,
 6488                            completions.clone(),
 6489                            completion_index,
 6490                            client.clone(),
 6491                        )
 6492                        .await
 6493                        .log_err()
 6494                        .is_some()
 6495                        {
 6496                            did_resolve = true;
 6497                        }
 6498                    } else {
 6499                        resolve_word_completion(
 6500                            &buffer_snapshot,
 6501                            &mut completions.borrow_mut()[completion_index],
 6502                        );
 6503                    }
 6504                }
 6505            } else {
 6506                for completion_index in completion_indices {
 6507                    let server_id = {
 6508                        let completion = &completions.borrow()[completion_index];
 6509                        completion.source.server_id()
 6510                    };
 6511                    if let Some(server_id) = server_id {
 6512                        let server_and_adapter = lsp_store
 6513                            .read_with(cx, |lsp_store, _| {
 6514                                let server = lsp_store.language_server_for_id(server_id)?;
 6515                                let adapter =
 6516                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6517                                Some((server, adapter))
 6518                            })
 6519                            .ok()
 6520                            .flatten();
 6521                        let Some((server, adapter)) = server_and_adapter else {
 6522                            continue;
 6523                        };
 6524
 6525                        let resolved = Self::resolve_completion_local(
 6526                            server,
 6527                            completions.clone(),
 6528                            completion_index,
 6529                            request_timeout,
 6530                        )
 6531                        .await
 6532                        .log_err()
 6533                        .is_some();
 6534                        if resolved {
 6535                            Self::regenerate_completion_labels(
 6536                                adapter,
 6537                                &buffer_snapshot,
 6538                                completions.clone(),
 6539                                completion_index,
 6540                            )
 6541                            .await
 6542                            .log_err();
 6543                            did_resolve = true;
 6544                        }
 6545                    } else {
 6546                        resolve_word_completion(
 6547                            &buffer_snapshot,
 6548                            &mut completions.borrow_mut()[completion_index],
 6549                        );
 6550                    }
 6551                }
 6552            }
 6553
 6554            Ok(did_resolve)
 6555        })
 6556    }
 6557
 6558    async fn resolve_completion_local(
 6559        server: Arc<lsp::LanguageServer>,
 6560        completions: Rc<RefCell<Box<[Completion]>>>,
 6561        completion_index: usize,
 6562        request_timeout: Duration,
 6563    ) -> Result<()> {
 6564        let server_id = server.server_id();
 6565        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6566            return Ok(());
 6567        }
 6568
 6569        let request = {
 6570            let completion = &completions.borrow()[completion_index];
 6571            match &completion.source {
 6572                CompletionSource::Lsp {
 6573                    lsp_completion,
 6574                    resolved,
 6575                    server_id: completion_server_id,
 6576                    ..
 6577                } => {
 6578                    if *resolved {
 6579                        return Ok(());
 6580                    }
 6581                    anyhow::ensure!(
 6582                        server_id == *completion_server_id,
 6583                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6584                    );
 6585                    server.request::<lsp::request::ResolveCompletionItem>(
 6586                        *lsp_completion.clone(),
 6587                        request_timeout,
 6588                    )
 6589                }
 6590                CompletionSource::BufferWord { .. }
 6591                | CompletionSource::Dap { .. }
 6592                | CompletionSource::Custom => {
 6593                    return Ok(());
 6594                }
 6595            }
 6596        };
 6597        let resolved_completion = request
 6598            .await
 6599            .into_response()
 6600            .context("resolve completion")?;
 6601
 6602        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6603        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6604
 6605        let mut completions = completions.borrow_mut();
 6606        let completion = &mut completions[completion_index];
 6607        if let CompletionSource::Lsp {
 6608            lsp_completion,
 6609            resolved,
 6610            server_id: completion_server_id,
 6611            ..
 6612        } = &mut completion.source
 6613        {
 6614            if *resolved {
 6615                return Ok(());
 6616            }
 6617            anyhow::ensure!(
 6618                server_id == *completion_server_id,
 6619                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6620            );
 6621            **lsp_completion = resolved_completion;
 6622            *resolved = true;
 6623        }
 6624        Ok(())
 6625    }
 6626
 6627    async fn regenerate_completion_labels(
 6628        adapter: Arc<CachedLspAdapter>,
 6629        snapshot: &BufferSnapshot,
 6630        completions: Rc<RefCell<Box<[Completion]>>>,
 6631        completion_index: usize,
 6632    ) -> Result<()> {
 6633        let completion_item = completions.borrow()[completion_index]
 6634            .source
 6635            .lsp_completion(true)
 6636            .map(Cow::into_owned);
 6637        if let Some(lsp_documentation) = completion_item
 6638            .as_ref()
 6639            .and_then(|completion_item| completion_item.documentation.clone())
 6640        {
 6641            let mut completions = completions.borrow_mut();
 6642            let completion = &mut completions[completion_index];
 6643            completion.documentation = Some(lsp_documentation.into());
 6644        } else {
 6645            let mut completions = completions.borrow_mut();
 6646            let completion = &mut completions[completion_index];
 6647            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6648        }
 6649
 6650        let mut new_label = match completion_item {
 6651            Some(completion_item) => {
 6652                // Some language servers always return `detail` lazily via resolve, regardless of
 6653                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6654                // See: https://github.com/yioneko/vtsls/issues/213
 6655                let language = snapshot.language();
 6656                match language {
 6657                    Some(language) => {
 6658                        adapter
 6659                            .labels_for_completions(
 6660                                std::slice::from_ref(&completion_item),
 6661                                language,
 6662                            )
 6663                            .await?
 6664                    }
 6665                    None => Vec::new(),
 6666                }
 6667                .pop()
 6668                .flatten()
 6669                .unwrap_or_else(|| {
 6670                    CodeLabel::fallback_for_completion(
 6671                        &completion_item,
 6672                        language.map(|language| language.as_ref()),
 6673                    )
 6674                })
 6675            }
 6676            None => CodeLabel::plain(
 6677                completions.borrow()[completion_index].new_text.clone(),
 6678                None,
 6679            ),
 6680        };
 6681        ensure_uniform_list_compatible_label(&mut new_label);
 6682
 6683        let mut completions = completions.borrow_mut();
 6684        let completion = &mut completions[completion_index];
 6685        if completion.label.filter_text() == new_label.filter_text() {
 6686            completion.label = new_label;
 6687        } else {
 6688            log::error!(
 6689                "Resolved completion changed display label from {} to {}. \
 6690                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6691                completion.label.text(),
 6692                new_label.text(),
 6693                completion.label.filter_text(),
 6694                new_label.filter_text()
 6695            );
 6696        }
 6697
 6698        Ok(())
 6699    }
 6700
 6701    async fn resolve_completion_remote(
 6702        project_id: u64,
 6703        server_id: LanguageServerId,
 6704        buffer_id: BufferId,
 6705        completions: Rc<RefCell<Box<[Completion]>>>,
 6706        completion_index: usize,
 6707        client: AnyProtoClient,
 6708    ) -> Result<()> {
 6709        let lsp_completion = {
 6710            let completion = &completions.borrow()[completion_index];
 6711            match &completion.source {
 6712                CompletionSource::Lsp {
 6713                    lsp_completion,
 6714                    resolved,
 6715                    server_id: completion_server_id,
 6716                    ..
 6717                } => {
 6718                    anyhow::ensure!(
 6719                        server_id == *completion_server_id,
 6720                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6721                    );
 6722                    if *resolved {
 6723                        return Ok(());
 6724                    }
 6725                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6726                }
 6727                CompletionSource::Custom
 6728                | CompletionSource::Dap { .. }
 6729                | CompletionSource::BufferWord { .. } => {
 6730                    return Ok(());
 6731                }
 6732            }
 6733        };
 6734        let request = proto::ResolveCompletionDocumentation {
 6735            project_id,
 6736            language_server_id: server_id.0 as u64,
 6737            lsp_completion,
 6738            buffer_id: buffer_id.into(),
 6739        };
 6740
 6741        let response = client
 6742            .request(request)
 6743            .await
 6744            .context("completion documentation resolve proto request")?;
 6745        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6746
 6747        let documentation = if response.documentation.is_empty() {
 6748            CompletionDocumentation::Undocumented
 6749        } else if response.documentation_is_markdown {
 6750            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6751        } else if response.documentation.lines().count() <= 1 {
 6752            CompletionDocumentation::SingleLine(response.documentation.into())
 6753        } else {
 6754            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6755        };
 6756
 6757        let mut completions = completions.borrow_mut();
 6758        let completion = &mut completions[completion_index];
 6759        completion.documentation = Some(documentation);
 6760        if let CompletionSource::Lsp {
 6761            insert_range,
 6762            lsp_completion,
 6763            resolved,
 6764            server_id: completion_server_id,
 6765            lsp_defaults: _,
 6766        } = &mut completion.source
 6767        {
 6768            let completion_insert_range = response
 6769                .old_insert_start
 6770                .and_then(deserialize_anchor)
 6771                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6772            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6773
 6774            if *resolved {
 6775                return Ok(());
 6776            }
 6777            anyhow::ensure!(
 6778                server_id == *completion_server_id,
 6779                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6780            );
 6781            **lsp_completion = resolved_lsp_completion;
 6782            *resolved = true;
 6783        }
 6784
 6785        let replace_range = response
 6786            .old_replace_start
 6787            .and_then(deserialize_anchor)
 6788            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6789        if let Some((old_replace_start, old_replace_end)) = replace_range
 6790            && !response.new_text.is_empty()
 6791        {
 6792            completion.new_text = response.new_text;
 6793            completion.replace_range = old_replace_start..old_replace_end;
 6794        }
 6795
 6796        Ok(())
 6797    }
 6798
 6799    pub fn apply_additional_edits_for_completion(
 6800        &self,
 6801        buffer_handle: Entity<Buffer>,
 6802        completions: Rc<RefCell<Box<[Completion]>>>,
 6803        completion_index: usize,
 6804        push_to_history: bool,
 6805        all_commit_ranges: Vec<Range<language::Anchor>>,
 6806        cx: &mut Context<Self>,
 6807    ) -> Task<Result<Option<Transaction>>> {
 6808        if let Some((client, project_id)) = self.upstream_client() {
 6809            let buffer = buffer_handle.read(cx);
 6810            let buffer_id = buffer.remote_id();
 6811            cx.spawn(async move |_, cx| {
 6812                let request = {
 6813                    let completion = completions.borrow()[completion_index].clone();
 6814                    proto::ApplyCompletionAdditionalEdits {
 6815                        project_id,
 6816                        buffer_id: buffer_id.into(),
 6817                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6818                            replace_range: completion.replace_range,
 6819                            new_text: completion.new_text,
 6820                            source: completion.source,
 6821                        })),
 6822                        all_commit_ranges: all_commit_ranges
 6823                            .iter()
 6824                            .cloned()
 6825                            .map(language::proto::serialize_anchor_range)
 6826                            .collect(),
 6827                    }
 6828                };
 6829
 6830                let Some(transaction) = client.request(request).await?.transaction else {
 6831                    return Ok(None);
 6832                };
 6833
 6834                let transaction = language::proto::deserialize_transaction(transaction)?;
 6835                buffer_handle
 6836                    .update(cx, |buffer, _| {
 6837                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6838                    })
 6839                    .await?;
 6840                if push_to_history {
 6841                    buffer_handle.update(cx, |buffer, _| {
 6842                        buffer.push_transaction(transaction.clone(), Instant::now());
 6843                        buffer.finalize_last_transaction();
 6844                    });
 6845                }
 6846                Ok(Some(transaction))
 6847            })
 6848        } else {
 6849            let request_timeout = ProjectSettings::get_global(cx)
 6850                .global_lsp_settings
 6851                .get_request_timeout();
 6852
 6853            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6854                let completion = &completions.borrow()[completion_index];
 6855                let server_id = completion.source.server_id()?;
 6856                Some(
 6857                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6858                        .1
 6859                        .clone(),
 6860                )
 6861            }) else {
 6862                return Task::ready(Ok(None));
 6863            };
 6864
 6865            cx.spawn(async move |this, cx| {
 6866                Self::resolve_completion_local(
 6867                    server.clone(),
 6868                    completions.clone(),
 6869                    completion_index,
 6870                    request_timeout,
 6871                )
 6872                .await
 6873                .context("resolving completion")?;
 6874                let completion = completions.borrow()[completion_index].clone();
 6875                let additional_text_edits = completion
 6876                    .source
 6877                    .lsp_completion(true)
 6878                    .as_ref()
 6879                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6880                if let Some(edits) = additional_text_edits {
 6881                    let edits = this
 6882                        .update(cx, |this, cx| {
 6883                            this.as_local_mut().unwrap().edits_from_lsp(
 6884                                &buffer_handle,
 6885                                edits,
 6886                                server.server_id(),
 6887                                None,
 6888                                cx,
 6889                            )
 6890                        })?
 6891                        .await?;
 6892
 6893                    buffer_handle.update(cx, |buffer, cx| {
 6894                        buffer.finalize_last_transaction();
 6895                        buffer.start_transaction();
 6896
 6897                        for (range, text) in edits {
 6898                            let primary = &completion.replace_range;
 6899
 6900                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6901                            // and the primary completion is just an insertion (empty range), then this is likely
 6902                            // an auto-import scenario and should not be considered overlapping
 6903                            // https://github.com/zed-industries/zed/issues/26136
 6904                            let is_file_start_auto_import = {
 6905                                let snapshot = buffer.snapshot();
 6906                                let primary_start_point = primary.start.to_point(&snapshot);
 6907                                let range_start_point = range.start.to_point(&snapshot);
 6908
 6909                                let result = primary_start_point.row == 0
 6910                                    && primary_start_point.column == 0
 6911                                    && range_start_point.row == 0
 6912                                    && range_start_point.column == 0;
 6913
 6914                                result
 6915                            };
 6916
 6917                            let has_overlap = if is_file_start_auto_import {
 6918                                false
 6919                            } else {
 6920                                all_commit_ranges.iter().any(|commit_range| {
 6921                                    let start_within =
 6922                                        commit_range.start.cmp(&range.start, buffer).is_le()
 6923                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 6924                                    let end_within =
 6925                                        range.start.cmp(&commit_range.end, buffer).is_le()
 6926                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 6927                                    start_within || end_within
 6928                                })
 6929                            };
 6930
 6931                            //Skip additional edits which overlap with the primary completion edit
 6932                            //https://github.com/zed-industries/zed/pull/1871
 6933                            if !has_overlap {
 6934                                buffer.edit([(range, text)], None, cx);
 6935                            }
 6936                        }
 6937
 6938                        let transaction = if buffer.end_transaction(cx).is_some() {
 6939                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6940                            if !push_to_history {
 6941                                buffer.forget_transaction(transaction.id);
 6942                            }
 6943                            Some(transaction)
 6944                        } else {
 6945                            None
 6946                        };
 6947                        Ok(transaction)
 6948                    })
 6949                } else {
 6950                    Ok(None)
 6951                }
 6952            })
 6953        }
 6954    }
 6955
 6956    pub fn pull_diagnostics(
 6957        &mut self,
 6958        buffer: Entity<Buffer>,
 6959        cx: &mut Context<Self>,
 6960    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6961        let buffer_id = buffer.read(cx).remote_id();
 6962
 6963        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6964            let mut suitable_capabilities = None;
 6965            // Are we capable for proto request?
 6966            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6967                &buffer,
 6968                |capabilities| {
 6969                    if let Some(caps) = &capabilities.diagnostic_provider {
 6970                        suitable_capabilities = Some(caps.clone());
 6971                        true
 6972                    } else {
 6973                        false
 6974                    }
 6975                },
 6976                cx,
 6977            );
 6978            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6979            let Some(dynamic_caps) = suitable_capabilities else {
 6980                return Task::ready(Ok(None));
 6981            };
 6982            assert!(any_server_has_diagnostics_provider);
 6983
 6984            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6985            let request = GetDocumentDiagnostics {
 6986                previous_result_id: None,
 6987                identifier,
 6988                registration_id: None,
 6989            };
 6990            let request_timeout = ProjectSettings::get_global(cx)
 6991                .global_lsp_settings
 6992                .get_request_timeout();
 6993            let request_task = client.request_lsp(
 6994                upstream_project_id,
 6995                None,
 6996                request_timeout,
 6997                cx.background_executor().clone(),
 6998                request.to_proto(upstream_project_id, buffer.read(cx)),
 6999            );
 7000            cx.background_spawn(async move {
 7001                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 7002                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 7003                // Do not attempt to further process the dummy responses here.
 7004                let _response = request_task.await?;
 7005                Ok(None)
 7006            })
 7007        } else {
 7008            let servers = buffer.update(cx, |buffer, cx| {
 7009                self.running_language_servers_for_local_buffer(buffer, cx)
 7010                    .map(|(_, server)| server.clone())
 7011                    .collect::<Vec<_>>()
 7012            });
 7013
 7014            let pull_diagnostics = servers
 7015                .into_iter()
 7016                .flat_map(|server| {
 7017                    let result = maybe!({
 7018                        let local = self.as_local()?;
 7019                        let server_id = server.server_id();
 7020                        let providers_with_identifiers = local
 7021                            .language_server_dynamic_registrations
 7022                            .get(&server_id)
 7023                            .into_iter()
 7024                            .flat_map(|registrations| registrations.diagnostics.clone())
 7025                            .collect::<Vec<_>>();
 7026                        Some(
 7027                            providers_with_identifiers
 7028                                .into_iter()
 7029                                .map(|(registration_id, dynamic_caps)| {
 7030                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7031                                    let registration_id = registration_id.map(SharedString::from);
 7032                                    let result_id = self.result_id_for_buffer_pull(
 7033                                        server_id,
 7034                                        buffer_id,
 7035                                        &registration_id,
 7036                                        cx,
 7037                                    );
 7038                                    self.request_lsp(
 7039                                        buffer.clone(),
 7040                                        LanguageServerToQuery::Other(server_id),
 7041                                        GetDocumentDiagnostics {
 7042                                            previous_result_id: result_id,
 7043                                            registration_id,
 7044                                            identifier,
 7045                                        },
 7046                                        cx,
 7047                                    )
 7048                                })
 7049                                .collect::<Vec<_>>(),
 7050                        )
 7051                    });
 7052
 7053                    result.unwrap_or_default()
 7054                })
 7055                .collect::<Vec<_>>();
 7056
 7057            cx.background_spawn(async move {
 7058                let mut responses = Vec::new();
 7059                for diagnostics in join_all(pull_diagnostics).await {
 7060                    responses.extend(diagnostics?);
 7061                }
 7062                Ok(Some(responses))
 7063            })
 7064        }
 7065    }
 7066
 7067    pub fn applicable_inlay_chunks(
 7068        &mut self,
 7069        buffer: &Entity<Buffer>,
 7070        ranges: &[Range<text::Anchor>],
 7071        cx: &mut Context<Self>,
 7072    ) -> Vec<Range<BufferRow>> {
 7073        let buffer_snapshot = buffer.read(cx).snapshot();
 7074        let ranges = ranges
 7075            .iter()
 7076            .map(|range| range.to_point(&buffer_snapshot))
 7077            .collect::<Vec<_>>();
 7078
 7079        self.latest_lsp_data(buffer, cx)
 7080            .inlay_hints
 7081            .applicable_chunks(ranges.as_slice())
 7082            .map(|chunk| chunk.row_range())
 7083            .collect()
 7084    }
 7085
 7086    pub fn invalidate_inlay_hints<'a>(
 7087        &'a mut self,
 7088        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7089    ) {
 7090        for buffer_id in for_buffers {
 7091            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7092                lsp_data.inlay_hints.clear();
 7093            }
 7094        }
 7095    }
 7096
 7097    pub fn inlay_hints(
 7098        &mut self,
 7099        invalidate: InvalidationStrategy,
 7100        buffer: Entity<Buffer>,
 7101        ranges: Vec<Range<text::Anchor>>,
 7102        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7103        cx: &mut Context<Self>,
 7104    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7105        let next_hint_id = self.next_hint_id.clone();
 7106        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7107        let query_version = lsp_data.buffer_version.clone();
 7108        let mut lsp_refresh_requested = false;
 7109        let for_server = if let InvalidationStrategy::RefreshRequested {
 7110            server_id,
 7111            request_id,
 7112        } = invalidate
 7113        {
 7114            let invalidated = lsp_data
 7115                .inlay_hints
 7116                .invalidate_for_server_refresh(server_id, request_id);
 7117            lsp_refresh_requested = invalidated;
 7118            Some(server_id)
 7119        } else {
 7120            None
 7121        };
 7122        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7123        let known_chunks = known_chunks
 7124            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7125            .map(|(_, known_chunks)| known_chunks)
 7126            .unwrap_or_default();
 7127
 7128        let buffer_snapshot = buffer.read(cx).snapshot();
 7129        let ranges = ranges
 7130            .iter()
 7131            .map(|range| range.to_point(&buffer_snapshot))
 7132            .collect::<Vec<_>>();
 7133
 7134        let mut hint_fetch_tasks = Vec::new();
 7135        let mut cached_inlay_hints = None;
 7136        let mut ranges_to_query = None;
 7137        let applicable_chunks = existing_inlay_hints
 7138            .applicable_chunks(ranges.as_slice())
 7139            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7140            .collect::<Vec<_>>();
 7141        if applicable_chunks.is_empty() {
 7142            return HashMap::default();
 7143        }
 7144
 7145        for row_chunk in applicable_chunks {
 7146            match (
 7147                existing_inlay_hints
 7148                    .cached_hints(&row_chunk)
 7149                    .filter(|_| !lsp_refresh_requested)
 7150                    .cloned(),
 7151                existing_inlay_hints
 7152                    .fetched_hints(&row_chunk)
 7153                    .as_ref()
 7154                    .filter(|_| !lsp_refresh_requested)
 7155                    .cloned(),
 7156            ) {
 7157                (None, None) => {
 7158                    let chunk_range = row_chunk.anchor_range();
 7159                    ranges_to_query
 7160                        .get_or_insert_with(Vec::new)
 7161                        .push((row_chunk, chunk_range));
 7162                }
 7163                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7164                (Some(cached_hints), None) => {
 7165                    for (server_id, cached_hints) in cached_hints {
 7166                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7167                            cached_inlay_hints
 7168                                .get_or_insert_with(HashMap::default)
 7169                                .entry(row_chunk.row_range())
 7170                                .or_insert_with(HashMap::default)
 7171                                .entry(server_id)
 7172                                .or_insert_with(Vec::new)
 7173                                .extend(cached_hints);
 7174                        }
 7175                    }
 7176                }
 7177                (Some(cached_hints), Some(fetched_hints)) => {
 7178                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7179                    for (server_id, cached_hints) in cached_hints {
 7180                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7181                            cached_inlay_hints
 7182                                .get_or_insert_with(HashMap::default)
 7183                                .entry(row_chunk.row_range())
 7184                                .or_insert_with(HashMap::default)
 7185                                .entry(server_id)
 7186                                .or_insert_with(Vec::new)
 7187                                .extend(cached_hints);
 7188                        }
 7189                    }
 7190                }
 7191            }
 7192        }
 7193
 7194        if hint_fetch_tasks.is_empty()
 7195            && ranges_to_query
 7196                .as_ref()
 7197                .is_none_or(|ranges| ranges.is_empty())
 7198            && let Some(cached_inlay_hints) = cached_inlay_hints
 7199        {
 7200            cached_inlay_hints
 7201                .into_iter()
 7202                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7203                .collect()
 7204        } else {
 7205            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7206                // When a server refresh was requested, other servers' cached hints
 7207                // are unaffected by the refresh and must be included in the result.
 7208                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7209                // removes all visible hints but only adds back the requesting
 7210                // server's new hints, permanently losing other servers' hints.
 7211                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7212                    lsp_data
 7213                        .inlay_hints
 7214                        .cached_hints(&chunk)
 7215                        .cloned()
 7216                        .unwrap_or_default()
 7217                } else {
 7218                    HashMap::default()
 7219                };
 7220
 7221                let next_hint_id = next_hint_id.clone();
 7222                let buffer = buffer.clone();
 7223                let query_version = query_version.clone();
 7224                let new_inlay_hints = cx
 7225                    .spawn(async move |lsp_store, cx| {
 7226                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7227                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7228                        })?;
 7229                        new_fetch_task
 7230                            .await
 7231                            .and_then(|new_hints_by_server| {
 7232                                lsp_store.update(cx, |lsp_store, cx| {
 7233                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7234                                    let update_cache = lsp_data.buffer_version == query_version;
 7235                                    if new_hints_by_server.is_empty() {
 7236                                        if update_cache {
 7237                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7238                                        }
 7239                                        other_servers_cached
 7240                                    } else {
 7241                                        let mut result = other_servers_cached;
 7242                                        for (server_id, new_hints) in new_hints_by_server {
 7243                                            let new_hints = new_hints
 7244                                                .into_iter()
 7245                                                .map(|new_hint| {
 7246                                                    (
 7247                                                        InlayId::Hint(next_hint_id.fetch_add(
 7248                                                            1,
 7249                                                            atomic::Ordering::AcqRel,
 7250                                                        )),
 7251                                                        new_hint,
 7252                                                    )
 7253                                                })
 7254                                                .collect::<Vec<_>>();
 7255                                            if update_cache {
 7256                                                lsp_data.inlay_hints.insert_new_hints(
 7257                                                    chunk,
 7258                                                    server_id,
 7259                                                    new_hints.clone(),
 7260                                                );
 7261                                            }
 7262                                            result.insert(server_id, new_hints);
 7263                                        }
 7264                                        result
 7265                                    }
 7266                                })
 7267                            })
 7268                            .map_err(Arc::new)
 7269                    })
 7270                    .shared();
 7271
 7272                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7273                *fetch_task = Some(new_inlay_hints.clone());
 7274                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7275            }
 7276
 7277            cached_inlay_hints
 7278                .unwrap_or_default()
 7279                .into_iter()
 7280                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7281                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7282                    (
 7283                        chunk.row_range(),
 7284                        cx.spawn(async move |_, _| {
 7285                            hints_fetch.await.map_err(|e| {
 7286                                if e.error_code() != ErrorCode::Internal {
 7287                                    anyhow!(e.error_code())
 7288                                } else {
 7289                                    anyhow!("{e:#}")
 7290                                }
 7291                            })
 7292                        }),
 7293                    )
 7294                }))
 7295                .collect()
 7296        }
 7297    }
 7298
 7299    fn fetch_inlay_hints(
 7300        &mut self,
 7301        for_server: Option<LanguageServerId>,
 7302        buffer: &Entity<Buffer>,
 7303        range: Range<Anchor>,
 7304        cx: &mut Context<Self>,
 7305    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7306        let request = InlayHints {
 7307            range: range.clone(),
 7308        };
 7309        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7310            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7311                return Task::ready(Ok(HashMap::default()));
 7312            }
 7313            let request_timeout = ProjectSettings::get_global(cx)
 7314                .global_lsp_settings
 7315                .get_request_timeout();
 7316            let request_task = upstream_client.request_lsp(
 7317                project_id,
 7318                for_server.map(|id| id.to_proto()),
 7319                request_timeout,
 7320                cx.background_executor().clone(),
 7321                request.to_proto(project_id, buffer.read(cx)),
 7322            );
 7323            let buffer = buffer.clone();
 7324            cx.spawn(async move |weak_lsp_store, cx| {
 7325                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7326                    return Ok(HashMap::default());
 7327                };
 7328                let Some(responses) = request_task.await? else {
 7329                    return Ok(HashMap::default());
 7330                };
 7331
 7332                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7333                    let lsp_store = lsp_store.clone();
 7334                    let buffer = buffer.clone();
 7335                    let cx = cx.clone();
 7336                    let request = request.clone();
 7337                    async move {
 7338                        (
 7339                            LanguageServerId::from_proto(response.server_id),
 7340                            request
 7341                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7342                                .await,
 7343                        )
 7344                    }
 7345                }))
 7346                .await;
 7347
 7348                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7349                let mut has_errors = false;
 7350                let inlay_hints = inlay_hints
 7351                    .into_iter()
 7352                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7353                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7354                        Err(e) => {
 7355                            has_errors = true;
 7356                            log::error!("{e:#}");
 7357                            None
 7358                        }
 7359                    })
 7360                    .map(|(server_id, mut new_hints)| {
 7361                        new_hints.retain(|hint| {
 7362                            hint.position.is_valid(&buffer_snapshot)
 7363                                && range.start.is_valid(&buffer_snapshot)
 7364                                && range.end.is_valid(&buffer_snapshot)
 7365                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7366                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7367                        });
 7368                        (server_id, new_hints)
 7369                    })
 7370                    .collect::<HashMap<_, _>>();
 7371                anyhow::ensure!(
 7372                    !has_errors || !inlay_hints.is_empty(),
 7373                    "Failed to fetch inlay hints"
 7374                );
 7375                Ok(inlay_hints)
 7376            })
 7377        } else {
 7378            let inlay_hints_task = match for_server {
 7379                Some(server_id) => {
 7380                    let server_task = self.request_lsp(
 7381                        buffer.clone(),
 7382                        LanguageServerToQuery::Other(server_id),
 7383                        request,
 7384                        cx,
 7385                    );
 7386                    cx.background_spawn(async move {
 7387                        let mut responses = Vec::new();
 7388                        match server_task.await {
 7389                            Ok(response) => responses.push((server_id, response)),
 7390                            // rust-analyzer likes to error with this when its still loading up
 7391                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7392                            Err(e) => log::error!(
 7393                                "Error handling response for inlay hints request: {e:#}"
 7394                            ),
 7395                        }
 7396                        responses
 7397                    })
 7398                }
 7399                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7400            };
 7401            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7402            cx.background_spawn(async move {
 7403                Ok(inlay_hints_task
 7404                    .await
 7405                    .into_iter()
 7406                    .map(|(server_id, mut new_hints)| {
 7407                        new_hints.retain(|hint| {
 7408                            hint.position.is_valid(&buffer_snapshot)
 7409                                && range.start.is_valid(&buffer_snapshot)
 7410                                && range.end.is_valid(&buffer_snapshot)
 7411                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7412                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7413                        });
 7414                        (server_id, new_hints)
 7415                    })
 7416                    .collect())
 7417            })
 7418        }
 7419    }
 7420
 7421    fn diagnostic_registration_exists(
 7422        &self,
 7423        server_id: LanguageServerId,
 7424        registration_id: &Option<SharedString>,
 7425    ) -> bool {
 7426        let Some(local) = self.as_local() else {
 7427            return false;
 7428        };
 7429        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7430        else {
 7431            return false;
 7432        };
 7433        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7434        registrations.diagnostics.contains_key(&registration_key)
 7435    }
 7436
 7437    pub fn pull_diagnostics_for_buffer(
 7438        &mut self,
 7439        buffer: Entity<Buffer>,
 7440        cx: &mut Context<Self>,
 7441    ) -> Task<anyhow::Result<()>> {
 7442        let diagnostics = self.pull_diagnostics(buffer, cx);
 7443        cx.spawn(async move |lsp_store, cx| {
 7444            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7445                return Ok(());
 7446            };
 7447            lsp_store.update(cx, |lsp_store, cx| {
 7448                if lsp_store.as_local().is_none() {
 7449                    return;
 7450                }
 7451
 7452                let mut unchanged_buffers = HashMap::default();
 7453                let server_diagnostics_updates = diagnostics
 7454                    .into_iter()
 7455                    .filter_map(|diagnostics_set| match diagnostics_set {
 7456                        LspPullDiagnostics::Response {
 7457                            server_id,
 7458                            uri,
 7459                            diagnostics,
 7460                            registration_id,
 7461                        } => Some((server_id, uri, diagnostics, registration_id)),
 7462                        LspPullDiagnostics::Default => None,
 7463                    })
 7464                    .filter(|(server_id, _, _, registration_id)| {
 7465                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7466                    })
 7467                    .fold(
 7468                        HashMap::default(),
 7469                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7470                            let (result_id, diagnostics) = match diagnostics {
 7471                                PulledDiagnostics::Unchanged { result_id } => {
 7472                                    unchanged_buffers
 7473                                        .entry(new_registration_id.clone())
 7474                                        .or_insert_with(HashSet::default)
 7475                                        .insert(uri.clone());
 7476                                    (Some(result_id), Vec::new())
 7477                                }
 7478                                PulledDiagnostics::Changed {
 7479                                    result_id,
 7480                                    diagnostics,
 7481                                } => (result_id, diagnostics),
 7482                            };
 7483                            let disk_based_sources = Cow::Owned(
 7484                                lsp_store
 7485                                    .language_server_adapter_for_id(server_id)
 7486                                    .as_ref()
 7487                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7488                                    .unwrap_or(&[])
 7489                                    .to_vec(),
 7490                            );
 7491                            acc.entry(server_id)
 7492                                .or_insert_with(HashMap::default)
 7493                                .entry(new_registration_id.clone())
 7494                                .or_insert_with(Vec::new)
 7495                                .push(DocumentDiagnosticsUpdate {
 7496                                    server_id,
 7497                                    diagnostics: lsp::PublishDiagnosticsParams {
 7498                                        uri,
 7499                                        diagnostics,
 7500                                        version: None,
 7501                                    },
 7502                                    result_id: result_id.map(SharedString::new),
 7503                                    disk_based_sources,
 7504                                    registration_id: new_registration_id,
 7505                                });
 7506                            acc
 7507                        },
 7508                    );
 7509
 7510                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7511                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7512                        lsp_store
 7513                            .merge_lsp_diagnostics(
 7514                                DiagnosticSourceKind::Pulled,
 7515                                diagnostic_updates,
 7516                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7517                                    DiagnosticSourceKind::Pulled => {
 7518                                        old_diagnostic.registration_id != registration_id
 7519                                            || unchanged_buffers
 7520                                                .get(&old_diagnostic.registration_id)
 7521                                                .is_some_and(|unchanged_buffers| {
 7522                                                    unchanged_buffers.contains(&document_uri)
 7523                                                })
 7524                                    }
 7525                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7526                                        true
 7527                                    }
 7528                                },
 7529                                cx,
 7530                            )
 7531                            .log_err();
 7532                    }
 7533                }
 7534            })
 7535        })
 7536    }
 7537
 7538    pub fn signature_help<T: ToPointUtf16>(
 7539        &mut self,
 7540        buffer: &Entity<Buffer>,
 7541        position: T,
 7542        cx: &mut Context<Self>,
 7543    ) -> Task<Option<Vec<SignatureHelp>>> {
 7544        let position = position.to_point_utf16(buffer.read(cx));
 7545
 7546        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7547            let request = GetSignatureHelp { position };
 7548            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7549                return Task::ready(None);
 7550            }
 7551            let request_timeout = ProjectSettings::get_global(cx)
 7552                .global_lsp_settings
 7553                .get_request_timeout();
 7554            let request_task = client.request_lsp(
 7555                upstream_project_id,
 7556                None,
 7557                request_timeout,
 7558                cx.background_executor().clone(),
 7559                request.to_proto(upstream_project_id, buffer.read(cx)),
 7560            );
 7561            let buffer = buffer.clone();
 7562            cx.spawn(async move |weak_lsp_store, cx| {
 7563                let lsp_store = weak_lsp_store.upgrade()?;
 7564                let signatures = join_all(
 7565                    request_task
 7566                        .await
 7567                        .log_err()
 7568                        .flatten()
 7569                        .map(|response| response.payload)
 7570                        .unwrap_or_default()
 7571                        .into_iter()
 7572                        .map(|response| {
 7573                            let response = GetSignatureHelp { position }.response_from_proto(
 7574                                response.response,
 7575                                lsp_store.clone(),
 7576                                buffer.clone(),
 7577                                cx.clone(),
 7578                            );
 7579                            async move { response.await.log_err().flatten() }
 7580                        }),
 7581                )
 7582                .await
 7583                .into_iter()
 7584                .flatten()
 7585                .collect();
 7586                Some(signatures)
 7587            })
 7588        } else {
 7589            let all_actions_task = self.request_multiple_lsp_locally(
 7590                buffer,
 7591                Some(position),
 7592                GetSignatureHelp { position },
 7593                cx,
 7594            );
 7595            cx.background_spawn(async move {
 7596                Some(
 7597                    all_actions_task
 7598                        .await
 7599                        .into_iter()
 7600                        .flat_map(|(_, actions)| actions)
 7601                        .collect::<Vec<_>>(),
 7602                )
 7603            })
 7604        }
 7605    }
 7606
 7607    pub fn hover(
 7608        &mut self,
 7609        buffer: &Entity<Buffer>,
 7610        position: PointUtf16,
 7611        cx: &mut Context<Self>,
 7612    ) -> Task<Option<Vec<Hover>>> {
 7613        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7614            let request = GetHover { position };
 7615            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7616                return Task::ready(None);
 7617            }
 7618            let request_timeout = ProjectSettings::get_global(cx)
 7619                .global_lsp_settings
 7620                .get_request_timeout();
 7621            let request_task = client.request_lsp(
 7622                upstream_project_id,
 7623                None,
 7624                request_timeout,
 7625                cx.background_executor().clone(),
 7626                request.to_proto(upstream_project_id, buffer.read(cx)),
 7627            );
 7628            let buffer = buffer.clone();
 7629            cx.spawn(async move |weak_lsp_store, cx| {
 7630                let lsp_store = weak_lsp_store.upgrade()?;
 7631                let hovers = join_all(
 7632                    request_task
 7633                        .await
 7634                        .log_err()
 7635                        .flatten()
 7636                        .map(|response| response.payload)
 7637                        .unwrap_or_default()
 7638                        .into_iter()
 7639                        .map(|response| {
 7640                            let response = GetHover { position }.response_from_proto(
 7641                                response.response,
 7642                                lsp_store.clone(),
 7643                                buffer.clone(),
 7644                                cx.clone(),
 7645                            );
 7646                            async move {
 7647                                response
 7648                                    .await
 7649                                    .log_err()
 7650                                    .flatten()
 7651                                    .and_then(remove_empty_hover_blocks)
 7652                            }
 7653                        }),
 7654                )
 7655                .await
 7656                .into_iter()
 7657                .flatten()
 7658                .collect();
 7659                Some(hovers)
 7660            })
 7661        } else {
 7662            let all_actions_task = self.request_multiple_lsp_locally(
 7663                buffer,
 7664                Some(position),
 7665                GetHover { position },
 7666                cx,
 7667            );
 7668            cx.background_spawn(async move {
 7669                Some(
 7670                    all_actions_task
 7671                        .await
 7672                        .into_iter()
 7673                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7674                        .collect::<Vec<Hover>>(),
 7675                )
 7676            })
 7677        }
 7678    }
 7679
 7680    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7681        let language_registry = self.languages.clone();
 7682
 7683        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7684            let request = upstream_client.request(proto::GetProjectSymbols {
 7685                project_id: *project_id,
 7686                query: query.to_string(),
 7687            });
 7688            cx.foreground_executor().spawn(async move {
 7689                let response = request.await?;
 7690                let mut symbols = Vec::new();
 7691                let core_symbols = response
 7692                    .symbols
 7693                    .into_iter()
 7694                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7695                    .collect::<Vec<_>>();
 7696                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7697                    .await;
 7698                Ok(symbols)
 7699            })
 7700        } else if let Some(local) = self.as_local() {
 7701            struct WorkspaceSymbolsResult {
 7702                server_id: LanguageServerId,
 7703                lsp_adapter: Arc<CachedLspAdapter>,
 7704                worktree: WeakEntity<Worktree>,
 7705                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7706            }
 7707
 7708            let mut requests = Vec::new();
 7709            let mut requested_servers = BTreeSet::new();
 7710            let request_timeout = ProjectSettings::get_global(cx)
 7711                .global_lsp_settings
 7712                .get_request_timeout();
 7713
 7714            for (seed, state) in local.language_server_ids.iter() {
 7715                let Some(worktree_handle) = self
 7716                    .worktree_store
 7717                    .read(cx)
 7718                    .worktree_for_id(seed.worktree_id, cx)
 7719                else {
 7720                    continue;
 7721                };
 7722
 7723                let worktree = worktree_handle.read(cx);
 7724                if !worktree.is_visible() {
 7725                    continue;
 7726                }
 7727
 7728                if !requested_servers.insert(state.id) {
 7729                    continue;
 7730                }
 7731
 7732                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7733                    Some(LanguageServerState::Running {
 7734                        adapter, server, ..
 7735                    }) => (adapter.clone(), server),
 7736
 7737                    _ => continue,
 7738                };
 7739
 7740                let supports_workspace_symbol_request =
 7741                    match server.capabilities().workspace_symbol_provider {
 7742                        Some(OneOf::Left(supported)) => supported,
 7743                        Some(OneOf::Right(_)) => true,
 7744                        None => false,
 7745                    };
 7746
 7747                if !supports_workspace_symbol_request {
 7748                    continue;
 7749                }
 7750
 7751                let worktree_handle = worktree_handle.clone();
 7752                let server_id = server.server_id();
 7753                requests.push(
 7754                    server
 7755                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7756                            lsp::WorkspaceSymbolParams {
 7757                                query: query.to_string(),
 7758                                ..Default::default()
 7759                            },
 7760                            request_timeout,
 7761                        )
 7762                        .map(move |response| {
 7763                            let lsp_symbols = response
 7764                                .into_response()
 7765                                .context("workspace symbols request")
 7766                                .log_err()
 7767                                .flatten()
 7768                                .map(|symbol_response| match symbol_response {
 7769                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7770                                        flat_responses
 7771                                            .into_iter()
 7772                                            .map(|lsp_symbol| {
 7773                                                (
 7774                                                    lsp_symbol.name,
 7775                                                    lsp_symbol.kind,
 7776                                                    lsp_symbol.location,
 7777                                                    lsp_symbol.container_name,
 7778                                                )
 7779                                            })
 7780                                            .collect::<Vec<_>>()
 7781                                    }
 7782                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7783                                        nested_responses
 7784                                            .into_iter()
 7785                                            .filter_map(|lsp_symbol| {
 7786                                                let location = match lsp_symbol.location {
 7787                                                    OneOf::Left(location) => location,
 7788                                                    OneOf::Right(_) => {
 7789                                                        log::error!(
 7790                                                            "Unexpected: client capabilities \
 7791                                                            forbid symbol resolutions in \
 7792                                                            workspace.symbol.resolveSupport"
 7793                                                        );
 7794                                                        return None;
 7795                                                    }
 7796                                                };
 7797                                                Some((
 7798                                                    lsp_symbol.name,
 7799                                                    lsp_symbol.kind,
 7800                                                    location,
 7801                                                    lsp_symbol.container_name,
 7802                                                ))
 7803                                            })
 7804                                            .collect::<Vec<_>>()
 7805                                    }
 7806                                })
 7807                                .unwrap_or_default();
 7808
 7809                            WorkspaceSymbolsResult {
 7810                                server_id,
 7811                                lsp_adapter,
 7812                                worktree: worktree_handle.downgrade(),
 7813                                lsp_symbols,
 7814                            }
 7815                        }),
 7816                );
 7817            }
 7818
 7819            cx.spawn(async move |this, cx| {
 7820                let responses = futures::future::join_all(requests).await;
 7821                let this = match this.upgrade() {
 7822                    Some(this) => this,
 7823                    None => return Ok(Vec::new()),
 7824                };
 7825
 7826                let mut symbols = Vec::new();
 7827                for result in responses {
 7828                    let core_symbols = this.update(cx, |this, cx| {
 7829                        result
 7830                            .lsp_symbols
 7831                            .into_iter()
 7832                            .filter_map(
 7833                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7834                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7835                                    let source_worktree = result.worktree.upgrade()?;
 7836                                    let source_worktree_id = source_worktree.read(cx).id();
 7837
 7838                                    let path = if let Some((tree, rel_path)) =
 7839                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7840                                    {
 7841                                        let worktree_id = tree.read(cx).id();
 7842                                        SymbolLocation::InProject(ProjectPath {
 7843                                            worktree_id,
 7844                                            path: rel_path,
 7845                                        })
 7846                                    } else {
 7847                                        SymbolLocation::OutsideProject {
 7848                                            signature: this.symbol_signature(&abs_path),
 7849                                            abs_path: abs_path.into(),
 7850                                        }
 7851                                    };
 7852
 7853                                    Some(CoreSymbol {
 7854                                        source_language_server_id: result.server_id,
 7855                                        language_server_name: result.lsp_adapter.name.clone(),
 7856                                        source_worktree_id,
 7857                                        path,
 7858                                        kind: symbol_kind,
 7859                                        name: collapse_newlines(&symbol_name, ""),
 7860                                        range: range_from_lsp(symbol_location.range),
 7861                                        container_name: container_name
 7862                                            .map(|c| collapse_newlines(&c, "")),
 7863                                    })
 7864                                },
 7865                            )
 7866                            .collect::<Vec<_>>()
 7867                    });
 7868
 7869                    populate_labels_for_symbols(
 7870                        core_symbols,
 7871                        &language_registry,
 7872                        Some(result.lsp_adapter),
 7873                        &mut symbols,
 7874                    )
 7875                    .await;
 7876                }
 7877
 7878                Ok(symbols)
 7879            })
 7880        } else {
 7881            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7882        }
 7883    }
 7884
 7885    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7886        let mut summary = DiagnosticSummary::default();
 7887        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7888            summary.error_count += path_summary.error_count;
 7889            summary.warning_count += path_summary.warning_count;
 7890        }
 7891        summary
 7892    }
 7893
 7894    /// Returns the diagnostic summary for a specific project path.
 7895    pub fn diagnostic_summary_for_path(
 7896        &self,
 7897        project_path: &ProjectPath,
 7898        _: &App,
 7899    ) -> DiagnosticSummary {
 7900        if let Some(summaries) = self
 7901            .diagnostic_summaries
 7902            .get(&project_path.worktree_id)
 7903            .and_then(|map| map.get(&project_path.path))
 7904        {
 7905            let (error_count, warning_count) = summaries.iter().fold(
 7906                (0, 0),
 7907                |(error_count, warning_count), (_language_server_id, summary)| {
 7908                    (
 7909                        error_count + summary.error_count,
 7910                        warning_count + summary.warning_count,
 7911                    )
 7912                },
 7913            );
 7914
 7915            DiagnosticSummary {
 7916                error_count,
 7917                warning_count,
 7918            }
 7919        } else {
 7920            DiagnosticSummary::default()
 7921        }
 7922    }
 7923
 7924    pub fn diagnostic_summaries<'a>(
 7925        &'a self,
 7926        include_ignored: bool,
 7927        cx: &'a App,
 7928    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7929        self.worktree_store
 7930            .read(cx)
 7931            .visible_worktrees(cx)
 7932            .filter_map(|worktree| {
 7933                let worktree = worktree.read(cx);
 7934                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7935            })
 7936            .flat_map(move |(worktree, summaries)| {
 7937                let worktree_id = worktree.id();
 7938                summaries
 7939                    .iter()
 7940                    .filter(move |(path, _)| {
 7941                        include_ignored
 7942                            || worktree
 7943                                .entry_for_path(path.as_ref())
 7944                                .is_some_and(|entry| !entry.is_ignored)
 7945                    })
 7946                    .flat_map(move |(path, summaries)| {
 7947                        summaries.iter().map(move |(server_id, summary)| {
 7948                            (
 7949                                ProjectPath {
 7950                                    worktree_id,
 7951                                    path: path.clone(),
 7952                                },
 7953                                *server_id,
 7954                                *summary,
 7955                            )
 7956                        })
 7957                    })
 7958            })
 7959    }
 7960
 7961    pub fn on_buffer_edited(
 7962        &mut self,
 7963        buffer: Entity<Buffer>,
 7964        cx: &mut Context<Self>,
 7965    ) -> Option<()> {
 7966        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7967            Some(
 7968                self.as_local()?
 7969                    .language_servers_for_buffer(buffer, cx)
 7970                    .map(|i| i.1.clone())
 7971                    .collect(),
 7972            )
 7973        })?;
 7974
 7975        let buffer = buffer.read(cx);
 7976        let file = File::from_dyn(buffer.file())?;
 7977        let abs_path = file.as_local()?.abs_path(cx);
 7978        let uri = lsp::Uri::from_file_path(&abs_path)
 7979            .ok()
 7980            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7981            .log_err()?;
 7982        let next_snapshot = buffer.text_snapshot();
 7983        for language_server in language_servers {
 7984            let language_server = language_server.clone();
 7985
 7986            let buffer_snapshots = self
 7987                .as_local_mut()?
 7988                .buffer_snapshots
 7989                .get_mut(&buffer.remote_id())
 7990                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7991            let previous_snapshot = buffer_snapshots.last()?;
 7992
 7993            let build_incremental_change = || {
 7994                buffer
 7995                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7996                        previous_snapshot.snapshot.version(),
 7997                    )
 7998                    .map(|edit| {
 7999                        let edit_start = edit.new.start.0;
 8000                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8001                        let new_text = next_snapshot
 8002                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8003                            .collect();
 8004                        lsp::TextDocumentContentChangeEvent {
 8005                            range: Some(lsp::Range::new(
 8006                                point_to_lsp(edit_start),
 8007                                point_to_lsp(edit_end),
 8008                            )),
 8009                            range_length: None,
 8010                            text: new_text,
 8011                        }
 8012                    })
 8013                    .collect()
 8014            };
 8015
 8016            let document_sync_kind = language_server
 8017                .capabilities()
 8018                .text_document_sync
 8019                .as_ref()
 8020                .and_then(|sync| match sync {
 8021                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8022                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8023                });
 8024
 8025            let content_changes: Vec<_> = match document_sync_kind {
 8026                Some(lsp::TextDocumentSyncKind::FULL) => {
 8027                    vec![lsp::TextDocumentContentChangeEvent {
 8028                        range: None,
 8029                        range_length: None,
 8030                        text: next_snapshot.text(),
 8031                    }]
 8032                }
 8033                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8034                _ => {
 8035                    #[cfg(any(test, feature = "test-support"))]
 8036                    {
 8037                        build_incremental_change()
 8038                    }
 8039
 8040                    #[cfg(not(any(test, feature = "test-support")))]
 8041                    {
 8042                        continue;
 8043                    }
 8044                }
 8045            };
 8046
 8047            let next_version = previous_snapshot.version + 1;
 8048            buffer_snapshots.push(LspBufferSnapshot {
 8049                version: next_version,
 8050                snapshot: next_snapshot.clone(),
 8051            });
 8052
 8053            language_server
 8054                .notify::<lsp::notification::DidChangeTextDocument>(
 8055                    lsp::DidChangeTextDocumentParams {
 8056                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8057                            uri.clone(),
 8058                            next_version,
 8059                        ),
 8060                        content_changes,
 8061                    },
 8062                )
 8063                .ok();
 8064            self.pull_workspace_diagnostics(language_server.server_id());
 8065        }
 8066
 8067        None
 8068    }
 8069
 8070    pub fn on_buffer_saved(
 8071        &mut self,
 8072        buffer: Entity<Buffer>,
 8073        cx: &mut Context<Self>,
 8074    ) -> Option<()> {
 8075        let file = File::from_dyn(buffer.read(cx).file())?;
 8076        let worktree_id = file.worktree_id(cx);
 8077        let abs_path = file.as_local()?.abs_path(cx);
 8078        let text_document = lsp::TextDocumentIdentifier {
 8079            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8080        };
 8081        let local = self.as_local()?;
 8082
 8083        for server in local.language_servers_for_worktree(worktree_id) {
 8084            if let Some(include_text) = include_text(server.as_ref()) {
 8085                let text = if include_text {
 8086                    Some(buffer.read(cx).text())
 8087                } else {
 8088                    None
 8089                };
 8090                server
 8091                    .notify::<lsp::notification::DidSaveTextDocument>(
 8092                        lsp::DidSaveTextDocumentParams {
 8093                            text_document: text_document.clone(),
 8094                            text,
 8095                        },
 8096                    )
 8097                    .ok();
 8098            }
 8099        }
 8100
 8101        let language_servers = buffer.update(cx, |buffer, cx| {
 8102            local.language_server_ids_for_buffer(buffer, cx)
 8103        });
 8104        for language_server_id in language_servers {
 8105            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8106        }
 8107
 8108        None
 8109    }
 8110
 8111    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8112        maybe!(async move {
 8113            let mut refreshed_servers = HashSet::default();
 8114            let servers = lsp_store
 8115                .update(cx, |lsp_store, cx| {
 8116                    let local = lsp_store.as_local()?;
 8117
 8118                    let servers = local
 8119                        .language_server_ids
 8120                        .iter()
 8121                        .filter_map(|(seed, state)| {
 8122                            let worktree = lsp_store
 8123                                .worktree_store
 8124                                .read(cx)
 8125                                .worktree_for_id(seed.worktree_id, cx);
 8126                            let delegate: Arc<dyn LspAdapterDelegate> =
 8127                                worktree.map(|worktree| {
 8128                                    LocalLspAdapterDelegate::new(
 8129                                        local.languages.clone(),
 8130                                        &local.environment,
 8131                                        cx.weak_entity(),
 8132                                        &worktree,
 8133                                        local.http_client.clone(),
 8134                                        local.fs.clone(),
 8135                                        cx,
 8136                                    )
 8137                                })?;
 8138                            let server_id = state.id;
 8139
 8140                            let states = local.language_servers.get(&server_id)?;
 8141
 8142                            match states {
 8143                                LanguageServerState::Starting { .. } => None,
 8144                                LanguageServerState::Running {
 8145                                    adapter, server, ..
 8146                                } => {
 8147                                    let adapter = adapter.clone();
 8148                                    let server = server.clone();
 8149                                    refreshed_servers.insert(server.name());
 8150                                    let toolchain = seed.toolchain.clone();
 8151                                    Some(cx.spawn(async move |_, cx| {
 8152                                        let settings =
 8153                                            LocalLspStore::workspace_configuration_for_adapter(
 8154                                                adapter.adapter.clone(),
 8155                                                &delegate,
 8156                                                toolchain,
 8157                                                None,
 8158                                                cx,
 8159                                            )
 8160                                            .await
 8161                                            .ok()?;
 8162                                        server
 8163                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8164                                                lsp::DidChangeConfigurationParams { settings },
 8165                                            )
 8166                                            .ok()?;
 8167                                        Some(())
 8168                                    }))
 8169                                }
 8170                            }
 8171                        })
 8172                        .collect::<Vec<_>>();
 8173
 8174                    Some(servers)
 8175                })
 8176                .ok()
 8177                .flatten()?;
 8178
 8179            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8180            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8181            // to stop and unregister its language server wrapper.
 8182            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8183            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8184            let _: Vec<Option<()>> = join_all(servers).await;
 8185
 8186            Some(())
 8187        })
 8188        .await;
 8189    }
 8190
 8191    fn maintain_workspace_config(
 8192        external_refresh_requests: watch::Receiver<()>,
 8193        cx: &mut Context<Self>,
 8194    ) -> Task<Result<()>> {
 8195        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8196        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8197
 8198        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8199            *settings_changed_tx.borrow_mut() = ();
 8200        });
 8201
 8202        let mut joint_future =
 8203            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8204        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8205        // - 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).
 8206        // - 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.
 8207        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8208        // - 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,
 8209        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8210        cx.spawn(async move |this, cx| {
 8211            while let Some(()) = joint_future.next().await {
 8212                this.update(cx, |this, cx| {
 8213                    this.refresh_server_tree(cx);
 8214                })
 8215                .ok();
 8216
 8217                Self::refresh_workspace_configurations(&this, cx).await;
 8218            }
 8219
 8220            drop(settings_observation);
 8221            anyhow::Ok(())
 8222        })
 8223    }
 8224
 8225    pub fn running_language_servers_for_local_buffer<'a>(
 8226        &'a self,
 8227        buffer: &Buffer,
 8228        cx: &mut App,
 8229    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8230        let local = self.as_local();
 8231        let language_server_ids = local
 8232            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8233            .unwrap_or_default();
 8234
 8235        language_server_ids
 8236            .into_iter()
 8237            .filter_map(
 8238                move |server_id| match local?.language_servers.get(&server_id)? {
 8239                    LanguageServerState::Running {
 8240                        adapter, server, ..
 8241                    } => Some((adapter, server)),
 8242                    _ => None,
 8243                },
 8244            )
 8245    }
 8246
 8247    pub fn language_servers_for_local_buffer(
 8248        &self,
 8249        buffer: &Buffer,
 8250        cx: &mut App,
 8251    ) -> Vec<LanguageServerId> {
 8252        let local = self.as_local();
 8253        local
 8254            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8255            .unwrap_or_default()
 8256    }
 8257
 8258    pub fn language_server_for_local_buffer<'a>(
 8259        &'a self,
 8260        buffer: &'a Buffer,
 8261        server_id: LanguageServerId,
 8262        cx: &'a mut App,
 8263    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8264        self.as_local()?
 8265            .language_servers_for_buffer(buffer, cx)
 8266            .find(|(_, s)| s.server_id() == server_id)
 8267    }
 8268
 8269    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8270        self.diagnostic_summaries.remove(&id_to_remove);
 8271        if let Some(local) = self.as_local_mut() {
 8272            let to_remove = local.remove_worktree(id_to_remove, cx);
 8273            for server in to_remove {
 8274                self.language_server_statuses.remove(&server);
 8275            }
 8276        }
 8277    }
 8278
 8279    fn invalidate_diagnostic_summaries_for_removed_entries(
 8280        &mut self,
 8281        worktree_id: WorktreeId,
 8282        changes: &UpdatedEntriesSet,
 8283        cx: &mut Context<Self>,
 8284    ) {
 8285        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8286            return;
 8287        };
 8288
 8289        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8290        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8291        let downstream = self.downstream_client.clone();
 8292
 8293        for (path, _, _) in changes
 8294            .iter()
 8295            .filter(|(_, _, change)| *change == PathChange::Removed)
 8296        {
 8297            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8298                for (server_id, _) in &summaries_by_server_id {
 8299                    cleared_server_ids.insert(*server_id);
 8300                    if let Some((client, project_id)) = &downstream {
 8301                        client
 8302                            .send(proto::UpdateDiagnosticSummary {
 8303                                project_id: *project_id,
 8304                                worktree_id: worktree_id.to_proto(),
 8305                                summary: Some(proto::DiagnosticSummary {
 8306                                    path: path.as_ref().to_proto(),
 8307                                    language_server_id: server_id.0 as u64,
 8308                                    error_count: 0,
 8309                                    warning_count: 0,
 8310                                }),
 8311                                more_summaries: Vec::new(),
 8312                            })
 8313                            .ok();
 8314                    }
 8315                }
 8316                cleared_paths.push(ProjectPath {
 8317                    worktree_id,
 8318                    path: path.clone(),
 8319                });
 8320            }
 8321        }
 8322
 8323        if !cleared_paths.is_empty() {
 8324            for server_id in cleared_server_ids {
 8325                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8326                    server_id,
 8327                    paths: cleared_paths.clone(),
 8328                });
 8329            }
 8330        }
 8331    }
 8332
 8333    pub fn shared(
 8334        &mut self,
 8335        project_id: u64,
 8336        downstream_client: AnyProtoClient,
 8337        _: &mut Context<Self>,
 8338    ) {
 8339        self.downstream_client = Some((downstream_client.clone(), project_id));
 8340
 8341        for (server_id, status) in &self.language_server_statuses {
 8342            if let Some(server) = self.language_server_for_id(*server_id) {
 8343                downstream_client
 8344                    .send(proto::StartLanguageServer {
 8345                        project_id,
 8346                        server: Some(proto::LanguageServer {
 8347                            id: server_id.to_proto(),
 8348                            name: status.name.to_string(),
 8349                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8350                        }),
 8351                        capabilities: serde_json::to_string(&server.capabilities())
 8352                            .expect("serializing server LSP capabilities"),
 8353                    })
 8354                    .log_err();
 8355            }
 8356        }
 8357    }
 8358
 8359    pub fn disconnected_from_host(&mut self) {
 8360        self.downstream_client.take();
 8361    }
 8362
 8363    pub fn disconnected_from_ssh_remote(&mut self) {
 8364        if let LspStoreMode::Remote(RemoteLspStore {
 8365            upstream_client, ..
 8366        }) = &mut self.mode
 8367        {
 8368            upstream_client.take();
 8369        }
 8370    }
 8371
 8372    pub(crate) fn set_language_server_statuses_from_proto(
 8373        &mut self,
 8374        project: WeakEntity<Project>,
 8375        language_servers: Vec<proto::LanguageServer>,
 8376        server_capabilities: Vec<String>,
 8377        cx: &mut Context<Self>,
 8378    ) {
 8379        let lsp_logs = cx
 8380            .try_global::<GlobalLogStore>()
 8381            .map(|lsp_store| lsp_store.0.clone());
 8382
 8383        self.language_server_statuses = language_servers
 8384            .into_iter()
 8385            .zip(server_capabilities)
 8386            .map(|(server, server_capabilities)| {
 8387                let server_id = LanguageServerId(server.id as usize);
 8388                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8389                    self.lsp_server_capabilities
 8390                        .insert(server_id, server_capabilities);
 8391                }
 8392
 8393                let name = LanguageServerName::from_proto(server.name);
 8394                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8395
 8396                if let Some(lsp_logs) = &lsp_logs {
 8397                    lsp_logs.update(cx, |lsp_logs, cx| {
 8398                        lsp_logs.add_language_server(
 8399                            // Only remote clients get their language servers set from proto
 8400                            LanguageServerKind::Remote {
 8401                                project: project.clone(),
 8402                            },
 8403                            server_id,
 8404                            Some(name.clone()),
 8405                            worktree,
 8406                            None,
 8407                            cx,
 8408                        );
 8409                    });
 8410                }
 8411
 8412                (
 8413                    server_id,
 8414                    LanguageServerStatus {
 8415                        name,
 8416                        server_version: None,
 8417                        server_readable_version: None,
 8418                        pending_work: Default::default(),
 8419                        has_pending_diagnostic_updates: false,
 8420                        progress_tokens: Default::default(),
 8421                        worktree,
 8422                        binary: None,
 8423                        configuration: None,
 8424                        workspace_folders: BTreeSet::new(),
 8425                        process_id: None,
 8426                    },
 8427                )
 8428            })
 8429            .collect();
 8430    }
 8431
 8432    #[cfg(feature = "test-support")]
 8433    pub fn update_diagnostic_entries(
 8434        &mut self,
 8435        server_id: LanguageServerId,
 8436        abs_path: PathBuf,
 8437        result_id: Option<SharedString>,
 8438        version: Option<i32>,
 8439        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8440        cx: &mut Context<Self>,
 8441    ) -> anyhow::Result<()> {
 8442        self.merge_diagnostic_entries(
 8443            vec![DocumentDiagnosticsUpdate {
 8444                diagnostics: DocumentDiagnostics {
 8445                    diagnostics,
 8446                    document_abs_path: abs_path,
 8447                    version,
 8448                },
 8449                result_id,
 8450                server_id,
 8451                disk_based_sources: Cow::Borrowed(&[]),
 8452                registration_id: None,
 8453            }],
 8454            |_, _, _| false,
 8455            cx,
 8456        )?;
 8457        Ok(())
 8458    }
 8459
 8460    pub fn merge_diagnostic_entries<'a>(
 8461        &mut self,
 8462        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8463        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8464        cx: &mut Context<Self>,
 8465    ) -> anyhow::Result<()> {
 8466        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8467        let mut updated_diagnostics_paths = HashMap::default();
 8468        for mut update in diagnostic_updates {
 8469            let abs_path = &update.diagnostics.document_abs_path;
 8470            let server_id = update.server_id;
 8471            let Some((worktree, relative_path)) =
 8472                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8473            else {
 8474                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8475                return Ok(());
 8476            };
 8477
 8478            let worktree_id = worktree.read(cx).id();
 8479            let project_path = ProjectPath {
 8480                worktree_id,
 8481                path: relative_path,
 8482            };
 8483
 8484            let document_uri = lsp::Uri::from_file_path(abs_path)
 8485                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8486            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8487                let snapshot = buffer_handle.read(cx).snapshot();
 8488                let buffer = buffer_handle.read(cx);
 8489                let reused_diagnostics = buffer
 8490                    .buffer_diagnostics(Some(server_id))
 8491                    .iter()
 8492                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8493                    .map(|v| {
 8494                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8495                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8496                        DiagnosticEntry {
 8497                            range: start..end,
 8498                            diagnostic: v.diagnostic.clone(),
 8499                        }
 8500                    })
 8501                    .collect::<Vec<_>>();
 8502
 8503                self.as_local_mut()
 8504                    .context("cannot merge diagnostics on a remote LspStore")?
 8505                    .update_buffer_diagnostics(
 8506                        &buffer_handle,
 8507                        server_id,
 8508                        Some(update.registration_id),
 8509                        update.result_id,
 8510                        update.diagnostics.version,
 8511                        update.diagnostics.diagnostics.clone(),
 8512                        reused_diagnostics.clone(),
 8513                        cx,
 8514                    )?;
 8515
 8516                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8517            } else if let Some(local) = self.as_local() {
 8518                let reused_diagnostics = local
 8519                    .diagnostics
 8520                    .get(&worktree_id)
 8521                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8522                    .and_then(|diagnostics_by_server_id| {
 8523                        diagnostics_by_server_id
 8524                            .binary_search_by_key(&server_id, |e| e.0)
 8525                            .ok()
 8526                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8527                    })
 8528                    .into_iter()
 8529                    .flatten()
 8530                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8531
 8532                update
 8533                    .diagnostics
 8534                    .diagnostics
 8535                    .extend(reused_diagnostics.cloned());
 8536            }
 8537
 8538            let updated = worktree.update(cx, |worktree, cx| {
 8539                self.update_worktree_diagnostics(
 8540                    worktree.id(),
 8541                    server_id,
 8542                    project_path.path.clone(),
 8543                    update.diagnostics.diagnostics,
 8544                    cx,
 8545                )
 8546            })?;
 8547            match updated {
 8548                ControlFlow::Continue(new_summary) => {
 8549                    if let Some((project_id, new_summary)) = new_summary {
 8550                        match &mut diagnostics_summary {
 8551                            Some(diagnostics_summary) => {
 8552                                diagnostics_summary
 8553                                    .more_summaries
 8554                                    .push(proto::DiagnosticSummary {
 8555                                        path: project_path.path.as_ref().to_proto(),
 8556                                        language_server_id: server_id.0 as u64,
 8557                                        error_count: new_summary.error_count,
 8558                                        warning_count: new_summary.warning_count,
 8559                                    })
 8560                            }
 8561                            None => {
 8562                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8563                                    project_id,
 8564                                    worktree_id: worktree_id.to_proto(),
 8565                                    summary: Some(proto::DiagnosticSummary {
 8566                                        path: project_path.path.as_ref().to_proto(),
 8567                                        language_server_id: server_id.0 as u64,
 8568                                        error_count: new_summary.error_count,
 8569                                        warning_count: new_summary.warning_count,
 8570                                    }),
 8571                                    more_summaries: Vec::new(),
 8572                                })
 8573                            }
 8574                        }
 8575                    }
 8576                    updated_diagnostics_paths
 8577                        .entry(server_id)
 8578                        .or_insert_with(Vec::new)
 8579                        .push(project_path);
 8580                }
 8581                ControlFlow::Break(()) => {}
 8582            }
 8583        }
 8584
 8585        if let Some((diagnostics_summary, (downstream_client, _))) =
 8586            diagnostics_summary.zip(self.downstream_client.as_ref())
 8587        {
 8588            downstream_client.send(diagnostics_summary).log_err();
 8589        }
 8590        for (server_id, paths) in updated_diagnostics_paths {
 8591            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8592        }
 8593        Ok(())
 8594    }
 8595
 8596    fn update_worktree_diagnostics(
 8597        &mut self,
 8598        worktree_id: WorktreeId,
 8599        server_id: LanguageServerId,
 8600        path_in_worktree: Arc<RelPath>,
 8601        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8602        _: &mut Context<Worktree>,
 8603    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8604        let local = match &mut self.mode {
 8605            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8606            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8607        };
 8608
 8609        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8610        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8611        let summaries_by_server_id = summaries_for_tree
 8612            .entry(path_in_worktree.clone())
 8613            .or_default();
 8614
 8615        let old_summary = summaries_by_server_id
 8616            .remove(&server_id)
 8617            .unwrap_or_default();
 8618
 8619        let new_summary = DiagnosticSummary::new(&diagnostics);
 8620        if diagnostics.is_empty() {
 8621            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8622            {
 8623                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8624                    diagnostics_by_server_id.remove(ix);
 8625                }
 8626                if diagnostics_by_server_id.is_empty() {
 8627                    diagnostics_for_tree.remove(&path_in_worktree);
 8628                }
 8629            }
 8630        } else {
 8631            summaries_by_server_id.insert(server_id, new_summary);
 8632            let diagnostics_by_server_id = diagnostics_for_tree
 8633                .entry(path_in_worktree.clone())
 8634                .or_default();
 8635            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8636                Ok(ix) => {
 8637                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8638                }
 8639                Err(ix) => {
 8640                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8641                }
 8642            }
 8643        }
 8644
 8645        if !old_summary.is_empty() || !new_summary.is_empty() {
 8646            if let Some((_, project_id)) = &self.downstream_client {
 8647                Ok(ControlFlow::Continue(Some((
 8648                    *project_id,
 8649                    proto::DiagnosticSummary {
 8650                        path: path_in_worktree.to_proto(),
 8651                        language_server_id: server_id.0 as u64,
 8652                        error_count: new_summary.error_count as u32,
 8653                        warning_count: new_summary.warning_count as u32,
 8654                    },
 8655                ))))
 8656            } else {
 8657                Ok(ControlFlow::Continue(None))
 8658            }
 8659        } else {
 8660            Ok(ControlFlow::Break(()))
 8661        }
 8662    }
 8663
 8664    pub fn open_buffer_for_symbol(
 8665        &mut self,
 8666        symbol: &Symbol,
 8667        cx: &mut Context<Self>,
 8668    ) -> Task<Result<Entity<Buffer>>> {
 8669        if let Some((client, project_id)) = self.upstream_client() {
 8670            let request = client.request(proto::OpenBufferForSymbol {
 8671                project_id,
 8672                symbol: Some(Self::serialize_symbol(symbol)),
 8673            });
 8674            cx.spawn(async move |this, cx| {
 8675                let response = request.await?;
 8676                let buffer_id = BufferId::new(response.buffer_id)?;
 8677                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8678                    .await
 8679            })
 8680        } else if let Some(local) = self.as_local() {
 8681            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8682                seed.worktree_id == symbol.source_worktree_id
 8683                    && state.id == symbol.source_language_server_id
 8684                    && symbol.language_server_name == seed.name
 8685            });
 8686            if !is_valid {
 8687                return Task::ready(Err(anyhow!(
 8688                    "language server for worktree and language not found"
 8689                )));
 8690            };
 8691
 8692            let symbol_abs_path = match &symbol.path {
 8693                SymbolLocation::InProject(project_path) => self
 8694                    .worktree_store
 8695                    .read(cx)
 8696                    .absolutize(&project_path, cx)
 8697                    .context("no such worktree"),
 8698                SymbolLocation::OutsideProject {
 8699                    abs_path,
 8700                    signature: _,
 8701                } => Ok(abs_path.to_path_buf()),
 8702            };
 8703            let symbol_abs_path = match symbol_abs_path {
 8704                Ok(abs_path) => abs_path,
 8705                Err(err) => return Task::ready(Err(err)),
 8706            };
 8707            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8708                uri
 8709            } else {
 8710                return Task::ready(Err(anyhow!("invalid symbol path")));
 8711            };
 8712
 8713            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8714        } else {
 8715            Task::ready(Err(anyhow!("no upstream client or local store")))
 8716        }
 8717    }
 8718
 8719    pub(crate) fn open_local_buffer_via_lsp(
 8720        &mut self,
 8721        abs_path: lsp::Uri,
 8722        language_server_id: LanguageServerId,
 8723        cx: &mut Context<Self>,
 8724    ) -> Task<Result<Entity<Buffer>>> {
 8725        let path_style = self.worktree_store.read(cx).path_style();
 8726        cx.spawn(async move |lsp_store, cx| {
 8727            // Escape percent-encoded string.
 8728            let current_scheme = abs_path.scheme().to_owned();
 8729            // Uri is immutable, so we can't modify the scheme
 8730
 8731            let abs_path = abs_path
 8732                .to_file_path_ext(path_style)
 8733                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8734            let p = abs_path.clone();
 8735            let yarn_worktree = lsp_store
 8736                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8737                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8738                        cx.spawn(async move |this, cx| {
 8739                            let t = this
 8740                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8741                                .ok()?;
 8742                            t.await
 8743                        })
 8744                    }),
 8745                    None => Task::ready(None),
 8746                })?
 8747                .await;
 8748            let (worktree_root_target, known_relative_path) =
 8749                if let Some((zip_root, relative_path)) = yarn_worktree {
 8750                    (zip_root, Some(relative_path))
 8751                } else {
 8752                    (Arc::<Path>::from(abs_path.as_path()), None)
 8753                };
 8754            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8755                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8756                    worktree_store.find_worktree(&worktree_root_target, cx)
 8757                })
 8758            })?;
 8759            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8760                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8761                (result.0, relative_path, None)
 8762            } else {
 8763                let worktree = lsp_store
 8764                    .update(cx, |lsp_store, cx| {
 8765                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8766                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8767                        })
 8768                    })?
 8769                    .await?;
 8770                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8771                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8772                    lsp_store
 8773                        .update(cx, |lsp_store, cx| {
 8774                            if let Some(local) = lsp_store.as_local_mut() {
 8775                                local.register_language_server_for_invisible_worktree(
 8776                                    &worktree,
 8777                                    language_server_id,
 8778                                    cx,
 8779                                )
 8780                            }
 8781                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8782                                Some(status) => status.worktree,
 8783                                None => None,
 8784                            }
 8785                        })
 8786                        .ok()
 8787                        .flatten()
 8788                        .zip(Some(worktree_root.clone()))
 8789                } else {
 8790                    None
 8791                };
 8792                let relative_path = if let Some(known_path) = known_relative_path {
 8793                    known_path
 8794                } else {
 8795                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8796                        .into_arc()
 8797                };
 8798                (worktree, relative_path, source_ws)
 8799            };
 8800            let project_path = ProjectPath {
 8801                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8802                path: relative_path,
 8803            };
 8804            let buffer = lsp_store
 8805                .update(cx, |lsp_store, cx| {
 8806                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8807                        buffer_store.open_buffer(project_path, cx)
 8808                    })
 8809                })?
 8810                .await?;
 8811            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8812            if let Some((source_ws, worktree_root)) = source_ws {
 8813                buffer.update(cx, |buffer, cx| {
 8814                    let settings = WorktreeSettings::get(
 8815                        Some(
 8816                            (&ProjectPath {
 8817                                worktree_id: source_ws,
 8818                                path: Arc::from(RelPath::empty()),
 8819                            })
 8820                                .into(),
 8821                        ),
 8822                        cx,
 8823                    );
 8824                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8825                    if is_read_only {
 8826                        buffer.set_capability(Capability::ReadOnly, cx);
 8827                    }
 8828                });
 8829            }
 8830            Ok(buffer)
 8831        })
 8832    }
 8833
 8834    fn local_lsp_servers_for_buffer(
 8835        &self,
 8836        buffer: &Entity<Buffer>,
 8837        cx: &mut Context<Self>,
 8838    ) -> Vec<LanguageServerId> {
 8839        let Some(local) = self.as_local() else {
 8840            return Vec::new();
 8841        };
 8842
 8843        let snapshot = buffer.read(cx).snapshot();
 8844
 8845        buffer.update(cx, |buffer, cx| {
 8846            local
 8847                .language_servers_for_buffer(buffer, cx)
 8848                .map(|(_, server)| server.server_id())
 8849                .filter(|server_id| {
 8850                    self.as_local().is_none_or(|local| {
 8851                        local
 8852                            .buffers_opened_in_servers
 8853                            .get(&snapshot.remote_id())
 8854                            .is_some_and(|servers| servers.contains(server_id))
 8855                    })
 8856                })
 8857                .collect()
 8858        })
 8859    }
 8860
 8861    fn request_multiple_lsp_locally<P, R>(
 8862        &mut self,
 8863        buffer: &Entity<Buffer>,
 8864        position: Option<P>,
 8865        request: R,
 8866        cx: &mut Context<Self>,
 8867    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8868    where
 8869        P: ToOffset,
 8870        R: LspCommand + Clone,
 8871        <R::LspRequest as lsp::request::Request>::Result: Send,
 8872        <R::LspRequest as lsp::request::Request>::Params: Send,
 8873    {
 8874        let Some(local) = self.as_local() else {
 8875            return Task::ready(Vec::new());
 8876        };
 8877
 8878        let snapshot = buffer.read(cx).snapshot();
 8879        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8880
 8881        let server_ids = buffer.update(cx, |buffer, cx| {
 8882            local
 8883                .language_servers_for_buffer(buffer, cx)
 8884                .filter(|(adapter, _)| {
 8885                    scope
 8886                        .as_ref()
 8887                        .map(|scope| scope.language_allowed(&adapter.name))
 8888                        .unwrap_or(true)
 8889                })
 8890                .map(|(_, server)| server.server_id())
 8891                .filter(|server_id| {
 8892                    self.as_local().is_none_or(|local| {
 8893                        local
 8894                            .buffers_opened_in_servers
 8895                            .get(&snapshot.remote_id())
 8896                            .is_some_and(|servers| servers.contains(server_id))
 8897                    })
 8898                })
 8899                .collect::<Vec<_>>()
 8900        });
 8901
 8902        let mut response_results = server_ids
 8903            .into_iter()
 8904            .map(|server_id| {
 8905                let task = self.request_lsp(
 8906                    buffer.clone(),
 8907                    LanguageServerToQuery::Other(server_id),
 8908                    request.clone(),
 8909                    cx,
 8910                );
 8911                async move { (server_id, task.await) }
 8912            })
 8913            .collect::<FuturesUnordered<_>>();
 8914
 8915        cx.background_spawn(async move {
 8916            let mut responses = Vec::with_capacity(response_results.len());
 8917            while let Some((server_id, response_result)) = response_results.next().await {
 8918                match response_result {
 8919                    Ok(response) => responses.push((server_id, response)),
 8920                    // rust-analyzer likes to error with this when its still loading up
 8921                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8922                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8923                }
 8924            }
 8925            responses
 8926        })
 8927    }
 8928
 8929    async fn handle_lsp_get_completions(
 8930        this: Entity<Self>,
 8931        envelope: TypedEnvelope<proto::GetCompletions>,
 8932        mut cx: AsyncApp,
 8933    ) -> Result<proto::GetCompletionsResponse> {
 8934        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8935
 8936        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8937        let buffer_handle = this.update(&mut cx, |this, cx| {
 8938            this.buffer_store.read(cx).get_existing(buffer_id)
 8939        })?;
 8940        let request = GetCompletions::from_proto(
 8941            envelope.payload,
 8942            this.clone(),
 8943            buffer_handle.clone(),
 8944            cx.clone(),
 8945        )
 8946        .await?;
 8947
 8948        let server_to_query = match request.server_id {
 8949            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8950            None => LanguageServerToQuery::FirstCapable,
 8951        };
 8952
 8953        let response = this
 8954            .update(&mut cx, |this, cx| {
 8955                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8956            })
 8957            .await?;
 8958        this.update(&mut cx, |this, cx| {
 8959            Ok(GetCompletions::response_to_proto(
 8960                response,
 8961                this,
 8962                sender_id,
 8963                &buffer_handle.read(cx).version(),
 8964                cx,
 8965            ))
 8966        })
 8967    }
 8968
 8969    async fn handle_lsp_command<T: LspCommand>(
 8970        this: Entity<Self>,
 8971        envelope: TypedEnvelope<T::ProtoRequest>,
 8972        mut cx: AsyncApp,
 8973    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8974    where
 8975        <T::LspRequest as lsp::request::Request>::Params: Send,
 8976        <T::LspRequest as lsp::request::Request>::Result: Send,
 8977    {
 8978        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8979        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8980        let buffer_handle = this.update(&mut cx, |this, cx| {
 8981            this.buffer_store.read(cx).get_existing(buffer_id)
 8982        })?;
 8983        let request = T::from_proto(
 8984            envelope.payload,
 8985            this.clone(),
 8986            buffer_handle.clone(),
 8987            cx.clone(),
 8988        )
 8989        .await?;
 8990        let response = this
 8991            .update(&mut cx, |this, cx| {
 8992                this.request_lsp(
 8993                    buffer_handle.clone(),
 8994                    LanguageServerToQuery::FirstCapable,
 8995                    request,
 8996                    cx,
 8997                )
 8998            })
 8999            .await?;
 9000        this.update(&mut cx, |this, cx| {
 9001            Ok(T::response_to_proto(
 9002                response,
 9003                this,
 9004                sender_id,
 9005                &buffer_handle.read(cx).version(),
 9006                cx,
 9007            ))
 9008        })
 9009    }
 9010
 9011    async fn handle_lsp_query(
 9012        lsp_store: Entity<Self>,
 9013        envelope: TypedEnvelope<proto::LspQuery>,
 9014        mut cx: AsyncApp,
 9015    ) -> Result<proto::Ack> {
 9016        use proto::lsp_query::Request;
 9017        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9018        let lsp_query = envelope.payload;
 9019        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9020        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9021        match lsp_query.request.context("invalid LSP query request")? {
 9022            Request::GetReferences(get_references) => {
 9023                let position = get_references.position.clone().and_then(deserialize_anchor);
 9024                Self::query_lsp_locally::<GetReferences>(
 9025                    lsp_store,
 9026                    server_id,
 9027                    sender_id,
 9028                    lsp_request_id,
 9029                    get_references,
 9030                    position,
 9031                    &mut cx,
 9032                )
 9033                .await?;
 9034            }
 9035            Request::GetDocumentColor(get_document_color) => {
 9036                Self::query_lsp_locally::<GetDocumentColor>(
 9037                    lsp_store,
 9038                    server_id,
 9039                    sender_id,
 9040                    lsp_request_id,
 9041                    get_document_color,
 9042                    None,
 9043                    &mut cx,
 9044                )
 9045                .await?;
 9046            }
 9047            Request::GetFoldingRanges(get_folding_ranges) => {
 9048                Self::query_lsp_locally::<GetFoldingRanges>(
 9049                    lsp_store,
 9050                    server_id,
 9051                    sender_id,
 9052                    lsp_request_id,
 9053                    get_folding_ranges,
 9054                    None,
 9055                    &mut cx,
 9056                )
 9057                .await?;
 9058            }
 9059            Request::GetDocumentSymbols(get_document_symbols) => {
 9060                Self::query_lsp_locally::<GetDocumentSymbols>(
 9061                    lsp_store,
 9062                    server_id,
 9063                    sender_id,
 9064                    lsp_request_id,
 9065                    get_document_symbols,
 9066                    None,
 9067                    &mut cx,
 9068                )
 9069                .await?;
 9070            }
 9071            Request::GetHover(get_hover) => {
 9072                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9073                Self::query_lsp_locally::<GetHover>(
 9074                    lsp_store,
 9075                    server_id,
 9076                    sender_id,
 9077                    lsp_request_id,
 9078                    get_hover,
 9079                    position,
 9080                    &mut cx,
 9081                )
 9082                .await?;
 9083            }
 9084            Request::GetCodeActions(get_code_actions) => {
 9085                Self::query_lsp_locally::<GetCodeActions>(
 9086                    lsp_store,
 9087                    server_id,
 9088                    sender_id,
 9089                    lsp_request_id,
 9090                    get_code_actions,
 9091                    None,
 9092                    &mut cx,
 9093                )
 9094                .await?;
 9095            }
 9096            Request::GetSignatureHelp(get_signature_help) => {
 9097                let position = get_signature_help
 9098                    .position
 9099                    .clone()
 9100                    .and_then(deserialize_anchor);
 9101                Self::query_lsp_locally::<GetSignatureHelp>(
 9102                    lsp_store,
 9103                    server_id,
 9104                    sender_id,
 9105                    lsp_request_id,
 9106                    get_signature_help,
 9107                    position,
 9108                    &mut cx,
 9109                )
 9110                .await?;
 9111            }
 9112            Request::GetCodeLens(get_code_lens) => {
 9113                Self::query_lsp_locally::<GetCodeLens>(
 9114                    lsp_store,
 9115                    server_id,
 9116                    sender_id,
 9117                    lsp_request_id,
 9118                    get_code_lens,
 9119                    None,
 9120                    &mut cx,
 9121                )
 9122                .await?;
 9123            }
 9124            Request::GetDefinition(get_definition) => {
 9125                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9126                Self::query_lsp_locally::<GetDefinitions>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    get_definition,
 9132                    position,
 9133                    &mut cx,
 9134                )
 9135                .await?;
 9136            }
 9137            Request::GetDeclaration(get_declaration) => {
 9138                let position = get_declaration
 9139                    .position
 9140                    .clone()
 9141                    .and_then(deserialize_anchor);
 9142                Self::query_lsp_locally::<GetDeclarations>(
 9143                    lsp_store,
 9144                    server_id,
 9145                    sender_id,
 9146                    lsp_request_id,
 9147                    get_declaration,
 9148                    position,
 9149                    &mut cx,
 9150                )
 9151                .await?;
 9152            }
 9153            Request::GetTypeDefinition(get_type_definition) => {
 9154                let position = get_type_definition
 9155                    .position
 9156                    .clone()
 9157                    .and_then(deserialize_anchor);
 9158                Self::query_lsp_locally::<GetTypeDefinitions>(
 9159                    lsp_store,
 9160                    server_id,
 9161                    sender_id,
 9162                    lsp_request_id,
 9163                    get_type_definition,
 9164                    position,
 9165                    &mut cx,
 9166                )
 9167                .await?;
 9168            }
 9169            Request::GetImplementation(get_implementation) => {
 9170                let position = get_implementation
 9171                    .position
 9172                    .clone()
 9173                    .and_then(deserialize_anchor);
 9174                Self::query_lsp_locally::<GetImplementations>(
 9175                    lsp_store,
 9176                    server_id,
 9177                    sender_id,
 9178                    lsp_request_id,
 9179                    get_implementation,
 9180                    position,
 9181                    &mut cx,
 9182                )
 9183                .await?;
 9184            }
 9185            Request::InlayHints(inlay_hints) => {
 9186                let query_start = inlay_hints
 9187                    .start
 9188                    .clone()
 9189                    .and_then(deserialize_anchor)
 9190                    .context("invalid inlay hints range start")?;
 9191                let query_end = inlay_hints
 9192                    .end
 9193                    .clone()
 9194                    .and_then(deserialize_anchor)
 9195                    .context("invalid inlay hints range end")?;
 9196                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9197                    &lsp_store,
 9198                    server_id,
 9199                    lsp_request_id,
 9200                    &inlay_hints,
 9201                    query_start..query_end,
 9202                    &mut cx,
 9203                )
 9204                .await
 9205                .context("preparing inlay hints request")?;
 9206                Self::query_lsp_locally::<InlayHints>(
 9207                    lsp_store,
 9208                    server_id,
 9209                    sender_id,
 9210                    lsp_request_id,
 9211                    inlay_hints,
 9212                    None,
 9213                    &mut cx,
 9214                )
 9215                .await
 9216                .context("querying for inlay hints")?
 9217            }
 9218            //////////////////////////////
 9219            // Below are LSP queries that need to fetch more data,
 9220            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9221            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9222                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9223                    &lsp_store,
 9224                    &get_document_diagnostics,
 9225                    &mut cx,
 9226                )
 9227                .await?;
 9228                lsp_store.update(&mut cx, |lsp_store, cx| {
 9229                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9230                    let key = LspKey {
 9231                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9232                        server_queried: server_id,
 9233                    };
 9234                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9235                    ) {
 9236                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9237                            lsp_requests.clear();
 9238                        };
 9239                    }
 9240
 9241                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9242                        lsp_request_id,
 9243                        cx.spawn(async move |lsp_store, cx| {
 9244                            let diagnostics_pull = lsp_store
 9245                                .update(cx, |lsp_store, cx| {
 9246                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9247                                })
 9248                                .ok();
 9249                            if let Some(diagnostics_pull) = diagnostics_pull {
 9250                                match diagnostics_pull.await {
 9251                                    Ok(()) => {}
 9252                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9253                                };
 9254                            }
 9255                        }),
 9256                    );
 9257                });
 9258            }
 9259            Request::SemanticTokens(semantic_tokens) => {
 9260                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9261                    &lsp_store,
 9262                    &semantic_tokens,
 9263                    &mut cx,
 9264                )
 9265                .await?;
 9266                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9267                lsp_store.update(&mut cx, |lsp_store, cx| {
 9268                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9269                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9270                        let key = LspKey {
 9271                            request_type: TypeId::of::<SemanticTokensFull>(),
 9272                            server_queried: server_id,
 9273                        };
 9274                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9275                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9276                                lsp_requests.clear();
 9277                            };
 9278                        }
 9279
 9280                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9281                            lsp_request_id,
 9282                            cx.spawn(async move |lsp_store, cx| {
 9283                                let tokens_fetch = lsp_store
 9284                                    .update(cx, |lsp_store, cx| {
 9285                                        lsp_store
 9286                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9287                                    })
 9288                                    .ok();
 9289                                if let Some(tokens_fetch) = tokens_fetch {
 9290                                    let new_tokens = tokens_fetch.await;
 9291                                    if let Some(new_tokens) = new_tokens {
 9292                                        lsp_store
 9293                                            .update(cx, |lsp_store, cx| {
 9294                                                let response = new_tokens
 9295                                                    .into_iter()
 9296                                                    .map(|(server_id, response)| {
 9297                                                        (
 9298                                                            server_id.to_proto(),
 9299                                                            SemanticTokensFull::response_to_proto(
 9300                                                                response,
 9301                                                                lsp_store,
 9302                                                                sender_id,
 9303                                                                &buffer_version,
 9304                                                                cx,
 9305                                                            ),
 9306                                                        )
 9307                                                    })
 9308                                                    .collect::<HashMap<_, _>>();
 9309                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9310                                                    project_id,
 9311                                                    lsp_request_id,
 9312                                                    response,
 9313                                                ) {
 9314                                                    Ok(()) => {}
 9315                                                    Err(e) => {
 9316                                                        log::error!(
 9317                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9318                                                        )
 9319                                                    }
 9320                                                }
 9321                                            })
 9322                                            .ok();
 9323                                    }
 9324                                }
 9325                            }),
 9326                        );
 9327                    }
 9328                });
 9329            }
 9330        }
 9331        Ok(proto::Ack {})
 9332    }
 9333
 9334    async fn handle_lsp_query_response(
 9335        lsp_store: Entity<Self>,
 9336        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9337        cx: AsyncApp,
 9338    ) -> Result<()> {
 9339        lsp_store.read_with(&cx, |lsp_store, _| {
 9340            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9341                upstream_client.handle_lsp_response(envelope.clone());
 9342            }
 9343        });
 9344        Ok(())
 9345    }
 9346
 9347    async fn handle_apply_code_action(
 9348        this: Entity<Self>,
 9349        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9350        mut cx: AsyncApp,
 9351    ) -> Result<proto::ApplyCodeActionResponse> {
 9352        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9353        let action =
 9354            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9355        let apply_code_action = this.update(&mut cx, |this, cx| {
 9356            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9357            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9358            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9359        })?;
 9360
 9361        let project_transaction = apply_code_action.await?;
 9362        let project_transaction = this.update(&mut cx, |this, cx| {
 9363            this.buffer_store.update(cx, |buffer_store, cx| {
 9364                buffer_store.serialize_project_transaction_for_peer(
 9365                    project_transaction,
 9366                    sender_id,
 9367                    cx,
 9368                )
 9369            })
 9370        });
 9371        Ok(proto::ApplyCodeActionResponse {
 9372            transaction: Some(project_transaction),
 9373        })
 9374    }
 9375
 9376    async fn handle_register_buffer_with_language_servers(
 9377        this: Entity<Self>,
 9378        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9379        mut cx: AsyncApp,
 9380    ) -> Result<proto::Ack> {
 9381        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9382        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9383        this.update(&mut cx, |this, cx| {
 9384            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9385                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9386                    project_id: upstream_project_id,
 9387                    buffer_id: buffer_id.to_proto(),
 9388                    only_servers: envelope.payload.only_servers,
 9389                });
 9390            }
 9391
 9392            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9393                anyhow::bail!("buffer is not open");
 9394            };
 9395
 9396            let handle = this.register_buffer_with_language_servers(
 9397                &buffer,
 9398                envelope
 9399                    .payload
 9400                    .only_servers
 9401                    .into_iter()
 9402                    .filter_map(|selector| {
 9403                        Some(match selector.selector? {
 9404                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9405                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9406                            }
 9407                            proto::language_server_selector::Selector::Name(name) => {
 9408                                LanguageServerSelector::Name(LanguageServerName(
 9409                                    SharedString::from(name),
 9410                                ))
 9411                            }
 9412                        })
 9413                    })
 9414                    .collect(),
 9415                false,
 9416                cx,
 9417            );
 9418            // Pull diagnostics for the buffer even if it was already registered.
 9419            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9420            // but it's unclear if we need it.
 9421            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9422                .detach();
 9423            this.buffer_store().update(cx, |buffer_store, _| {
 9424                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9425            });
 9426
 9427            Ok(())
 9428        })?;
 9429        Ok(proto::Ack {})
 9430    }
 9431
 9432    async fn handle_rename_project_entry(
 9433        this: Entity<Self>,
 9434        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9435        mut cx: AsyncApp,
 9436    ) -> Result<proto::ProjectEntryResponse> {
 9437        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9438        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9439        let new_path =
 9440            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9441
 9442        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9443            .update(&mut cx, |this, cx| {
 9444                let (worktree, entry) = this
 9445                    .worktree_store
 9446                    .read(cx)
 9447                    .worktree_and_entry_for_id(entry_id, cx)?;
 9448                let new_worktree = this
 9449                    .worktree_store
 9450                    .read(cx)
 9451                    .worktree_for_id(new_worktree_id, cx)?;
 9452                Some((
 9453                    this.worktree_store.clone(),
 9454                    worktree,
 9455                    new_worktree,
 9456                    entry.clone(),
 9457                ))
 9458            })
 9459            .context("worktree not found")?;
 9460        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9461            (worktree.absolutize(&old_entry.path), worktree.id())
 9462        });
 9463        let new_abs_path =
 9464            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9465
 9466        let _transaction = Self::will_rename_entry(
 9467            this.downgrade(),
 9468            old_worktree_id,
 9469            &old_abs_path,
 9470            &new_abs_path,
 9471            old_entry.is_dir(),
 9472            cx.clone(),
 9473        )
 9474        .await;
 9475        let response = WorktreeStore::handle_rename_project_entry(
 9476            worktree_store,
 9477            envelope.payload,
 9478            cx.clone(),
 9479        )
 9480        .await;
 9481        this.read_with(&cx, |this, _| {
 9482            this.did_rename_entry(
 9483                old_worktree_id,
 9484                &old_abs_path,
 9485                &new_abs_path,
 9486                old_entry.is_dir(),
 9487            );
 9488        });
 9489        response
 9490    }
 9491
 9492    async fn handle_update_diagnostic_summary(
 9493        this: Entity<Self>,
 9494        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9495        mut cx: AsyncApp,
 9496    ) -> Result<()> {
 9497        this.update(&mut cx, |lsp_store, cx| {
 9498            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9499            let mut updated_diagnostics_paths = HashMap::default();
 9500            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9501            for message_summary in envelope
 9502                .payload
 9503                .summary
 9504                .into_iter()
 9505                .chain(envelope.payload.more_summaries)
 9506            {
 9507                let project_path = ProjectPath {
 9508                    worktree_id,
 9509                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9510                };
 9511                let path = project_path.path.clone();
 9512                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9513                let summary = DiagnosticSummary {
 9514                    error_count: message_summary.error_count as usize,
 9515                    warning_count: message_summary.warning_count as usize,
 9516                };
 9517
 9518                if summary.is_empty() {
 9519                    if let Some(worktree_summaries) =
 9520                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9521                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9522                    {
 9523                        summaries.remove(&server_id);
 9524                        if summaries.is_empty() {
 9525                            worktree_summaries.remove(&path);
 9526                        }
 9527                    }
 9528                } else {
 9529                    lsp_store
 9530                        .diagnostic_summaries
 9531                        .entry(worktree_id)
 9532                        .or_default()
 9533                        .entry(path)
 9534                        .or_default()
 9535                        .insert(server_id, summary);
 9536                }
 9537
 9538                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9539                    match &mut diagnostics_summary {
 9540                        Some(diagnostics_summary) => {
 9541                            diagnostics_summary
 9542                                .more_summaries
 9543                                .push(proto::DiagnosticSummary {
 9544                                    path: project_path.path.as_ref().to_proto(),
 9545                                    language_server_id: server_id.0 as u64,
 9546                                    error_count: summary.error_count as u32,
 9547                                    warning_count: summary.warning_count as u32,
 9548                                })
 9549                        }
 9550                        None => {
 9551                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9552                                project_id: *project_id,
 9553                                worktree_id: worktree_id.to_proto(),
 9554                                summary: Some(proto::DiagnosticSummary {
 9555                                    path: project_path.path.as_ref().to_proto(),
 9556                                    language_server_id: server_id.0 as u64,
 9557                                    error_count: summary.error_count as u32,
 9558                                    warning_count: summary.warning_count as u32,
 9559                                }),
 9560                                more_summaries: Vec::new(),
 9561                            })
 9562                        }
 9563                    }
 9564                }
 9565                updated_diagnostics_paths
 9566                    .entry(server_id)
 9567                    .or_insert_with(Vec::new)
 9568                    .push(project_path);
 9569            }
 9570
 9571            if let Some((diagnostics_summary, (downstream_client, _))) =
 9572                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9573            {
 9574                downstream_client.send(diagnostics_summary).log_err();
 9575            }
 9576            for (server_id, paths) in updated_diagnostics_paths {
 9577                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9578            }
 9579            Ok(())
 9580        })
 9581    }
 9582
 9583    async fn handle_start_language_server(
 9584        lsp_store: Entity<Self>,
 9585        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9586        mut cx: AsyncApp,
 9587    ) -> Result<()> {
 9588        let server = envelope.payload.server.context("invalid server")?;
 9589        let server_capabilities =
 9590            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9591                .with_context(|| {
 9592                    format!(
 9593                        "incorrect server capabilities {}",
 9594                        envelope.payload.capabilities
 9595                    )
 9596                })?;
 9597        lsp_store.update(&mut cx, |lsp_store, cx| {
 9598            let server_id = LanguageServerId(server.id as usize);
 9599            let server_name = LanguageServerName::from_proto(server.name.clone());
 9600            lsp_store
 9601                .lsp_server_capabilities
 9602                .insert(server_id, server_capabilities);
 9603            lsp_store.language_server_statuses.insert(
 9604                server_id,
 9605                LanguageServerStatus {
 9606                    name: server_name.clone(),
 9607                    server_version: None,
 9608                    server_readable_version: None,
 9609                    pending_work: Default::default(),
 9610                    has_pending_diagnostic_updates: false,
 9611                    progress_tokens: Default::default(),
 9612                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9613                    binary: None,
 9614                    configuration: None,
 9615                    workspace_folders: BTreeSet::new(),
 9616                    process_id: None,
 9617                },
 9618            );
 9619            cx.emit(LspStoreEvent::LanguageServerAdded(
 9620                server_id,
 9621                server_name,
 9622                server.worktree_id.map(WorktreeId::from_proto),
 9623            ));
 9624            cx.notify();
 9625        });
 9626        Ok(())
 9627    }
 9628
 9629    async fn handle_update_language_server(
 9630        lsp_store: Entity<Self>,
 9631        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9632        mut cx: AsyncApp,
 9633    ) -> Result<()> {
 9634        lsp_store.update(&mut cx, |lsp_store, cx| {
 9635            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9636
 9637            match envelope.payload.variant.context("invalid variant")? {
 9638                proto::update_language_server::Variant::WorkStart(payload) => {
 9639                    lsp_store.on_lsp_work_start(
 9640                        language_server_id,
 9641                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9642                            .context("invalid progress token value")?,
 9643                        LanguageServerProgress {
 9644                            title: payload.title,
 9645                            is_disk_based_diagnostics_progress: false,
 9646                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9647                            message: payload.message,
 9648                            percentage: payload.percentage.map(|p| p as usize),
 9649                            last_update_at: cx.background_executor().now(),
 9650                        },
 9651                        cx,
 9652                    );
 9653                }
 9654                proto::update_language_server::Variant::WorkProgress(payload) => {
 9655                    lsp_store.on_lsp_work_progress(
 9656                        language_server_id,
 9657                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9658                            .context("invalid progress token value")?,
 9659                        LanguageServerProgress {
 9660                            title: None,
 9661                            is_disk_based_diagnostics_progress: false,
 9662                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9663                            message: payload.message,
 9664                            percentage: payload.percentage.map(|p| p as usize),
 9665                            last_update_at: cx.background_executor().now(),
 9666                        },
 9667                        cx,
 9668                    );
 9669                }
 9670
 9671                proto::update_language_server::Variant::WorkEnd(payload) => {
 9672                    lsp_store.on_lsp_work_end(
 9673                        language_server_id,
 9674                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9675                            .context("invalid progress token value")?,
 9676                        cx,
 9677                    );
 9678                }
 9679
 9680                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9681                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9682                }
 9683
 9684                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9685                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9686                }
 9687
 9688                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9689                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9690                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9691                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9692                        language_server_id,
 9693                        name: envelope
 9694                            .payload
 9695                            .server_name
 9696                            .map(SharedString::new)
 9697                            .map(LanguageServerName),
 9698                        message: non_lsp,
 9699                    });
 9700                }
 9701            }
 9702
 9703            Ok(())
 9704        })
 9705    }
 9706
 9707    async fn handle_language_server_log(
 9708        this: Entity<Self>,
 9709        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9710        mut cx: AsyncApp,
 9711    ) -> Result<()> {
 9712        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9713        let log_type = envelope
 9714            .payload
 9715            .log_type
 9716            .map(LanguageServerLogType::from_proto)
 9717            .context("invalid language server log type")?;
 9718
 9719        let message = envelope.payload.message;
 9720
 9721        this.update(&mut cx, |_, cx| {
 9722            cx.emit(LspStoreEvent::LanguageServerLog(
 9723                language_server_id,
 9724                log_type,
 9725                message,
 9726            ));
 9727        });
 9728        Ok(())
 9729    }
 9730
 9731    async fn handle_lsp_ext_cancel_flycheck(
 9732        lsp_store: Entity<Self>,
 9733        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9734        cx: AsyncApp,
 9735    ) -> Result<proto::Ack> {
 9736        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9737        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9738            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9739                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9740            } else {
 9741                None
 9742            }
 9743        });
 9744        if let Some(task) = task {
 9745            task.context("handling lsp ext cancel flycheck")?;
 9746        }
 9747
 9748        Ok(proto::Ack {})
 9749    }
 9750
 9751    async fn handle_lsp_ext_run_flycheck(
 9752        lsp_store: Entity<Self>,
 9753        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9754        mut cx: AsyncApp,
 9755    ) -> Result<proto::Ack> {
 9756        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9757        lsp_store.update(&mut cx, |lsp_store, cx| {
 9758            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9759                let text_document = if envelope.payload.current_file_only {
 9760                    let buffer_id = envelope
 9761                        .payload
 9762                        .buffer_id
 9763                        .map(|id| BufferId::new(id))
 9764                        .transpose()?;
 9765                    buffer_id
 9766                        .and_then(|buffer_id| {
 9767                            lsp_store
 9768                                .buffer_store()
 9769                                .read(cx)
 9770                                .get(buffer_id)
 9771                                .and_then(|buffer| {
 9772                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9773                                })
 9774                                .map(|path| make_text_document_identifier(&path))
 9775                        })
 9776                        .transpose()?
 9777                } else {
 9778                    None
 9779                };
 9780                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9781                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9782                )?;
 9783            }
 9784            anyhow::Ok(())
 9785        })?;
 9786
 9787        Ok(proto::Ack {})
 9788    }
 9789
 9790    async fn handle_lsp_ext_clear_flycheck(
 9791        lsp_store: Entity<Self>,
 9792        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9793        cx: AsyncApp,
 9794    ) -> Result<proto::Ack> {
 9795        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9796        lsp_store.read_with(&cx, |lsp_store, _| {
 9797            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9798                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9799            } else {
 9800                None
 9801            }
 9802        });
 9803
 9804        Ok(proto::Ack {})
 9805    }
 9806
 9807    pub fn disk_based_diagnostics_started(
 9808        &mut self,
 9809        language_server_id: LanguageServerId,
 9810        cx: &mut Context<Self>,
 9811    ) {
 9812        if let Some(language_server_status) =
 9813            self.language_server_statuses.get_mut(&language_server_id)
 9814        {
 9815            language_server_status.has_pending_diagnostic_updates = true;
 9816        }
 9817
 9818        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9819        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9820            language_server_id,
 9821            name: self
 9822                .language_server_adapter_for_id(language_server_id)
 9823                .map(|adapter| adapter.name()),
 9824            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9825                Default::default(),
 9826            ),
 9827        })
 9828    }
 9829
 9830    pub fn disk_based_diagnostics_finished(
 9831        &mut self,
 9832        language_server_id: LanguageServerId,
 9833        cx: &mut Context<Self>,
 9834    ) {
 9835        if let Some(language_server_status) =
 9836            self.language_server_statuses.get_mut(&language_server_id)
 9837        {
 9838            language_server_status.has_pending_diagnostic_updates = false;
 9839        }
 9840
 9841        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9842        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9843            language_server_id,
 9844            name: self
 9845                .language_server_adapter_for_id(language_server_id)
 9846                .map(|adapter| adapter.name()),
 9847            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9848                Default::default(),
 9849            ),
 9850        })
 9851    }
 9852
 9853    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9854    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9855    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9856    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9857    // the language server might take some time to publish diagnostics.
 9858    fn simulate_disk_based_diagnostics_events_if_needed(
 9859        &mut self,
 9860        language_server_id: LanguageServerId,
 9861        cx: &mut Context<Self>,
 9862    ) {
 9863        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9864
 9865        let Some(LanguageServerState::Running {
 9866            simulate_disk_based_diagnostics_completion,
 9867            adapter,
 9868            ..
 9869        }) = self
 9870            .as_local_mut()
 9871            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9872        else {
 9873            return;
 9874        };
 9875
 9876        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9877            return;
 9878        }
 9879
 9880        let prev_task =
 9881            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9882                cx.background_executor()
 9883                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9884                    .await;
 9885
 9886                this.update(cx, |this, cx| {
 9887                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9888
 9889                    if let Some(LanguageServerState::Running {
 9890                        simulate_disk_based_diagnostics_completion,
 9891                        ..
 9892                    }) = this.as_local_mut().and_then(|local_store| {
 9893                        local_store.language_servers.get_mut(&language_server_id)
 9894                    }) {
 9895                        *simulate_disk_based_diagnostics_completion = None;
 9896                    }
 9897                })
 9898                .ok();
 9899            }));
 9900
 9901        if prev_task.is_none() {
 9902            self.disk_based_diagnostics_started(language_server_id, cx);
 9903        }
 9904    }
 9905
 9906    pub fn language_server_statuses(
 9907        &self,
 9908    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9909        self.language_server_statuses
 9910            .iter()
 9911            .map(|(key, value)| (*key, value))
 9912    }
 9913
 9914    pub(super) fn did_rename_entry(
 9915        &self,
 9916        worktree_id: WorktreeId,
 9917        old_path: &Path,
 9918        new_path: &Path,
 9919        is_dir: bool,
 9920    ) {
 9921        maybe!({
 9922            let local_store = self.as_local()?;
 9923
 9924            let old_uri = lsp::Uri::from_file_path(old_path)
 9925                .ok()
 9926                .map(|uri| uri.to_string())?;
 9927            let new_uri = lsp::Uri::from_file_path(new_path)
 9928                .ok()
 9929                .map(|uri| uri.to_string())?;
 9930
 9931            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9932                let Some(filter) = local_store
 9933                    .language_server_paths_watched_for_rename
 9934                    .get(&language_server.server_id())
 9935                else {
 9936                    continue;
 9937                };
 9938
 9939                if filter.should_send_did_rename(&old_uri, is_dir) {
 9940                    language_server
 9941                        .notify::<DidRenameFiles>(RenameFilesParams {
 9942                            files: vec![FileRename {
 9943                                old_uri: old_uri.clone(),
 9944                                new_uri: new_uri.clone(),
 9945                            }],
 9946                        })
 9947                        .ok();
 9948                }
 9949            }
 9950            Some(())
 9951        });
 9952    }
 9953
 9954    pub(super) fn will_rename_entry(
 9955        this: WeakEntity<Self>,
 9956        worktree_id: WorktreeId,
 9957        old_path: &Path,
 9958        new_path: &Path,
 9959        is_dir: bool,
 9960        cx: AsyncApp,
 9961    ) -> Task<ProjectTransaction> {
 9962        let old_uri = lsp::Uri::from_file_path(old_path)
 9963            .ok()
 9964            .map(|uri| uri.to_string());
 9965        let new_uri = lsp::Uri::from_file_path(new_path)
 9966            .ok()
 9967            .map(|uri| uri.to_string());
 9968        cx.spawn(async move |cx| {
 9969            let mut tasks = vec![];
 9970            this.update(cx, |this, cx| {
 9971                let local_store = this.as_local()?;
 9972                let old_uri = old_uri?;
 9973                let new_uri = new_uri?;
 9974                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9975                    let Some(filter) = local_store
 9976                        .language_server_paths_watched_for_rename
 9977                        .get(&language_server.server_id())
 9978                    else {
 9979                        continue;
 9980                    };
 9981
 9982                    if !filter.should_send_will_rename(&old_uri, is_dir) {
 9983                        continue;
 9984                    }
 9985                    let request_timeout = ProjectSettings::get_global(cx)
 9986                        .global_lsp_settings
 9987                        .get_request_timeout();
 9988
 9989                    let apply_edit = cx.spawn({
 9990                        let old_uri = old_uri.clone();
 9991                        let new_uri = new_uri.clone();
 9992                        let language_server = language_server.clone();
 9993                        async move |this, cx| {
 9994                            let edit = language_server
 9995                                .request::<WillRenameFiles>(
 9996                                    RenameFilesParams {
 9997                                        files: vec![FileRename { old_uri, new_uri }],
 9998                                    },
 9999                                    request_timeout,
10000                                )
10001                                .await
10002                                .into_response()
10003                                .context("will rename files")
10004                                .log_err()
10005                                .flatten()?;
10006
10007                            LocalLspStore::deserialize_workspace_edit(
10008                                this.upgrade()?,
10009                                edit,
10010                                false,
10011                                language_server.clone(),
10012                                cx,
10013                            )
10014                            .await
10015                            .ok()
10016                        }
10017                    });
10018                    tasks.push(apply_edit);
10019                }
10020                Some(())
10021            })
10022            .ok()
10023            .flatten();
10024            let mut merged_transaction = ProjectTransaction::default();
10025            for task in tasks {
10026                // Await on tasks sequentially so that the order of application of edits is deterministic
10027                // (at least with regards to the order of registration of language servers)
10028                if let Some(transaction) = task.await {
10029                    for (buffer, buffer_transaction) in transaction.0 {
10030                        merged_transaction.0.insert(buffer, buffer_transaction);
10031                    }
10032                }
10033            }
10034            merged_transaction
10035        })
10036    }
10037
10038    fn lsp_notify_abs_paths_changed(
10039        &mut self,
10040        server_id: LanguageServerId,
10041        changes: Vec<PathEvent>,
10042    ) {
10043        maybe!({
10044            let server = self.language_server_for_id(server_id)?;
10045            let changes = changes
10046                .into_iter()
10047                .filter_map(|event| {
10048                    let typ = match event.kind? {
10049                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10050                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10051                        PathEventKind::Changed | PathEventKind::Rescan => {
10052                            lsp::FileChangeType::CHANGED
10053                        }
10054                    };
10055                    Some(lsp::FileEvent {
10056                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10057                        typ,
10058                    })
10059                })
10060                .collect::<Vec<_>>();
10061            if !changes.is_empty() {
10062                server
10063                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10064                        lsp::DidChangeWatchedFilesParams { changes },
10065                    )
10066                    .ok();
10067            }
10068            Some(())
10069        });
10070    }
10071
10072    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10073        self.as_local()?.language_server_for_id(id)
10074    }
10075
10076    fn on_lsp_progress(
10077        &mut self,
10078        progress_params: lsp::ProgressParams,
10079        language_server_id: LanguageServerId,
10080        disk_based_diagnostics_progress_token: Option<String>,
10081        cx: &mut Context<Self>,
10082    ) {
10083        match progress_params.value {
10084            lsp::ProgressParamsValue::WorkDone(progress) => {
10085                self.handle_work_done_progress(
10086                    progress,
10087                    language_server_id,
10088                    disk_based_diagnostics_progress_token,
10089                    ProgressToken::from_lsp(progress_params.token),
10090                    cx,
10091                );
10092            }
10093            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10094                let registration_id = match progress_params.token {
10095                    lsp::NumberOrString::Number(_) => None,
10096                    lsp::NumberOrString::String(token) => token
10097                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10098                        .map(|(_, id)| id.to_owned()),
10099                };
10100                if let Some(LanguageServerState::Running {
10101                    workspace_diagnostics_refresh_tasks,
10102                    ..
10103                }) = self
10104                    .as_local_mut()
10105                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10106                    && let Some(workspace_diagnostics) =
10107                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10108                {
10109                    workspace_diagnostics.progress_tx.try_send(()).ok();
10110                    self.apply_workspace_diagnostic_report(
10111                        language_server_id,
10112                        report,
10113                        registration_id.map(SharedString::from),
10114                        cx,
10115                    )
10116                }
10117            }
10118        }
10119    }
10120
10121    fn handle_work_done_progress(
10122        &mut self,
10123        progress: lsp::WorkDoneProgress,
10124        language_server_id: LanguageServerId,
10125        disk_based_diagnostics_progress_token: Option<String>,
10126        token: ProgressToken,
10127        cx: &mut Context<Self>,
10128    ) {
10129        let language_server_status =
10130            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10131                status
10132            } else {
10133                return;
10134            };
10135
10136        if !language_server_status.progress_tokens.contains(&token) {
10137            return;
10138        }
10139
10140        let is_disk_based_diagnostics_progress =
10141            if let (Some(disk_based_token), ProgressToken::String(token)) =
10142                (&disk_based_diagnostics_progress_token, &token)
10143            {
10144                token.starts_with(disk_based_token)
10145            } else {
10146                false
10147            };
10148
10149        match progress {
10150            lsp::WorkDoneProgress::Begin(report) => {
10151                if is_disk_based_diagnostics_progress {
10152                    self.disk_based_diagnostics_started(language_server_id, cx);
10153                }
10154                self.on_lsp_work_start(
10155                    language_server_id,
10156                    token.clone(),
10157                    LanguageServerProgress {
10158                        title: Some(report.title),
10159                        is_disk_based_diagnostics_progress,
10160                        is_cancellable: report.cancellable.unwrap_or(false),
10161                        message: report.message.clone(),
10162                        percentage: report.percentage.map(|p| p as usize),
10163                        last_update_at: cx.background_executor().now(),
10164                    },
10165                    cx,
10166                );
10167            }
10168            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10169                language_server_id,
10170                token,
10171                LanguageServerProgress {
10172                    title: None,
10173                    is_disk_based_diagnostics_progress,
10174                    is_cancellable: report.cancellable.unwrap_or(false),
10175                    message: report.message,
10176                    percentage: report.percentage.map(|p| p as usize),
10177                    last_update_at: cx.background_executor().now(),
10178                },
10179                cx,
10180            ),
10181            lsp::WorkDoneProgress::End(_) => {
10182                language_server_status.progress_tokens.remove(&token);
10183                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10184                if is_disk_based_diagnostics_progress {
10185                    self.disk_based_diagnostics_finished(language_server_id, cx);
10186                }
10187            }
10188        }
10189    }
10190
10191    fn on_lsp_work_start(
10192        &mut self,
10193        language_server_id: LanguageServerId,
10194        token: ProgressToken,
10195        progress: LanguageServerProgress,
10196        cx: &mut Context<Self>,
10197    ) {
10198        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10199            status.pending_work.insert(token.clone(), progress.clone());
10200            cx.notify();
10201        }
10202        cx.emit(LspStoreEvent::LanguageServerUpdate {
10203            language_server_id,
10204            name: self
10205                .language_server_adapter_for_id(language_server_id)
10206                .map(|adapter| adapter.name()),
10207            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10208                token: Some(token.to_proto()),
10209                title: progress.title,
10210                message: progress.message,
10211                percentage: progress.percentage.map(|p| p as u32),
10212                is_cancellable: Some(progress.is_cancellable),
10213            }),
10214        })
10215    }
10216
10217    fn on_lsp_work_progress(
10218        &mut self,
10219        language_server_id: LanguageServerId,
10220        token: ProgressToken,
10221        progress: LanguageServerProgress,
10222        cx: &mut Context<Self>,
10223    ) {
10224        let mut did_update = false;
10225        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10226            match status.pending_work.entry(token.clone()) {
10227                btree_map::Entry::Vacant(entry) => {
10228                    entry.insert(progress.clone());
10229                    did_update = true;
10230                }
10231                btree_map::Entry::Occupied(mut entry) => {
10232                    let entry = entry.get_mut();
10233                    if (progress.last_update_at - entry.last_update_at)
10234                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10235                    {
10236                        entry.last_update_at = progress.last_update_at;
10237                        if progress.message.is_some() {
10238                            entry.message = progress.message.clone();
10239                        }
10240                        if progress.percentage.is_some() {
10241                            entry.percentage = progress.percentage;
10242                        }
10243                        if progress.is_cancellable != entry.is_cancellable {
10244                            entry.is_cancellable = progress.is_cancellable;
10245                        }
10246                        did_update = true;
10247                    }
10248                }
10249            }
10250        }
10251
10252        if did_update {
10253            cx.emit(LspStoreEvent::LanguageServerUpdate {
10254                language_server_id,
10255                name: self
10256                    .language_server_adapter_for_id(language_server_id)
10257                    .map(|adapter| adapter.name()),
10258                message: proto::update_language_server::Variant::WorkProgress(
10259                    proto::LspWorkProgress {
10260                        token: Some(token.to_proto()),
10261                        message: progress.message,
10262                        percentage: progress.percentage.map(|p| p as u32),
10263                        is_cancellable: Some(progress.is_cancellable),
10264                    },
10265                ),
10266            })
10267        }
10268    }
10269
10270    fn on_lsp_work_end(
10271        &mut self,
10272        language_server_id: LanguageServerId,
10273        token: ProgressToken,
10274        cx: &mut Context<Self>,
10275    ) {
10276        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10277            if let Some(work) = status.pending_work.remove(&token)
10278                && !work.is_disk_based_diagnostics_progress
10279            {
10280                cx.emit(LspStoreEvent::RefreshInlayHints {
10281                    server_id: language_server_id,
10282                    request_id: None,
10283                });
10284            }
10285            cx.notify();
10286        }
10287
10288        cx.emit(LspStoreEvent::LanguageServerUpdate {
10289            language_server_id,
10290            name: self
10291                .language_server_adapter_for_id(language_server_id)
10292                .map(|adapter| adapter.name()),
10293            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10294                token: Some(token.to_proto()),
10295            }),
10296        })
10297    }
10298
10299    pub async fn handle_resolve_completion_documentation(
10300        this: Entity<Self>,
10301        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10302        mut cx: AsyncApp,
10303    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10304        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10305
10306        let completion = this
10307            .read_with(&cx, |this, cx| {
10308                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10309                let server = this
10310                    .language_server_for_id(id)
10311                    .with_context(|| format!("No language server {id}"))?;
10312
10313                let request_timeout = ProjectSettings::get_global(cx)
10314                    .global_lsp_settings
10315                    .get_request_timeout();
10316
10317                anyhow::Ok(cx.background_spawn(async move {
10318                    let can_resolve = server
10319                        .capabilities()
10320                        .completion_provider
10321                        .as_ref()
10322                        .and_then(|options| options.resolve_provider)
10323                        .unwrap_or(false);
10324                    if can_resolve {
10325                        server
10326                            .request::<lsp::request::ResolveCompletionItem>(
10327                                lsp_completion,
10328                                request_timeout,
10329                            )
10330                            .await
10331                            .into_response()
10332                            .context("resolve completion item")
10333                    } else {
10334                        anyhow::Ok(lsp_completion)
10335                    }
10336                }))
10337            })?
10338            .await?;
10339
10340        let mut documentation_is_markdown = false;
10341        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10342        let documentation = match completion.documentation {
10343            Some(lsp::Documentation::String(text)) => text,
10344
10345            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10346                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10347                value
10348            }
10349
10350            _ => String::new(),
10351        };
10352
10353        // If we have a new buffer_id, that means we're talking to a new client
10354        // and want to check for new text_edits in the completion too.
10355        let mut old_replace_start = None;
10356        let mut old_replace_end = None;
10357        let mut old_insert_start = None;
10358        let mut old_insert_end = None;
10359        let mut new_text = String::default();
10360        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10361            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10362                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10363                anyhow::Ok(buffer.read(cx).snapshot())
10364            })?;
10365
10366            if let Some(text_edit) = completion.text_edit.as_ref() {
10367                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10368
10369                if let Some(mut edit) = edit {
10370                    LineEnding::normalize(&mut edit.new_text);
10371
10372                    new_text = edit.new_text;
10373                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10374                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10375                    if let Some(insert_range) = edit.insert_range {
10376                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10377                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10378                    }
10379                }
10380            }
10381        }
10382
10383        Ok(proto::ResolveCompletionDocumentationResponse {
10384            documentation,
10385            documentation_is_markdown,
10386            old_replace_start,
10387            old_replace_end,
10388            new_text,
10389            lsp_completion,
10390            old_insert_start,
10391            old_insert_end,
10392        })
10393    }
10394
10395    async fn handle_on_type_formatting(
10396        this: Entity<Self>,
10397        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10398        mut cx: AsyncApp,
10399    ) -> Result<proto::OnTypeFormattingResponse> {
10400        let on_type_formatting = this.update(&mut cx, |this, cx| {
10401            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10402            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10403            let position = envelope
10404                .payload
10405                .position
10406                .and_then(deserialize_anchor)
10407                .context("invalid position")?;
10408            anyhow::Ok(this.apply_on_type_formatting(
10409                buffer,
10410                position,
10411                envelope.payload.trigger.clone(),
10412                cx,
10413            ))
10414        })?;
10415
10416        let transaction = on_type_formatting
10417            .await?
10418            .as_ref()
10419            .map(language::proto::serialize_transaction);
10420        Ok(proto::OnTypeFormattingResponse { transaction })
10421    }
10422
10423    async fn handle_pull_workspace_diagnostics(
10424        lsp_store: Entity<Self>,
10425        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10426        mut cx: AsyncApp,
10427    ) -> Result<proto::Ack> {
10428        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10429        lsp_store.update(&mut cx, |lsp_store, _| {
10430            lsp_store.pull_workspace_diagnostics(server_id);
10431        });
10432        Ok(proto::Ack {})
10433    }
10434
10435    async fn handle_open_buffer_for_symbol(
10436        this: Entity<Self>,
10437        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10438        mut cx: AsyncApp,
10439    ) -> Result<proto::OpenBufferForSymbolResponse> {
10440        let peer_id = envelope.original_sender_id().unwrap_or_default();
10441        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10442        let symbol = Self::deserialize_symbol(symbol)?;
10443        this.read_with(&cx, |this, _| {
10444            if let SymbolLocation::OutsideProject {
10445                abs_path,
10446                signature,
10447            } = &symbol.path
10448            {
10449                let new_signature = this.symbol_signature(&abs_path);
10450                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10451            }
10452            Ok(())
10453        })?;
10454        let buffer = this
10455            .update(&mut cx, |this, cx| {
10456                this.open_buffer_for_symbol(
10457                    &Symbol {
10458                        language_server_name: symbol.language_server_name,
10459                        source_worktree_id: symbol.source_worktree_id,
10460                        source_language_server_id: symbol.source_language_server_id,
10461                        path: symbol.path,
10462                        name: symbol.name,
10463                        kind: symbol.kind,
10464                        range: symbol.range,
10465                        label: CodeLabel::default(),
10466                        container_name: symbol.container_name,
10467                    },
10468                    cx,
10469                )
10470            })
10471            .await?;
10472
10473        this.update(&mut cx, |this, cx| {
10474            let is_private = buffer
10475                .read(cx)
10476                .file()
10477                .map(|f| f.is_private())
10478                .unwrap_or_default();
10479            if is_private {
10480                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10481            } else {
10482                this.buffer_store
10483                    .update(cx, |buffer_store, cx| {
10484                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10485                    })
10486                    .detach_and_log_err(cx);
10487                let buffer_id = buffer.read(cx).remote_id().to_proto();
10488                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10489            }
10490        })
10491    }
10492
10493    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10494        let mut hasher = Sha256::new();
10495        hasher.update(abs_path.to_string_lossy().as_bytes());
10496        hasher.update(self.nonce.to_be_bytes());
10497        hasher.finalize().as_slice().try_into().unwrap()
10498    }
10499
10500    pub async fn handle_get_project_symbols(
10501        this: Entity<Self>,
10502        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10503        mut cx: AsyncApp,
10504    ) -> Result<proto::GetProjectSymbolsResponse> {
10505        let symbols = this
10506            .update(&mut cx, |this, cx| {
10507                this.symbols(&envelope.payload.query, cx)
10508            })
10509            .await?;
10510
10511        Ok(proto::GetProjectSymbolsResponse {
10512            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10513        })
10514    }
10515
10516    pub async fn handle_restart_language_servers(
10517        this: Entity<Self>,
10518        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10519        mut cx: AsyncApp,
10520    ) -> Result<proto::Ack> {
10521        this.update(&mut cx, |lsp_store, cx| {
10522            let buffers =
10523                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10524            lsp_store.restart_language_servers_for_buffers(
10525                buffers,
10526                envelope
10527                    .payload
10528                    .only_servers
10529                    .into_iter()
10530                    .filter_map(|selector| {
10531                        Some(match selector.selector? {
10532                            proto::language_server_selector::Selector::ServerId(server_id) => {
10533                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10534                            }
10535                            proto::language_server_selector::Selector::Name(name) => {
10536                                LanguageServerSelector::Name(LanguageServerName(
10537                                    SharedString::from(name),
10538                                ))
10539                            }
10540                        })
10541                    })
10542                    .collect(),
10543                true,
10544                cx,
10545            );
10546        });
10547
10548        Ok(proto::Ack {})
10549    }
10550
10551    pub async fn handle_stop_language_servers(
10552        lsp_store: Entity<Self>,
10553        envelope: TypedEnvelope<proto::StopLanguageServers>,
10554        mut cx: AsyncApp,
10555    ) -> Result<proto::Ack> {
10556        lsp_store.update(&mut cx, |lsp_store, cx| {
10557            if envelope.payload.all
10558                && envelope.payload.also_servers.is_empty()
10559                && envelope.payload.buffer_ids.is_empty()
10560            {
10561                lsp_store.stop_all_language_servers(cx);
10562            } else {
10563                let buffers =
10564                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10565                lsp_store
10566                    .stop_language_servers_for_buffers(
10567                        buffers,
10568                        envelope
10569                            .payload
10570                            .also_servers
10571                            .into_iter()
10572                            .filter_map(|selector| {
10573                                Some(match selector.selector? {
10574                                    proto::language_server_selector::Selector::ServerId(
10575                                        server_id,
10576                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10577                                        server_id,
10578                                    )),
10579                                    proto::language_server_selector::Selector::Name(name) => {
10580                                        LanguageServerSelector::Name(LanguageServerName(
10581                                            SharedString::from(name),
10582                                        ))
10583                                    }
10584                                })
10585                            })
10586                            .collect(),
10587                        cx,
10588                    )
10589                    .detach_and_log_err(cx);
10590            }
10591        });
10592
10593        Ok(proto::Ack {})
10594    }
10595
10596    pub async fn handle_cancel_language_server_work(
10597        lsp_store: Entity<Self>,
10598        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10599        mut cx: AsyncApp,
10600    ) -> Result<proto::Ack> {
10601        lsp_store.update(&mut cx, |lsp_store, cx| {
10602            if let Some(work) = envelope.payload.work {
10603                match work {
10604                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10605                        let buffers =
10606                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10607                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10608                    }
10609                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10610                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10611                        let token = work
10612                            .token
10613                            .map(|token| {
10614                                ProgressToken::from_proto(token)
10615                                    .context("invalid work progress token")
10616                            })
10617                            .transpose()?;
10618                        lsp_store.cancel_language_server_work(server_id, token, cx);
10619                    }
10620                }
10621            }
10622            anyhow::Ok(())
10623        })?;
10624
10625        Ok(proto::Ack {})
10626    }
10627
10628    fn buffer_ids_to_buffers(
10629        &mut self,
10630        buffer_ids: impl Iterator<Item = u64>,
10631        cx: &mut Context<Self>,
10632    ) -> Vec<Entity<Buffer>> {
10633        buffer_ids
10634            .into_iter()
10635            .flat_map(|buffer_id| {
10636                self.buffer_store
10637                    .read(cx)
10638                    .get(BufferId::new(buffer_id).log_err()?)
10639            })
10640            .collect::<Vec<_>>()
10641    }
10642
10643    async fn handle_apply_additional_edits_for_completion(
10644        this: Entity<Self>,
10645        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10646        mut cx: AsyncApp,
10647    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10648        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10649            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10650            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10651            let completion = Self::deserialize_completion(
10652                envelope.payload.completion.context("invalid completion")?,
10653            )?;
10654            let all_commit_ranges = envelope
10655                .payload
10656                .all_commit_ranges
10657                .into_iter()
10658                .map(language::proto::deserialize_anchor_range)
10659                .collect::<Result<Vec<_>, _>>()?;
10660            anyhow::Ok((buffer, completion, all_commit_ranges))
10661        })?;
10662
10663        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10664            this.apply_additional_edits_for_completion(
10665                buffer,
10666                Rc::new(RefCell::new(Box::new([Completion {
10667                    replace_range: completion.replace_range,
10668                    new_text: completion.new_text,
10669                    source: completion.source,
10670                    documentation: None,
10671                    label: CodeLabel::default(),
10672                    match_start: None,
10673                    snippet_deduplication_key: None,
10674                    insert_text_mode: None,
10675                    icon_path: None,
10676                    confirm: None,
10677                }]))),
10678                0,
10679                false,
10680                all_commit_ranges,
10681                cx,
10682            )
10683        });
10684
10685        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10686            transaction: apply_additional_edits
10687                .await?
10688                .as_ref()
10689                .map(language::proto::serialize_transaction),
10690        })
10691    }
10692
10693    pub fn last_formatting_failure(&self) -> Option<&str> {
10694        self.last_formatting_failure.as_deref()
10695    }
10696
10697    pub fn reset_last_formatting_failure(&mut self) {
10698        self.last_formatting_failure = None;
10699    }
10700
10701    pub fn environment_for_buffer(
10702        &self,
10703        buffer: &Entity<Buffer>,
10704        cx: &mut Context<Self>,
10705    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10706        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10707            environment.update(cx, |env, cx| {
10708                env.buffer_environment(buffer, &self.worktree_store, cx)
10709            })
10710        } else {
10711            Task::ready(None).shared()
10712        }
10713    }
10714
10715    pub fn format(
10716        &mut self,
10717        buffers: HashSet<Entity<Buffer>>,
10718        target: LspFormatTarget,
10719        push_to_history: bool,
10720        trigger: FormatTrigger,
10721        cx: &mut Context<Self>,
10722    ) -> Task<anyhow::Result<ProjectTransaction>> {
10723        let logger = zlog::scoped!("format");
10724        if self.as_local().is_some() {
10725            zlog::trace!(logger => "Formatting locally");
10726            let logger = zlog::scoped!(logger => "local");
10727            let buffers = buffers
10728                .into_iter()
10729                .map(|buffer_handle| {
10730                    let buffer = buffer_handle.read(cx);
10731                    let buffer_abs_path = File::from_dyn(buffer.file())
10732                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10733
10734                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10735                })
10736                .collect::<Vec<_>>();
10737
10738            cx.spawn(async move |lsp_store, cx| {
10739                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10740
10741                for (handle, abs_path, id) in buffers {
10742                    let env = lsp_store
10743                        .update(cx, |lsp_store, cx| {
10744                            lsp_store.environment_for_buffer(&handle, cx)
10745                        })?
10746                        .await;
10747
10748                    let ranges = match &target {
10749                        LspFormatTarget::Buffers => None,
10750                        LspFormatTarget::Ranges(ranges) => {
10751                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10752                        }
10753                    };
10754
10755                    formattable_buffers.push(FormattableBuffer {
10756                        handle,
10757                        abs_path,
10758                        env,
10759                        ranges,
10760                    });
10761                }
10762                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10763
10764                let format_timer = zlog::time!(logger => "Formatting buffers");
10765                let result = LocalLspStore::format_locally(
10766                    lsp_store.clone(),
10767                    formattable_buffers,
10768                    push_to_history,
10769                    trigger,
10770                    logger,
10771                    cx,
10772                )
10773                .await;
10774                format_timer.end();
10775
10776                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10777
10778                lsp_store.update(cx, |lsp_store, _| {
10779                    lsp_store.update_last_formatting_failure(&result);
10780                })?;
10781
10782                result
10783            })
10784        } else if let Some((client, project_id)) = self.upstream_client() {
10785            zlog::trace!(logger => "Formatting remotely");
10786            let logger = zlog::scoped!(logger => "remote");
10787
10788            let buffer_ranges = match &target {
10789                LspFormatTarget::Buffers => Vec::new(),
10790                LspFormatTarget::Ranges(ranges) => ranges
10791                    .iter()
10792                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10793                        buffer_id: buffer_id.to_proto(),
10794                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10795                    })
10796                    .collect(),
10797            };
10798
10799            let buffer_store = self.buffer_store();
10800            cx.spawn(async move |lsp_store, cx| {
10801                zlog::trace!(logger => "Sending remote format request");
10802                let request_timer = zlog::time!(logger => "remote format request");
10803                let result = client
10804                    .request(proto::FormatBuffers {
10805                        project_id,
10806                        trigger: trigger as i32,
10807                        buffer_ids: buffers
10808                            .iter()
10809                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10810                            .collect(),
10811                        buffer_ranges,
10812                    })
10813                    .await
10814                    .and_then(|result| result.transaction.context("missing transaction"));
10815                request_timer.end();
10816
10817                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10818
10819                lsp_store.update(cx, |lsp_store, _| {
10820                    lsp_store.update_last_formatting_failure(&result);
10821                })?;
10822
10823                let transaction_response = result?;
10824                let _timer = zlog::time!(logger => "deserializing project transaction");
10825                buffer_store
10826                    .update(cx, |buffer_store, cx| {
10827                        buffer_store.deserialize_project_transaction(
10828                            transaction_response,
10829                            push_to_history,
10830                            cx,
10831                        )
10832                    })
10833                    .await
10834            })
10835        } else {
10836            zlog::trace!(logger => "Not formatting");
10837            Task::ready(Ok(ProjectTransaction::default()))
10838        }
10839    }
10840
10841    async fn handle_format_buffers(
10842        this: Entity<Self>,
10843        envelope: TypedEnvelope<proto::FormatBuffers>,
10844        mut cx: AsyncApp,
10845    ) -> Result<proto::FormatBuffersResponse> {
10846        let sender_id = envelope.original_sender_id().unwrap_or_default();
10847        let format = this.update(&mut cx, |this, cx| {
10848            let mut buffers = HashSet::default();
10849            for buffer_id in &envelope.payload.buffer_ids {
10850                let buffer_id = BufferId::new(*buffer_id)?;
10851                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10852            }
10853
10854            let target = if envelope.payload.buffer_ranges.is_empty() {
10855                LspFormatTarget::Buffers
10856            } else {
10857                let mut ranges_map = BTreeMap::new();
10858                for buffer_range in &envelope.payload.buffer_ranges {
10859                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10860                    let ranges: Result<Vec<_>> = buffer_range
10861                        .ranges
10862                        .iter()
10863                        .map(|range| {
10864                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10865                        })
10866                        .collect();
10867                    ranges_map.insert(buffer_id, ranges?);
10868                }
10869                LspFormatTarget::Ranges(ranges_map)
10870            };
10871
10872            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10873            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10874        })?;
10875
10876        let project_transaction = format.await?;
10877        let project_transaction = this.update(&mut cx, |this, cx| {
10878            this.buffer_store.update(cx, |buffer_store, cx| {
10879                buffer_store.serialize_project_transaction_for_peer(
10880                    project_transaction,
10881                    sender_id,
10882                    cx,
10883                )
10884            })
10885        });
10886        Ok(proto::FormatBuffersResponse {
10887            transaction: Some(project_transaction),
10888        })
10889    }
10890
10891    async fn handle_apply_code_action_kind(
10892        this: Entity<Self>,
10893        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10894        mut cx: AsyncApp,
10895    ) -> Result<proto::ApplyCodeActionKindResponse> {
10896        let sender_id = envelope.original_sender_id().unwrap_or_default();
10897        let format = this.update(&mut cx, |this, cx| {
10898            let mut buffers = HashSet::default();
10899            for buffer_id in &envelope.payload.buffer_ids {
10900                let buffer_id = BufferId::new(*buffer_id)?;
10901                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10902            }
10903            let kind = match envelope.payload.kind.as_str() {
10904                "" => CodeActionKind::EMPTY,
10905                "quickfix" => CodeActionKind::QUICKFIX,
10906                "refactor" => CodeActionKind::REFACTOR,
10907                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10908                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10909                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10910                "source" => CodeActionKind::SOURCE,
10911                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10912                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10913                _ => anyhow::bail!(
10914                    "Invalid code action kind {}",
10915                    envelope.payload.kind.as_str()
10916                ),
10917            };
10918            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10919        })?;
10920
10921        let project_transaction = format.await?;
10922        let project_transaction = this.update(&mut cx, |this, cx| {
10923            this.buffer_store.update(cx, |buffer_store, cx| {
10924                buffer_store.serialize_project_transaction_for_peer(
10925                    project_transaction,
10926                    sender_id,
10927                    cx,
10928                )
10929            })
10930        });
10931        Ok(proto::ApplyCodeActionKindResponse {
10932            transaction: Some(project_transaction),
10933        })
10934    }
10935
10936    async fn shutdown_language_server(
10937        server_state: Option<LanguageServerState>,
10938        name: LanguageServerName,
10939        cx: &mut AsyncApp,
10940    ) {
10941        let server = match server_state {
10942            Some(LanguageServerState::Starting { startup, .. }) => {
10943                let mut timer = cx
10944                    .background_executor()
10945                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10946                    .fuse();
10947
10948                select! {
10949                    server = startup.fuse() => server,
10950                    () = timer => {
10951                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10952                        None
10953                    },
10954                }
10955            }
10956
10957            Some(LanguageServerState::Running { server, .. }) => Some(server),
10958
10959            None => None,
10960        };
10961
10962        let Some(server) = server else { return };
10963        if let Some(shutdown) = server.shutdown() {
10964            shutdown.await;
10965        }
10966    }
10967
10968    // Returns a list of all of the worktrees which no longer have a language server and the root path
10969    // for the stopped server
10970    fn stop_local_language_server(
10971        &mut self,
10972        server_id: LanguageServerId,
10973        cx: &mut Context<Self>,
10974    ) -> Task<()> {
10975        let local = match &mut self.mode {
10976            LspStoreMode::Local(local) => local,
10977            _ => {
10978                return Task::ready(());
10979            }
10980        };
10981
10982        // Remove this server ID from all entries in the given worktree.
10983        local
10984            .language_server_ids
10985            .retain(|_, state| state.id != server_id);
10986        self.buffer_store.update(cx, |buffer_store, cx| {
10987            for buffer in buffer_store.buffers() {
10988                buffer.update(cx, |buffer, cx| {
10989                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10990                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10991                });
10992            }
10993        });
10994
10995        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
10996        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10997            summaries.retain(|path, summaries_by_server_id| {
10998                if summaries_by_server_id.remove(&server_id).is_some() {
10999                    if let Some((client, project_id)) = self.downstream_client.clone() {
11000                        client
11001                            .send(proto::UpdateDiagnosticSummary {
11002                                project_id,
11003                                worktree_id: worktree_id.to_proto(),
11004                                summary: Some(proto::DiagnosticSummary {
11005                                    path: path.as_ref().to_proto(),
11006                                    language_server_id: server_id.0 as u64,
11007                                    error_count: 0,
11008                                    warning_count: 0,
11009                                }),
11010                                more_summaries: Vec::new(),
11011                            })
11012                            .log_err();
11013                    }
11014                    cleared_paths.push(ProjectPath {
11015                        worktree_id: *worktree_id,
11016                        path: path.clone(),
11017                    });
11018                    !summaries_by_server_id.is_empty()
11019                } else {
11020                    true
11021                }
11022            });
11023        }
11024        if !cleared_paths.is_empty() {
11025            cx.emit(LspStoreEvent::DiagnosticsUpdated {
11026                server_id,
11027                paths: cleared_paths,
11028            });
11029        }
11030
11031        let local = self.as_local_mut().unwrap();
11032        for diagnostics in local.diagnostics.values_mut() {
11033            diagnostics.retain(|_, diagnostics_by_server_id| {
11034                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11035                    diagnostics_by_server_id.remove(ix);
11036                    !diagnostics_by_server_id.is_empty()
11037                } else {
11038                    true
11039                }
11040            });
11041        }
11042        local.language_server_watched_paths.remove(&server_id);
11043
11044        let server_state = local.language_servers.remove(&server_id);
11045        self.cleanup_lsp_data(server_id);
11046        let name = self
11047            .language_server_statuses
11048            .remove(&server_id)
11049            .map(|status| status.name)
11050            .or_else(|| {
11051                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11052                    Some(adapter.name())
11053                } else {
11054                    None
11055                }
11056            });
11057
11058        if let Some(name) = name {
11059            log::info!("stopping language server {name}");
11060            self.languages
11061                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11062            cx.notify();
11063
11064            return cx.spawn(async move |lsp_store, cx| {
11065                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11066                lsp_store
11067                    .update(cx, |lsp_store, cx| {
11068                        lsp_store
11069                            .languages
11070                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11071                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11072                        cx.notify();
11073                    })
11074                    .ok();
11075            });
11076        }
11077
11078        if server_state.is_some() {
11079            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11080        }
11081        Task::ready(())
11082    }
11083
11084    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11085        if let Some(local) = self.as_local_mut() {
11086            local.all_language_servers_stopped = true;
11087        }
11088        self.shutdown_all_language_servers(cx).detach();
11089    }
11090
11091    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11092        if let Some((client, project_id)) = self.upstream_client() {
11093            let request = client.request(proto::StopLanguageServers {
11094                project_id,
11095                buffer_ids: Vec::new(),
11096                also_servers: Vec::new(),
11097                all: true,
11098            });
11099            cx.background_spawn(async move {
11100                request.await.ok();
11101            })
11102        } else {
11103            let Some(local) = self.as_local_mut() else {
11104                return Task::ready(());
11105            };
11106            let language_servers_to_stop = local
11107                .language_server_ids
11108                .values()
11109                .map(|state| state.id)
11110                .collect();
11111            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11112            let tasks = language_servers_to_stop
11113                .into_iter()
11114                .map(|server| self.stop_local_language_server(server, cx))
11115                .collect::<Vec<_>>();
11116            cx.background_spawn(async move {
11117                futures::future::join_all(tasks).await;
11118            })
11119        }
11120    }
11121
11122    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11123        if let Some(local) = self.as_local_mut() {
11124            local.all_language_servers_stopped = false;
11125            local.stopped_language_servers.clear();
11126        }
11127        let buffers = self.buffer_store.read(cx).buffers().collect();
11128        self.restart_language_servers_for_buffers(buffers, HashSet::default(), true, cx);
11129    }
11130
11131    pub fn restart_language_servers_for_buffers(
11132        &mut self,
11133        buffers: Vec<Entity<Buffer>>,
11134        only_restart_servers: HashSet<LanguageServerSelector>,
11135        clear_stopped: bool,
11136        cx: &mut Context<Self>,
11137    ) {
11138        if let Some((client, project_id)) = self.upstream_client() {
11139            let request = client.request(proto::RestartLanguageServers {
11140                project_id,
11141                buffer_ids: buffers
11142                    .into_iter()
11143                    .map(|b| b.read(cx).remote_id().to_proto())
11144                    .collect(),
11145                only_servers: only_restart_servers
11146                    .into_iter()
11147                    .map(|selector| {
11148                        let selector = match selector {
11149                            LanguageServerSelector::Id(language_server_id) => {
11150                                proto::language_server_selector::Selector::ServerId(
11151                                    language_server_id.to_proto(),
11152                                )
11153                            }
11154                            LanguageServerSelector::Name(language_server_name) => {
11155                                proto::language_server_selector::Selector::Name(
11156                                    language_server_name.to_string(),
11157                                )
11158                            }
11159                        };
11160                        proto::LanguageServerSelector {
11161                            selector: Some(selector),
11162                        }
11163                    })
11164                    .collect(),
11165                all: false,
11166            });
11167            cx.background_spawn(request).detach_and_log_err(cx);
11168        } else {
11169            let (stopped_names, stop_task) = if only_restart_servers.is_empty() {
11170                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11171            } else {
11172                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11173            };
11174            cx.spawn(async move |lsp_store, cx| {
11175                stop_task.await;
11176                lsp_store.update(cx, |lsp_store, cx| {
11177                    if clear_stopped {
11178                        if let Some(local) = lsp_store.as_local_mut() {
11179                            for name in &stopped_names {
11180                                local.stopped_language_servers.remove(name);
11181                            }
11182                        }
11183                    }
11184                    for buffer in buffers {
11185                        lsp_store.register_buffer_with_language_servers(
11186                            &buffer,
11187                            only_restart_servers.clone(),
11188                            true,
11189                            cx,
11190                        );
11191                    }
11192                })
11193            })
11194            .detach();
11195        }
11196    }
11197
11198    pub fn stop_language_servers_for_buffers(
11199        &mut self,
11200        buffers: Vec<Entity<Buffer>>,
11201        also_stop_servers: HashSet<LanguageServerSelector>,
11202        cx: &mut Context<Self>,
11203    ) -> Task<Result<()>> {
11204        if let Some((client, project_id)) = self.upstream_client() {
11205            let request = client.request(proto::StopLanguageServers {
11206                project_id,
11207                buffer_ids: buffers
11208                    .into_iter()
11209                    .map(|b| b.read(cx).remote_id().to_proto())
11210                    .collect(),
11211                also_servers: also_stop_servers
11212                    .into_iter()
11213                    .map(|selector| {
11214                        let selector = match selector {
11215                            LanguageServerSelector::Id(language_server_id) => {
11216                                proto::language_server_selector::Selector::ServerId(
11217                                    language_server_id.to_proto(),
11218                                )
11219                            }
11220                            LanguageServerSelector::Name(language_server_name) => {
11221                                proto::language_server_selector::Selector::Name(
11222                                    language_server_name.to_string(),
11223                                )
11224                            }
11225                        };
11226                        proto::LanguageServerSelector {
11227                            selector: Some(selector),
11228                        }
11229                    })
11230                    .collect(),
11231                all: false,
11232            });
11233            cx.background_spawn(async move {
11234                let _ = request.await?;
11235                Ok(())
11236            })
11237        } else {
11238            let (stopped_names, task) =
11239                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11240            if let Some(local) = self.as_local_mut() {
11241                local.stopped_language_servers.extend(stopped_names);
11242            }
11243            cx.background_spawn(async move {
11244                task.await;
11245                Ok(())
11246            })
11247        }
11248    }
11249
11250    fn stop_local_language_servers_for_buffers(
11251        &mut self,
11252        buffers: &[Entity<Buffer>],
11253        also_stop_servers: HashSet<LanguageServerSelector>,
11254        cx: &mut Context<Self>,
11255    ) -> (HashSet<LanguageServerName>, Task<()>) {
11256        let Some(local) = self.as_local_mut() else {
11257            return (HashSet::default(), Task::ready(()));
11258        };
11259        let mut language_server_names_to_stop = BTreeSet::default();
11260        let mut language_servers_to_stop = also_stop_servers
11261            .into_iter()
11262            .flat_map(|selector| match selector {
11263                LanguageServerSelector::Id(id) => Some(id),
11264                LanguageServerSelector::Name(name) => {
11265                    language_server_names_to_stop.insert(name);
11266                    None
11267                }
11268            })
11269            .collect::<BTreeSet<_>>();
11270
11271        let mut covered_worktrees = HashSet::default();
11272        for buffer in buffers {
11273            buffer.update(cx, |buffer, cx| {
11274                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11275                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11276                    && covered_worktrees.insert(worktree_id)
11277                {
11278                    language_server_names_to_stop.retain(|name| {
11279                        let old_ids_count = language_servers_to_stop.len();
11280                        let all_language_servers_with_this_name = local
11281                            .language_server_ids
11282                            .iter()
11283                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11284                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11285                        old_ids_count == language_servers_to_stop.len()
11286                    });
11287                }
11288            });
11289        }
11290        for name in language_server_names_to_stop {
11291            language_servers_to_stop.extend(
11292                local
11293                    .language_server_ids
11294                    .iter()
11295                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11296            );
11297        }
11298
11299        let stopped_names: HashSet<LanguageServerName> = language_servers_to_stop
11300            .iter()
11301            .filter_map(|id| {
11302                local
11303                    .language_server_ids
11304                    .iter()
11305                    .find(|(_, state)| state.id == *id)
11306                    .map(|(seed, _)| seed.name.clone())
11307            })
11308            .collect();
11309
11310        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11311        let tasks = language_servers_to_stop
11312            .into_iter()
11313            .map(|server| self.stop_local_language_server(server, cx))
11314            .collect::<Vec<_>>();
11315
11316        (
11317            stopped_names,
11318            cx.background_spawn(futures::future::join_all(tasks).map(|_| ())),
11319        )
11320    }
11321
11322    #[cfg(any(test, feature = "test-support"))]
11323    pub fn update_diagnostics(
11324        &mut self,
11325        server_id: LanguageServerId,
11326        diagnostics: lsp::PublishDiagnosticsParams,
11327        result_id: Option<SharedString>,
11328        source_kind: DiagnosticSourceKind,
11329        disk_based_sources: &[String],
11330        cx: &mut Context<Self>,
11331    ) -> Result<()> {
11332        self.merge_lsp_diagnostics(
11333            source_kind,
11334            vec![DocumentDiagnosticsUpdate {
11335                diagnostics,
11336                result_id,
11337                server_id,
11338                disk_based_sources: Cow::Borrowed(disk_based_sources),
11339                registration_id: None,
11340            }],
11341            |_, _, _| false,
11342            cx,
11343        )
11344    }
11345
11346    pub fn merge_lsp_diagnostics(
11347        &mut self,
11348        source_kind: DiagnosticSourceKind,
11349        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11350        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11351        cx: &mut Context<Self>,
11352    ) -> Result<()> {
11353        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11354        let updates = lsp_diagnostics
11355            .into_iter()
11356            .filter_map(|update| {
11357                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11358                Some(DocumentDiagnosticsUpdate {
11359                    diagnostics: self.lsp_to_document_diagnostics(
11360                        abs_path,
11361                        source_kind,
11362                        update.server_id,
11363                        update.diagnostics,
11364                        &update.disk_based_sources,
11365                        update.registration_id.clone(),
11366                    ),
11367                    result_id: update.result_id,
11368                    server_id: update.server_id,
11369                    disk_based_sources: update.disk_based_sources,
11370                    registration_id: update.registration_id,
11371                })
11372            })
11373            .collect();
11374        self.merge_diagnostic_entries(updates, merge, cx)?;
11375        Ok(())
11376    }
11377
11378    fn lsp_to_document_diagnostics(
11379        &mut self,
11380        document_abs_path: PathBuf,
11381        source_kind: DiagnosticSourceKind,
11382        server_id: LanguageServerId,
11383        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11384        disk_based_sources: &[String],
11385        registration_id: Option<SharedString>,
11386    ) -> DocumentDiagnostics {
11387        let mut diagnostics = Vec::default();
11388        let mut primary_diagnostic_group_ids = HashMap::default();
11389        let mut sources_by_group_id = HashMap::default();
11390        let mut supporting_diagnostics = HashMap::default();
11391
11392        let adapter = self.language_server_adapter_for_id(server_id);
11393
11394        // Ensure that primary diagnostics are always the most severe
11395        lsp_diagnostics
11396            .diagnostics
11397            .sort_by_key(|item| item.severity);
11398
11399        for diagnostic in &lsp_diagnostics.diagnostics {
11400            let source = diagnostic.source.as_ref();
11401            let range = range_from_lsp(diagnostic.range);
11402            let is_supporting = diagnostic
11403                .related_information
11404                .as_ref()
11405                .is_some_and(|infos| {
11406                    infos.iter().any(|info| {
11407                        primary_diagnostic_group_ids.contains_key(&(
11408                            source,
11409                            diagnostic.code.clone(),
11410                            range_from_lsp(info.location.range),
11411                        ))
11412                    })
11413                });
11414
11415            let is_unnecessary = diagnostic
11416                .tags
11417                .as_ref()
11418                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11419
11420            let underline = self
11421                .language_server_adapter_for_id(server_id)
11422                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11423
11424            if is_supporting {
11425                supporting_diagnostics.insert(
11426                    (source, diagnostic.code.clone(), range),
11427                    (diagnostic.severity, is_unnecessary),
11428                );
11429            } else {
11430                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11431                let is_disk_based =
11432                    source.is_some_and(|source| disk_based_sources.contains(source));
11433
11434                sources_by_group_id.insert(group_id, source);
11435                primary_diagnostic_group_ids
11436                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11437
11438                diagnostics.push(DiagnosticEntry {
11439                    range,
11440                    diagnostic: Diagnostic {
11441                        source: diagnostic.source.clone(),
11442                        source_kind,
11443                        code: diagnostic.code.clone(),
11444                        code_description: diagnostic
11445                            .code_description
11446                            .as_ref()
11447                            .and_then(|d| d.href.clone()),
11448                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11449                        markdown: adapter.as_ref().and_then(|adapter| {
11450                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11451                        }),
11452                        message: diagnostic.message.trim().to_string(),
11453                        group_id,
11454                        is_primary: true,
11455                        is_disk_based,
11456                        is_unnecessary,
11457                        underline,
11458                        data: diagnostic.data.clone(),
11459                        registration_id: registration_id.clone(),
11460                    },
11461                });
11462                if let Some(infos) = &diagnostic.related_information {
11463                    for info in infos {
11464                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11465                            let range = range_from_lsp(info.location.range);
11466                            diagnostics.push(DiagnosticEntry {
11467                                range,
11468                                diagnostic: Diagnostic {
11469                                    source: diagnostic.source.clone(),
11470                                    source_kind,
11471                                    code: diagnostic.code.clone(),
11472                                    code_description: diagnostic
11473                                        .code_description
11474                                        .as_ref()
11475                                        .and_then(|d| d.href.clone()),
11476                                    severity: DiagnosticSeverity::INFORMATION,
11477                                    markdown: adapter.as_ref().and_then(|adapter| {
11478                                        adapter.diagnostic_message_to_markdown(&info.message)
11479                                    }),
11480                                    message: info.message.trim().to_string(),
11481                                    group_id,
11482                                    is_primary: false,
11483                                    is_disk_based,
11484                                    is_unnecessary: false,
11485                                    underline,
11486                                    data: diagnostic.data.clone(),
11487                                    registration_id: registration_id.clone(),
11488                                },
11489                            });
11490                        }
11491                    }
11492                }
11493            }
11494        }
11495
11496        for entry in &mut diagnostics {
11497            let diagnostic = &mut entry.diagnostic;
11498            if !diagnostic.is_primary {
11499                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11500                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11501                    source,
11502                    diagnostic.code.clone(),
11503                    entry.range.clone(),
11504                )) {
11505                    if let Some(severity) = severity {
11506                        diagnostic.severity = severity;
11507                    }
11508                    diagnostic.is_unnecessary = is_unnecessary;
11509                }
11510            }
11511        }
11512
11513        DocumentDiagnostics {
11514            diagnostics,
11515            document_abs_path,
11516            version: lsp_diagnostics.version,
11517        }
11518    }
11519
11520    fn insert_newly_running_language_server(
11521        &mut self,
11522        adapter: Arc<CachedLspAdapter>,
11523        language_server: Arc<LanguageServer>,
11524        server_id: LanguageServerId,
11525        key: LanguageServerSeed,
11526        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11527        cx: &mut Context<Self>,
11528    ) {
11529        let Some(local) = self.as_local_mut() else {
11530            return;
11531        };
11532        // If the language server for this key doesn't match the server id, don't store the
11533        // server. Which will cause it to be dropped, killing the process
11534        if local
11535            .language_server_ids
11536            .get(&key)
11537            .map(|state| state.id != server_id)
11538            .unwrap_or(false)
11539        {
11540            return;
11541        }
11542
11543        // Update language_servers collection with Running variant of LanguageServerState
11544        // indicating that the server is up and running and ready
11545        let workspace_folders = workspace_folders.lock().clone();
11546        language_server.set_workspace_folders(workspace_folders);
11547
11548        let workspace_diagnostics_refresh_tasks = language_server
11549            .capabilities()
11550            .diagnostic_provider
11551            .and_then(|provider| {
11552                local
11553                    .language_server_dynamic_registrations
11554                    .entry(server_id)
11555                    .or_default()
11556                    .diagnostics
11557                    .entry(None)
11558                    .or_insert(provider.clone());
11559                let workspace_refresher =
11560                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11561
11562                Some((None, workspace_refresher))
11563            })
11564            .into_iter()
11565            .collect();
11566        local.language_servers.insert(
11567            server_id,
11568            LanguageServerState::Running {
11569                workspace_diagnostics_refresh_tasks,
11570                adapter: adapter.clone(),
11571                server: language_server.clone(),
11572                simulate_disk_based_diagnostics_completion: None,
11573            },
11574        );
11575        local
11576            .languages
11577            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11578        if let Some(file_ops_caps) = language_server
11579            .capabilities()
11580            .workspace
11581            .as_ref()
11582            .and_then(|ws| ws.file_operations.as_ref())
11583        {
11584            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11585            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11586            if did_rename_caps.or(will_rename_caps).is_some() {
11587                let watcher = RenamePathsWatchedForServer::default()
11588                    .with_did_rename_patterns(did_rename_caps)
11589                    .with_will_rename_patterns(will_rename_caps);
11590                local
11591                    .language_server_paths_watched_for_rename
11592                    .insert(server_id, watcher);
11593            }
11594        }
11595
11596        self.language_server_statuses.insert(
11597            server_id,
11598            LanguageServerStatus {
11599                name: language_server.name(),
11600                server_version: language_server.version(),
11601                server_readable_version: language_server.readable_version(),
11602                pending_work: Default::default(),
11603                has_pending_diagnostic_updates: false,
11604                progress_tokens: Default::default(),
11605                worktree: Some(key.worktree_id),
11606                binary: Some(language_server.binary().clone()),
11607                configuration: Some(language_server.configuration().clone()),
11608                workspace_folders: language_server.workspace_folders(),
11609                process_id: language_server.process_id(),
11610            },
11611        );
11612
11613        cx.emit(LspStoreEvent::LanguageServerAdded(
11614            server_id,
11615            language_server.name(),
11616            Some(key.worktree_id),
11617        ));
11618
11619        let server_capabilities = language_server.capabilities();
11620        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11621            downstream_client
11622                .send(proto::StartLanguageServer {
11623                    project_id: *project_id,
11624                    server: Some(proto::LanguageServer {
11625                        id: server_id.to_proto(),
11626                        name: language_server.name().to_string(),
11627                        worktree_id: Some(key.worktree_id.to_proto()),
11628                    }),
11629                    capabilities: serde_json::to_string(&server_capabilities)
11630                        .expect("serializing server LSP capabilities"),
11631                })
11632                .log_err();
11633        }
11634        self.lsp_server_capabilities
11635            .insert(server_id, server_capabilities);
11636
11637        // Tell the language server about every open buffer in the worktree that matches the language.
11638        // Also check for buffers in worktrees that reused this server
11639        let mut worktrees_using_server = vec![key.worktree_id];
11640        if let Some(local) = self.as_local() {
11641            // Find all worktrees that have this server in their language server tree
11642            for (worktree_id, servers) in &local.lsp_tree.instances {
11643                if *worktree_id != key.worktree_id {
11644                    for server_map in servers.roots.values() {
11645                        if server_map
11646                            .values()
11647                            .any(|(node, _)| node.id() == Some(server_id))
11648                        {
11649                            worktrees_using_server.push(*worktree_id);
11650                        }
11651                    }
11652                }
11653            }
11654        }
11655
11656        let mut buffer_paths_registered = Vec::new();
11657        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11658            let mut lsp_adapters = HashMap::default();
11659            for buffer_handle in buffer_store.buffers() {
11660                let buffer = buffer_handle.read(cx);
11661                let file = match File::from_dyn(buffer.file()) {
11662                    Some(file) => file,
11663                    None => continue,
11664                };
11665                let language = match buffer.language() {
11666                    Some(language) => language,
11667                    None => continue,
11668                };
11669
11670                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11671                    || !lsp_adapters
11672                        .entry(language.name())
11673                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11674                        .iter()
11675                        .any(|a| a.name == key.name)
11676                {
11677                    continue;
11678                }
11679                // didOpen
11680                let file = match file.as_local() {
11681                    Some(file) => file,
11682                    None => continue,
11683                };
11684
11685                let local = self.as_local_mut().unwrap();
11686
11687                let buffer_id = buffer.remote_id();
11688                if local.registered_buffers.contains_key(&buffer_id) {
11689                    let abs_path = file.abs_path(cx);
11690                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11691                        Ok(uri) => uri,
11692                        Err(()) => {
11693                            log::error!("failed to convert path to URI: {:?}", abs_path);
11694                            continue;
11695                        }
11696                    };
11697
11698                    let versions = local
11699                        .buffer_snapshots
11700                        .entry(buffer_id)
11701                        .or_default()
11702                        .entry(server_id)
11703                        .and_modify(|_| {
11704                            assert!(
11705                            false,
11706                            "There should not be an existing snapshot for a newly inserted buffer"
11707                        )
11708                        })
11709                        .or_insert_with(|| {
11710                            vec![LspBufferSnapshot {
11711                                version: 0,
11712                                snapshot: buffer.text_snapshot(),
11713                            }]
11714                        });
11715
11716                    let snapshot = versions.last().unwrap();
11717                    let version = snapshot.version;
11718                    let initial_snapshot = &snapshot.snapshot;
11719                    language_server.register_buffer(
11720                        uri,
11721                        adapter.language_id(&language.name()),
11722                        version,
11723                        initial_snapshot.text(),
11724                    );
11725                    buffer_paths_registered.push((buffer_id, abs_path));
11726                    local
11727                        .buffers_opened_in_servers
11728                        .entry(buffer_id)
11729                        .or_default()
11730                        .insert(server_id);
11731                }
11732                buffer_handle.update(cx, |buffer, cx| {
11733                    buffer.set_completion_triggers(
11734                        server_id,
11735                        language_server
11736                            .capabilities()
11737                            .completion_provider
11738                            .as_ref()
11739                            .and_then(|provider| {
11740                                provider
11741                                    .trigger_characters
11742                                    .as_ref()
11743                                    .map(|characters| characters.iter().cloned().collect())
11744                            })
11745                            .unwrap_or_default(),
11746                        cx,
11747                    )
11748                });
11749            }
11750        });
11751
11752        for (buffer_id, abs_path) in buffer_paths_registered {
11753            cx.emit(LspStoreEvent::LanguageServerUpdate {
11754                language_server_id: server_id,
11755                name: Some(adapter.name()),
11756                message: proto::update_language_server::Variant::RegisteredForBuffer(
11757                    proto::RegisteredForBuffer {
11758                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11759                        buffer_id: buffer_id.to_proto(),
11760                    },
11761                ),
11762            });
11763        }
11764
11765        cx.notify();
11766    }
11767
11768    pub fn language_servers_running_disk_based_diagnostics(
11769        &self,
11770    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11771        self.language_server_statuses
11772            .iter()
11773            .filter_map(|(id, status)| {
11774                if status.has_pending_diagnostic_updates {
11775                    Some(*id)
11776                } else {
11777                    None
11778                }
11779            })
11780    }
11781
11782    pub(crate) fn cancel_language_server_work_for_buffers(
11783        &mut self,
11784        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11785        cx: &mut Context<Self>,
11786    ) {
11787        if let Some((client, project_id)) = self.upstream_client() {
11788            let request = client.request(proto::CancelLanguageServerWork {
11789                project_id,
11790                work: Some(proto::cancel_language_server_work::Work::Buffers(
11791                    proto::cancel_language_server_work::Buffers {
11792                        buffer_ids: buffers
11793                            .into_iter()
11794                            .map(|b| b.read(cx).remote_id().to_proto())
11795                            .collect(),
11796                    },
11797                )),
11798            });
11799            cx.background_spawn(request).detach_and_log_err(cx);
11800        } else if let Some(local) = self.as_local() {
11801            let servers = buffers
11802                .into_iter()
11803                .flat_map(|buffer| {
11804                    buffer.update(cx, |buffer, cx| {
11805                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11806                    })
11807                })
11808                .collect::<HashSet<_>>();
11809            for server_id in servers {
11810                self.cancel_language_server_work(server_id, None, cx);
11811            }
11812        }
11813    }
11814
11815    pub(crate) fn cancel_language_server_work(
11816        &mut self,
11817        server_id: LanguageServerId,
11818        token_to_cancel: Option<ProgressToken>,
11819        cx: &mut Context<Self>,
11820    ) {
11821        if let Some(local) = self.as_local() {
11822            let status = self.language_server_statuses.get(&server_id);
11823            let server = local.language_servers.get(&server_id);
11824            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11825            {
11826                for (token, progress) in &status.pending_work {
11827                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11828                        && token != token_to_cancel
11829                    {
11830                        continue;
11831                    }
11832                    if progress.is_cancellable {
11833                        server
11834                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11835                                WorkDoneProgressCancelParams {
11836                                    token: token.to_lsp(),
11837                                },
11838                            )
11839                            .ok();
11840                    }
11841                }
11842            }
11843        } else if let Some((client, project_id)) = self.upstream_client() {
11844            let request = client.request(proto::CancelLanguageServerWork {
11845                project_id,
11846                work: Some(
11847                    proto::cancel_language_server_work::Work::LanguageServerWork(
11848                        proto::cancel_language_server_work::LanguageServerWork {
11849                            language_server_id: server_id.to_proto(),
11850                            token: token_to_cancel.map(|token| token.to_proto()),
11851                        },
11852                    ),
11853                ),
11854            });
11855            cx.background_spawn(request).detach_and_log_err(cx);
11856        }
11857    }
11858
11859    fn register_supplementary_language_server(
11860        &mut self,
11861        id: LanguageServerId,
11862        name: LanguageServerName,
11863        server: Arc<LanguageServer>,
11864        cx: &mut Context<Self>,
11865    ) {
11866        if let Some(local) = self.as_local_mut() {
11867            local
11868                .supplementary_language_servers
11869                .insert(id, (name.clone(), server));
11870            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11871        }
11872    }
11873
11874    fn unregister_supplementary_language_server(
11875        &mut self,
11876        id: LanguageServerId,
11877        cx: &mut Context<Self>,
11878    ) {
11879        if let Some(local) = self.as_local_mut() {
11880            local.supplementary_language_servers.remove(&id);
11881            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11882        }
11883    }
11884
11885    pub(crate) fn supplementary_language_servers(
11886        &self,
11887    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11888        self.as_local().into_iter().flat_map(|local| {
11889            local
11890                .supplementary_language_servers
11891                .iter()
11892                .map(|(id, (name, _))| (*id, name.clone()))
11893        })
11894    }
11895
11896    pub fn language_server_adapter_for_id(
11897        &self,
11898        id: LanguageServerId,
11899    ) -> Option<Arc<CachedLspAdapter>> {
11900        self.as_local()
11901            .and_then(|local| local.language_servers.get(&id))
11902            .and_then(|language_server_state| match language_server_state {
11903                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11904                _ => None,
11905            })
11906    }
11907
11908    pub(super) fn update_local_worktree_language_servers(
11909        &mut self,
11910        worktree_handle: &Entity<Worktree>,
11911        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11912        cx: &mut Context<Self>,
11913    ) {
11914        if changes.is_empty() {
11915            return;
11916        }
11917
11918        let Some(local) = self.as_local() else { return };
11919
11920        local.prettier_store.update(cx, |prettier_store, cx| {
11921            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11922        });
11923
11924        let worktree_id = worktree_handle.read(cx).id();
11925        let mut language_server_ids = local
11926            .language_server_ids
11927            .iter()
11928            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11929            .collect::<Vec<_>>();
11930        language_server_ids.sort();
11931        language_server_ids.dedup();
11932
11933        // let abs_path = worktree_handle.read(cx).abs_path();
11934        for server_id in &language_server_ids {
11935            if let Some(LanguageServerState::Running { server, .. }) =
11936                local.language_servers.get(server_id)
11937                && let Some(watched_paths) = local
11938                    .language_server_watched_paths
11939                    .get(server_id)
11940                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11941            {
11942                let params = lsp::DidChangeWatchedFilesParams {
11943                    changes: changes
11944                        .iter()
11945                        .filter_map(|(path, _, change)| {
11946                            if !watched_paths.is_match(path.as_std_path()) {
11947                                return None;
11948                            }
11949                            let typ = match change {
11950                                PathChange::Loaded => return None,
11951                                PathChange::Added => lsp::FileChangeType::CREATED,
11952                                PathChange::Removed => lsp::FileChangeType::DELETED,
11953                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11954                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11955                            };
11956                            let uri = lsp::Uri::from_file_path(
11957                                worktree_handle.read(cx).absolutize(&path),
11958                            )
11959                            .ok()?;
11960                            Some(lsp::FileEvent { uri, typ })
11961                        })
11962                        .collect(),
11963                };
11964                if !params.changes.is_empty() {
11965                    server
11966                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11967                        .ok();
11968                }
11969            }
11970        }
11971        for (path, _, _) in changes {
11972            if let Some(file_name) = path.file_name()
11973                && local.watched_manifest_filenames.contains(file_name)
11974            {
11975                self.request_workspace_config_refresh();
11976                break;
11977            }
11978        }
11979    }
11980
11981    pub fn wait_for_remote_buffer(
11982        &mut self,
11983        id: BufferId,
11984        cx: &mut Context<Self>,
11985    ) -> Task<Result<Entity<Buffer>>> {
11986        self.buffer_store.update(cx, |buffer_store, cx| {
11987            buffer_store.wait_for_remote_buffer(id, cx)
11988        })
11989    }
11990
11991    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11992        let mut result = proto::Symbol {
11993            language_server_name: symbol.language_server_name.0.to_string(),
11994            source_worktree_id: symbol.source_worktree_id.to_proto(),
11995            language_server_id: symbol.source_language_server_id.to_proto(),
11996            name: symbol.name.clone(),
11997            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11998            start: Some(proto::PointUtf16 {
11999                row: symbol.range.start.0.row,
12000                column: symbol.range.start.0.column,
12001            }),
12002            end: Some(proto::PointUtf16 {
12003                row: symbol.range.end.0.row,
12004                column: symbol.range.end.0.column,
12005            }),
12006            worktree_id: Default::default(),
12007            path: Default::default(),
12008            signature: Default::default(),
12009            container_name: symbol.container_name.clone(),
12010        };
12011        match &symbol.path {
12012            SymbolLocation::InProject(path) => {
12013                result.worktree_id = path.worktree_id.to_proto();
12014                result.path = path.path.to_proto();
12015            }
12016            SymbolLocation::OutsideProject {
12017                abs_path,
12018                signature,
12019            } => {
12020                result.path = abs_path.to_string_lossy().into_owned();
12021                result.signature = signature.to_vec();
12022            }
12023        }
12024        result
12025    }
12026
12027    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12028        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12029        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12030        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12031
12032        let path = if serialized_symbol.signature.is_empty() {
12033            SymbolLocation::InProject(ProjectPath {
12034                worktree_id,
12035                path: RelPath::from_proto(&serialized_symbol.path)
12036                    .context("invalid symbol path")?,
12037            })
12038        } else {
12039            SymbolLocation::OutsideProject {
12040                abs_path: Path::new(&serialized_symbol.path).into(),
12041                signature: serialized_symbol
12042                    .signature
12043                    .try_into()
12044                    .map_err(|_| anyhow!("invalid signature"))?,
12045            }
12046        };
12047
12048        let start = serialized_symbol.start.context("invalid start")?;
12049        let end = serialized_symbol.end.context("invalid end")?;
12050        Ok(CoreSymbol {
12051            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12052            source_worktree_id,
12053            source_language_server_id: LanguageServerId::from_proto(
12054                serialized_symbol.language_server_id,
12055            ),
12056            path,
12057            name: serialized_symbol.name,
12058            range: Unclipped(PointUtf16::new(start.row, start.column))
12059                ..Unclipped(PointUtf16::new(end.row, end.column)),
12060            kind,
12061            container_name: serialized_symbol.container_name,
12062        })
12063    }
12064
12065    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12066        let mut serialized_completion = proto::Completion {
12067            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12068            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12069            new_text: completion.new_text.clone(),
12070            ..proto::Completion::default()
12071        };
12072        match &completion.source {
12073            CompletionSource::Lsp {
12074                insert_range,
12075                server_id,
12076                lsp_completion,
12077                lsp_defaults,
12078                resolved,
12079            } => {
12080                let (old_insert_start, old_insert_end) = insert_range
12081                    .as_ref()
12082                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12083                    .unzip();
12084
12085                serialized_completion.old_insert_start = old_insert_start;
12086                serialized_completion.old_insert_end = old_insert_end;
12087                serialized_completion.source = proto::completion::Source::Lsp as i32;
12088                serialized_completion.server_id = server_id.0 as u64;
12089                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12090                serialized_completion.lsp_defaults = lsp_defaults
12091                    .as_deref()
12092                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12093                serialized_completion.resolved = *resolved;
12094            }
12095            CompletionSource::BufferWord {
12096                word_range,
12097                resolved,
12098            } => {
12099                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12100                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12101                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12102                serialized_completion.resolved = *resolved;
12103            }
12104            CompletionSource::Custom => {
12105                serialized_completion.source = proto::completion::Source::Custom as i32;
12106                serialized_completion.resolved = true;
12107            }
12108            CompletionSource::Dap { sort_text } => {
12109                serialized_completion.source = proto::completion::Source::Dap as i32;
12110                serialized_completion.sort_text = Some(sort_text.clone());
12111            }
12112        }
12113
12114        serialized_completion
12115    }
12116
12117    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12118        let old_replace_start = completion
12119            .old_replace_start
12120            .and_then(deserialize_anchor)
12121            .context("invalid old start")?;
12122        let old_replace_end = completion
12123            .old_replace_end
12124            .and_then(deserialize_anchor)
12125            .context("invalid old end")?;
12126        let insert_range = {
12127            match completion.old_insert_start.zip(completion.old_insert_end) {
12128                Some((start, end)) => {
12129                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12130                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12131                    Some(start..end)
12132                }
12133                None => None,
12134            }
12135        };
12136        Ok(CoreCompletion {
12137            replace_range: old_replace_start..old_replace_end,
12138            new_text: completion.new_text,
12139            source: match proto::completion::Source::from_i32(completion.source) {
12140                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12141                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12142                    insert_range,
12143                    server_id: LanguageServerId::from_proto(completion.server_id),
12144                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12145                    lsp_defaults: completion
12146                        .lsp_defaults
12147                        .as_deref()
12148                        .map(serde_json::from_slice)
12149                        .transpose()?,
12150                    resolved: completion.resolved,
12151                },
12152                Some(proto::completion::Source::BufferWord) => {
12153                    let word_range = completion
12154                        .buffer_word_start
12155                        .and_then(deserialize_anchor)
12156                        .context("invalid buffer word start")?
12157                        ..completion
12158                            .buffer_word_end
12159                            .and_then(deserialize_anchor)
12160                            .context("invalid buffer word end")?;
12161                    CompletionSource::BufferWord {
12162                        word_range,
12163                        resolved: completion.resolved,
12164                    }
12165                }
12166                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12167                    sort_text: completion
12168                        .sort_text
12169                        .context("expected sort text to exist")?,
12170                },
12171                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12172            },
12173        })
12174    }
12175
12176    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12177        let (kind, lsp_action) = match &action.lsp_action {
12178            LspAction::Action(code_action) => (
12179                proto::code_action::Kind::Action as i32,
12180                serde_json::to_vec(code_action).unwrap(),
12181            ),
12182            LspAction::Command(command) => (
12183                proto::code_action::Kind::Command as i32,
12184                serde_json::to_vec(command).unwrap(),
12185            ),
12186            LspAction::CodeLens(code_lens) => (
12187                proto::code_action::Kind::CodeLens as i32,
12188                serde_json::to_vec(code_lens).unwrap(),
12189            ),
12190        };
12191
12192        proto::CodeAction {
12193            server_id: action.server_id.0 as u64,
12194            start: Some(serialize_anchor(&action.range.start)),
12195            end: Some(serialize_anchor(&action.range.end)),
12196            lsp_action,
12197            kind,
12198            resolved: action.resolved,
12199        }
12200    }
12201
12202    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12203        let start = action
12204            .start
12205            .and_then(deserialize_anchor)
12206            .context("invalid start")?;
12207        let end = action
12208            .end
12209            .and_then(deserialize_anchor)
12210            .context("invalid end")?;
12211        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12212            Some(proto::code_action::Kind::Action) => {
12213                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12214            }
12215            Some(proto::code_action::Kind::Command) => {
12216                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12217            }
12218            Some(proto::code_action::Kind::CodeLens) => {
12219                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12220            }
12221            None => anyhow::bail!("Unknown action kind {}", action.kind),
12222        };
12223        Ok(CodeAction {
12224            server_id: LanguageServerId(action.server_id as usize),
12225            range: start..end,
12226            resolved: action.resolved,
12227            lsp_action,
12228        })
12229    }
12230
12231    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12232        match &formatting_result {
12233            Ok(_) => self.last_formatting_failure = None,
12234            Err(error) => {
12235                let error_string = format!("{error:#}");
12236                log::error!("Formatting failed: {error_string}");
12237                self.last_formatting_failure
12238                    .replace(error_string.lines().join(" "));
12239            }
12240        }
12241    }
12242
12243    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12244        self.lsp_server_capabilities.remove(&for_server);
12245        self.semantic_token_config.remove_server_data(for_server);
12246        for lsp_data in self.lsp_data.values_mut() {
12247            lsp_data.remove_server_data(for_server);
12248        }
12249        if let Some(local) = self.as_local_mut() {
12250            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12251            local
12252                .workspace_pull_diagnostics_result_ids
12253                .remove(&for_server);
12254            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12255                buffer_servers.remove(&for_server);
12256            }
12257        }
12258    }
12259
12260    pub fn result_id_for_buffer_pull(
12261        &self,
12262        server_id: LanguageServerId,
12263        buffer_id: BufferId,
12264        registration_id: &Option<SharedString>,
12265        cx: &App,
12266    ) -> Option<SharedString> {
12267        let abs_path = self
12268            .buffer_store
12269            .read(cx)
12270            .get(buffer_id)
12271            .and_then(|b| File::from_dyn(b.read(cx).file()))
12272            .map(|f| f.abs_path(cx))?;
12273        self.as_local()?
12274            .buffer_pull_diagnostics_result_ids
12275            .get(&server_id)?
12276            .get(registration_id)?
12277            .get(&abs_path)?
12278            .clone()
12279    }
12280
12281    /// Gets all result_ids for a workspace diagnostics pull request.
12282    /// 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.
12283    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12284    pub fn result_ids_for_workspace_refresh(
12285        &self,
12286        server_id: LanguageServerId,
12287        registration_id: &Option<SharedString>,
12288    ) -> HashMap<PathBuf, SharedString> {
12289        let Some(local) = self.as_local() else {
12290            return HashMap::default();
12291        };
12292        local
12293            .workspace_pull_diagnostics_result_ids
12294            .get(&server_id)
12295            .into_iter()
12296            .filter_map(|diagnostics| diagnostics.get(registration_id))
12297            .flatten()
12298            .filter_map(|(abs_path, result_id)| {
12299                let result_id = local
12300                    .buffer_pull_diagnostics_result_ids
12301                    .get(&server_id)
12302                    .and_then(|buffer_ids_result_ids| {
12303                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12304                    })
12305                    .cloned()
12306                    .flatten()
12307                    .or_else(|| result_id.clone())?;
12308                Some((abs_path.clone(), result_id))
12309            })
12310            .collect()
12311    }
12312
12313    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12314        if let Some(LanguageServerState::Running {
12315            workspace_diagnostics_refresh_tasks,
12316            ..
12317        }) = self
12318            .as_local_mut()
12319            .and_then(|local| local.language_servers.get_mut(&server_id))
12320        {
12321            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12322                diagnostics.refresh_tx.try_send(()).ok();
12323            }
12324        }
12325    }
12326
12327    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12328    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12329    /// which requires refreshing both workspace and document diagnostics.
12330    pub fn pull_document_diagnostics_for_server(
12331        &mut self,
12332        server_id: LanguageServerId,
12333        source_buffer_id: Option<BufferId>,
12334        cx: &mut Context<Self>,
12335    ) -> Shared<Task<()>> {
12336        let Some(local) = self.as_local_mut() else {
12337            return Task::ready(()).shared();
12338        };
12339        let mut buffers_to_refresh = HashSet::default();
12340        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12341            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12342                buffers_to_refresh.insert(*buffer_id);
12343            }
12344        }
12345
12346        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12347    }
12348
12349    pub fn pull_document_diagnostics_for_buffer_edit(
12350        &mut self,
12351        buffer_id: BufferId,
12352        cx: &mut Context<Self>,
12353    ) {
12354        let Some(local) = self.as_local_mut() else {
12355            return;
12356        };
12357        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12358        else {
12359            return;
12360        };
12361        for server_id in languages_servers {
12362            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12363        }
12364    }
12365
12366    fn apply_workspace_diagnostic_report(
12367        &mut self,
12368        server_id: LanguageServerId,
12369        report: lsp::WorkspaceDiagnosticReportResult,
12370        registration_id: Option<SharedString>,
12371        cx: &mut Context<Self>,
12372    ) {
12373        let mut workspace_diagnostics =
12374            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12375                report,
12376                server_id,
12377                registration_id,
12378            );
12379        workspace_diagnostics.retain(|d| match &d.diagnostics {
12380            LspPullDiagnostics::Response {
12381                server_id,
12382                registration_id,
12383                ..
12384            } => self.diagnostic_registration_exists(*server_id, registration_id),
12385            LspPullDiagnostics::Default => false,
12386        });
12387        let mut unchanged_buffers = HashMap::default();
12388        let workspace_diagnostics_updates = workspace_diagnostics
12389            .into_iter()
12390            .filter_map(
12391                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12392                    LspPullDiagnostics::Response {
12393                        server_id,
12394                        uri,
12395                        diagnostics,
12396                        registration_id,
12397                    } => Some((
12398                        server_id,
12399                        uri,
12400                        diagnostics,
12401                        workspace_diagnostics.version,
12402                        registration_id,
12403                    )),
12404                    LspPullDiagnostics::Default => None,
12405                },
12406            )
12407            .fold(
12408                HashMap::default(),
12409                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12410                    let (result_id, diagnostics) = match diagnostics {
12411                        PulledDiagnostics::Unchanged { result_id } => {
12412                            unchanged_buffers
12413                                .entry(new_registration_id.clone())
12414                                .or_insert_with(HashSet::default)
12415                                .insert(uri.clone());
12416                            (Some(result_id), Vec::new())
12417                        }
12418                        PulledDiagnostics::Changed {
12419                            result_id,
12420                            diagnostics,
12421                        } => (result_id, diagnostics),
12422                    };
12423                    let disk_based_sources = Cow::Owned(
12424                        self.language_server_adapter_for_id(server_id)
12425                            .as_ref()
12426                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12427                            .unwrap_or(&[])
12428                            .to_vec(),
12429                    );
12430
12431                    let Some(abs_path) = uri.to_file_path().ok() else {
12432                        return acc;
12433                    };
12434                    let Some((worktree, relative_path)) =
12435                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12436                    else {
12437                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12438                        return acc;
12439                    };
12440                    let worktree_id = worktree.read(cx).id();
12441                    let project_path = ProjectPath {
12442                        worktree_id,
12443                        path: relative_path,
12444                    };
12445                    if let Some(local_lsp_store) = self.as_local_mut() {
12446                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12447                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12448                    }
12449                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12450                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12451                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12452                        acc.entry(server_id)
12453                            .or_insert_with(HashMap::default)
12454                            .entry(new_registration_id.clone())
12455                            .or_insert_with(Vec::new)
12456                            .push(DocumentDiagnosticsUpdate {
12457                                server_id,
12458                                diagnostics: lsp::PublishDiagnosticsParams {
12459                                    uri,
12460                                    diagnostics,
12461                                    version,
12462                                },
12463                                result_id: result_id.map(SharedString::new),
12464                                disk_based_sources,
12465                                registration_id: new_registration_id,
12466                            });
12467                    }
12468                    acc
12469                },
12470            );
12471
12472        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12473            for (registration_id, diagnostic_updates) in diagnostic_updates {
12474                self.merge_lsp_diagnostics(
12475                    DiagnosticSourceKind::Pulled,
12476                    diagnostic_updates,
12477                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12478                        DiagnosticSourceKind::Pulled => {
12479                            old_diagnostic.registration_id != registration_id
12480                                || unchanged_buffers
12481                                    .get(&old_diagnostic.registration_id)
12482                                    .is_some_and(|unchanged_buffers| {
12483                                        unchanged_buffers.contains(&document_uri)
12484                                    })
12485                        }
12486                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12487                    },
12488                    cx,
12489                )
12490                .log_err();
12491            }
12492        }
12493    }
12494
12495    fn register_server_capabilities(
12496        &mut self,
12497        server_id: LanguageServerId,
12498        params: lsp::RegistrationParams,
12499        cx: &mut Context<Self>,
12500    ) -> anyhow::Result<()> {
12501        let server = self
12502            .language_server_for_id(server_id)
12503            .with_context(|| format!("no server {server_id} found"))?;
12504        for reg in params.registrations {
12505            match reg.method.as_str() {
12506                "workspace/didChangeWatchedFiles" => {
12507                    if let Some(options) = reg.register_options {
12508                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12509                            let caps = serde_json::from_value(options)?;
12510                            local_lsp_store
12511                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12512                            true
12513                        } else {
12514                            false
12515                        };
12516                        if notify {
12517                            notify_server_capabilities_updated(&server, cx);
12518                        }
12519                    }
12520                }
12521                "workspace/didChangeConfiguration" => {
12522                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12523                }
12524                "workspace/didChangeWorkspaceFolders" => {
12525                    // In this case register options is an empty object, we can ignore it
12526                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12527                        supported: Some(true),
12528                        change_notifications: Some(OneOf::Right(reg.id)),
12529                    };
12530                    server.update_capabilities(|capabilities| {
12531                        capabilities
12532                            .workspace
12533                            .get_or_insert_default()
12534                            .workspace_folders = Some(caps);
12535                    });
12536                    notify_server_capabilities_updated(&server, cx);
12537                }
12538                "workspace/symbol" => {
12539                    let options = parse_register_capabilities(reg)?;
12540                    server.update_capabilities(|capabilities| {
12541                        capabilities.workspace_symbol_provider = Some(options);
12542                    });
12543                    notify_server_capabilities_updated(&server, cx);
12544                }
12545                "workspace/fileOperations" => {
12546                    if let Some(options) = reg.register_options {
12547                        let caps = serde_json::from_value(options)?;
12548                        server.update_capabilities(|capabilities| {
12549                            capabilities
12550                                .workspace
12551                                .get_or_insert_default()
12552                                .file_operations = Some(caps);
12553                        });
12554                        notify_server_capabilities_updated(&server, cx);
12555                    }
12556                }
12557                "workspace/executeCommand" => {
12558                    if let Some(options) = reg.register_options {
12559                        let options = serde_json::from_value(options)?;
12560                        server.update_capabilities(|capabilities| {
12561                            capabilities.execute_command_provider = Some(options);
12562                        });
12563                        notify_server_capabilities_updated(&server, cx);
12564                    }
12565                }
12566                "textDocument/rangeFormatting" => {
12567                    let options = parse_register_capabilities(reg)?;
12568                    server.update_capabilities(|capabilities| {
12569                        capabilities.document_range_formatting_provider = Some(options);
12570                    });
12571                    notify_server_capabilities_updated(&server, cx);
12572                }
12573                "textDocument/onTypeFormatting" => {
12574                    if let Some(options) = reg
12575                        .register_options
12576                        .map(serde_json::from_value)
12577                        .transpose()?
12578                    {
12579                        server.update_capabilities(|capabilities| {
12580                            capabilities.document_on_type_formatting_provider = Some(options);
12581                        });
12582                        notify_server_capabilities_updated(&server, cx);
12583                    }
12584                }
12585                "textDocument/formatting" => {
12586                    let options = parse_register_capabilities(reg)?;
12587                    server.update_capabilities(|capabilities| {
12588                        capabilities.document_formatting_provider = Some(options);
12589                    });
12590                    notify_server_capabilities_updated(&server, cx);
12591                }
12592                "textDocument/rename" => {
12593                    let options = parse_register_capabilities(reg)?;
12594                    server.update_capabilities(|capabilities| {
12595                        capabilities.rename_provider = Some(options);
12596                    });
12597                    notify_server_capabilities_updated(&server, cx);
12598                }
12599                "textDocument/inlayHint" => {
12600                    let options = parse_register_capabilities(reg)?;
12601                    server.update_capabilities(|capabilities| {
12602                        capabilities.inlay_hint_provider = Some(options);
12603                    });
12604                    notify_server_capabilities_updated(&server, cx);
12605                }
12606                "textDocument/documentSymbol" => {
12607                    let options = parse_register_capabilities(reg)?;
12608                    server.update_capabilities(|capabilities| {
12609                        capabilities.document_symbol_provider = Some(options);
12610                    });
12611                    notify_server_capabilities_updated(&server, cx);
12612                }
12613                "textDocument/codeAction" => {
12614                    let options = parse_register_capabilities(reg)?;
12615                    let provider = match options {
12616                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12617                        OneOf::Right(caps) => caps,
12618                    };
12619                    server.update_capabilities(|capabilities| {
12620                        capabilities.code_action_provider = Some(provider);
12621                    });
12622                    notify_server_capabilities_updated(&server, cx);
12623                }
12624                "textDocument/definition" => {
12625                    let options = parse_register_capabilities(reg)?;
12626                    server.update_capabilities(|capabilities| {
12627                        capabilities.definition_provider = Some(options);
12628                    });
12629                    notify_server_capabilities_updated(&server, cx);
12630                }
12631                "textDocument/completion" => {
12632                    if let Some(caps) = reg
12633                        .register_options
12634                        .map(serde_json::from_value::<CompletionOptions>)
12635                        .transpose()?
12636                    {
12637                        server.update_capabilities(|capabilities| {
12638                            capabilities.completion_provider = Some(caps.clone());
12639                        });
12640
12641                        if let Some(local) = self.as_local() {
12642                            let mut buffers_with_language_server = Vec::new();
12643                            for handle in self.buffer_store.read(cx).buffers() {
12644                                let buffer_id = handle.read(cx).remote_id();
12645                                if local
12646                                    .buffers_opened_in_servers
12647                                    .get(&buffer_id)
12648                                    .filter(|s| s.contains(&server_id))
12649                                    .is_some()
12650                                {
12651                                    buffers_with_language_server.push(handle);
12652                                }
12653                            }
12654                            let triggers = caps
12655                                .trigger_characters
12656                                .unwrap_or_default()
12657                                .into_iter()
12658                                .collect::<BTreeSet<_>>();
12659                            for handle in buffers_with_language_server {
12660                                let triggers = triggers.clone();
12661                                let _ = handle.update(cx, move |buffer, cx| {
12662                                    buffer.set_completion_triggers(server_id, triggers, cx);
12663                                });
12664                            }
12665                        }
12666                        notify_server_capabilities_updated(&server, cx);
12667                    }
12668                }
12669                "textDocument/hover" => {
12670                    let options = parse_register_capabilities(reg)?;
12671                    let provider = match options {
12672                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12673                        OneOf::Right(caps) => caps,
12674                    };
12675                    server.update_capabilities(|capabilities| {
12676                        capabilities.hover_provider = Some(provider);
12677                    });
12678                    notify_server_capabilities_updated(&server, cx);
12679                }
12680                "textDocument/signatureHelp" => {
12681                    if let Some(caps) = reg
12682                        .register_options
12683                        .map(serde_json::from_value)
12684                        .transpose()?
12685                    {
12686                        server.update_capabilities(|capabilities| {
12687                            capabilities.signature_help_provider = Some(caps);
12688                        });
12689                        notify_server_capabilities_updated(&server, cx);
12690                    }
12691                }
12692                "textDocument/didChange" => {
12693                    if let Some(sync_kind) = reg
12694                        .register_options
12695                        .and_then(|opts| opts.get("syncKind").cloned())
12696                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12697                        .transpose()?
12698                    {
12699                        server.update_capabilities(|capabilities| {
12700                            let mut sync_options =
12701                                Self::take_text_document_sync_options(capabilities);
12702                            sync_options.change = Some(sync_kind);
12703                            capabilities.text_document_sync =
12704                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12705                        });
12706                        notify_server_capabilities_updated(&server, cx);
12707                    }
12708                }
12709                "textDocument/didSave" => {
12710                    if let Some(include_text) = reg
12711                        .register_options
12712                        .map(|opts| {
12713                            let transpose = opts
12714                                .get("includeText")
12715                                .cloned()
12716                                .map(serde_json::from_value::<Option<bool>>)
12717                                .transpose();
12718                            match transpose {
12719                                Ok(value) => Ok(value.flatten()),
12720                                Err(e) => Err(e),
12721                            }
12722                        })
12723                        .transpose()?
12724                    {
12725                        server.update_capabilities(|capabilities| {
12726                            let mut sync_options =
12727                                Self::take_text_document_sync_options(capabilities);
12728                            sync_options.save =
12729                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12730                                    include_text,
12731                                }));
12732                            capabilities.text_document_sync =
12733                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12734                        });
12735                        notify_server_capabilities_updated(&server, cx);
12736                    }
12737                }
12738                "textDocument/codeLens" => {
12739                    if let Some(caps) = reg
12740                        .register_options
12741                        .map(serde_json::from_value)
12742                        .transpose()?
12743                    {
12744                        server.update_capabilities(|capabilities| {
12745                            capabilities.code_lens_provider = Some(caps);
12746                        });
12747                        notify_server_capabilities_updated(&server, cx);
12748                    }
12749                }
12750                "textDocument/diagnostic" => {
12751                    if let Some(caps) = reg
12752                        .register_options
12753                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12754                        .transpose()?
12755                    {
12756                        let local = self
12757                            .as_local_mut()
12758                            .context("Expected LSP Store to be local")?;
12759                        let state = local
12760                            .language_servers
12761                            .get_mut(&server_id)
12762                            .context("Could not obtain Language Servers state")?;
12763                        local
12764                            .language_server_dynamic_registrations
12765                            .entry(server_id)
12766                            .or_default()
12767                            .diagnostics
12768                            .insert(Some(reg.id.clone()), caps.clone());
12769
12770                        let supports_workspace_diagnostics =
12771                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12772                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12773                                    diagnostic_options.workspace_diagnostics
12774                                }
12775                                DiagnosticServerCapabilities::RegistrationOptions(
12776                                    diagnostic_registration_options,
12777                                ) => {
12778                                    diagnostic_registration_options
12779                                        .diagnostic_options
12780                                        .workspace_diagnostics
12781                                }
12782                            };
12783
12784                        if supports_workspace_diagnostics(&caps) {
12785                            if let LanguageServerState::Running {
12786                                workspace_diagnostics_refresh_tasks,
12787                                ..
12788                            } = state
12789                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12790                                    Some(reg.id.clone()),
12791                                    caps.clone(),
12792                                    server.clone(),
12793                                    cx,
12794                                )
12795                            {
12796                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12797                            }
12798                        }
12799
12800                        server.update_capabilities(|capabilities| {
12801                            capabilities.diagnostic_provider = Some(caps);
12802                        });
12803
12804                        notify_server_capabilities_updated(&server, cx);
12805
12806                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12807                    }
12808                }
12809                "textDocument/documentColor" => {
12810                    let options = parse_register_capabilities(reg)?;
12811                    let provider = match options {
12812                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12813                        OneOf::Right(caps) => caps,
12814                    };
12815                    server.update_capabilities(|capabilities| {
12816                        capabilities.color_provider = Some(provider);
12817                    });
12818                    notify_server_capabilities_updated(&server, cx);
12819                }
12820                "textDocument/foldingRange" => {
12821                    let options = parse_register_capabilities(reg)?;
12822                    let provider = match options {
12823                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12824                        OneOf::Right(caps) => caps,
12825                    };
12826                    server.update_capabilities(|capabilities| {
12827                        capabilities.folding_range_provider = Some(provider);
12828                    });
12829                    notify_server_capabilities_updated(&server, cx);
12830                }
12831                _ => log::warn!("unhandled capability registration: {reg:?}"),
12832            }
12833        }
12834
12835        Ok(())
12836    }
12837
12838    fn unregister_server_capabilities(
12839        &mut self,
12840        server_id: LanguageServerId,
12841        params: lsp::UnregistrationParams,
12842        cx: &mut Context<Self>,
12843    ) -> anyhow::Result<()> {
12844        let server = self
12845            .language_server_for_id(server_id)
12846            .with_context(|| format!("no server {server_id} found"))?;
12847        for unreg in params.unregisterations.iter() {
12848            match unreg.method.as_str() {
12849                "workspace/didChangeWatchedFiles" => {
12850                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12851                        local_lsp_store
12852                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12853                        true
12854                    } else {
12855                        false
12856                    };
12857                    if notify {
12858                        notify_server_capabilities_updated(&server, cx);
12859                    }
12860                }
12861                "workspace/didChangeConfiguration" => {
12862                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12863                }
12864                "workspace/didChangeWorkspaceFolders" => {
12865                    server.update_capabilities(|capabilities| {
12866                        capabilities
12867                            .workspace
12868                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12869                                workspace_folders: None,
12870                                file_operations: None,
12871                            })
12872                            .workspace_folders = None;
12873                    });
12874                    notify_server_capabilities_updated(&server, cx);
12875                }
12876                "workspace/symbol" => {
12877                    server.update_capabilities(|capabilities| {
12878                        capabilities.workspace_symbol_provider = None
12879                    });
12880                    notify_server_capabilities_updated(&server, cx);
12881                }
12882                "workspace/fileOperations" => {
12883                    server.update_capabilities(|capabilities| {
12884                        capabilities
12885                            .workspace
12886                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12887                                workspace_folders: None,
12888                                file_operations: None,
12889                            })
12890                            .file_operations = None;
12891                    });
12892                    notify_server_capabilities_updated(&server, cx);
12893                }
12894                "workspace/executeCommand" => {
12895                    server.update_capabilities(|capabilities| {
12896                        capabilities.execute_command_provider = None;
12897                    });
12898                    notify_server_capabilities_updated(&server, cx);
12899                }
12900                "textDocument/rangeFormatting" => {
12901                    server.update_capabilities(|capabilities| {
12902                        capabilities.document_range_formatting_provider = None
12903                    });
12904                    notify_server_capabilities_updated(&server, cx);
12905                }
12906                "textDocument/onTypeFormatting" => {
12907                    server.update_capabilities(|capabilities| {
12908                        capabilities.document_on_type_formatting_provider = None;
12909                    });
12910                    notify_server_capabilities_updated(&server, cx);
12911                }
12912                "textDocument/formatting" => {
12913                    server.update_capabilities(|capabilities| {
12914                        capabilities.document_formatting_provider = None;
12915                    });
12916                    notify_server_capabilities_updated(&server, cx);
12917                }
12918                "textDocument/rename" => {
12919                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12920                    notify_server_capabilities_updated(&server, cx);
12921                }
12922                "textDocument/codeAction" => {
12923                    server.update_capabilities(|capabilities| {
12924                        capabilities.code_action_provider = None;
12925                    });
12926                    notify_server_capabilities_updated(&server, cx);
12927                }
12928                "textDocument/definition" => {
12929                    server.update_capabilities(|capabilities| {
12930                        capabilities.definition_provider = None;
12931                    });
12932                    notify_server_capabilities_updated(&server, cx);
12933                }
12934                "textDocument/completion" => {
12935                    server.update_capabilities(|capabilities| {
12936                        capabilities.completion_provider = None;
12937                    });
12938                    notify_server_capabilities_updated(&server, cx);
12939                }
12940                "textDocument/hover" => {
12941                    server.update_capabilities(|capabilities| {
12942                        capabilities.hover_provider = None;
12943                    });
12944                    notify_server_capabilities_updated(&server, cx);
12945                }
12946                "textDocument/signatureHelp" => {
12947                    server.update_capabilities(|capabilities| {
12948                        capabilities.signature_help_provider = None;
12949                    });
12950                    notify_server_capabilities_updated(&server, cx);
12951                }
12952                "textDocument/didChange" => {
12953                    server.update_capabilities(|capabilities| {
12954                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12955                        sync_options.change = None;
12956                        capabilities.text_document_sync =
12957                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12958                    });
12959                    notify_server_capabilities_updated(&server, cx);
12960                }
12961                "textDocument/didSave" => {
12962                    server.update_capabilities(|capabilities| {
12963                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12964                        sync_options.save = None;
12965                        capabilities.text_document_sync =
12966                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12967                    });
12968                    notify_server_capabilities_updated(&server, cx);
12969                }
12970                "textDocument/codeLens" => {
12971                    server.update_capabilities(|capabilities| {
12972                        capabilities.code_lens_provider = None;
12973                    });
12974                    notify_server_capabilities_updated(&server, cx);
12975                }
12976                "textDocument/diagnostic" => {
12977                    let local = self
12978                        .as_local_mut()
12979                        .context("Expected LSP Store to be local")?;
12980
12981                    let state = local
12982                        .language_servers
12983                        .get_mut(&server_id)
12984                        .context("Could not obtain Language Servers state")?;
12985                    let registrations = local
12986                        .language_server_dynamic_registrations
12987                        .get_mut(&server_id)
12988                        .with_context(|| {
12989                            format!("Expected dynamic registration to exist for server {server_id}")
12990                        })?;
12991                    registrations.diagnostics
12992                        .remove(&Some(unreg.id.clone()))
12993                        .with_context(|| format!(
12994                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12995                            unreg.id)
12996                        )?;
12997                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12998
12999                    if let LanguageServerState::Running {
13000                        workspace_diagnostics_refresh_tasks,
13001                        ..
13002                    } = state
13003                    {
13004                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
13005                    }
13006
13007                    self.clear_unregistered_diagnostics(
13008                        server_id,
13009                        SharedString::from(unreg.id.clone()),
13010                        cx,
13011                    )?;
13012
13013                    if removed_last_diagnostic_provider {
13014                        server.update_capabilities(|capabilities| {
13015                            debug_assert!(capabilities.diagnostic_provider.is_some());
13016                            capabilities.diagnostic_provider = None;
13017                        });
13018                    }
13019
13020                    notify_server_capabilities_updated(&server, cx);
13021                }
13022                "textDocument/documentColor" => {
13023                    server.update_capabilities(|capabilities| {
13024                        capabilities.color_provider = None;
13025                    });
13026                    notify_server_capabilities_updated(&server, cx);
13027                }
13028                "textDocument/foldingRange" => {
13029                    server.update_capabilities(|capabilities| {
13030                        capabilities.folding_range_provider = None;
13031                    });
13032                    notify_server_capabilities_updated(&server, cx);
13033                }
13034                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13035            }
13036        }
13037
13038        Ok(())
13039    }
13040
13041    fn clear_unregistered_diagnostics(
13042        &mut self,
13043        server_id: LanguageServerId,
13044        cleared_registration_id: SharedString,
13045        cx: &mut Context<Self>,
13046    ) -> anyhow::Result<()> {
13047        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13048
13049        self.buffer_store.update(cx, |buffer_store, cx| {
13050            for buffer_handle in buffer_store.buffers() {
13051                let buffer = buffer_handle.read(cx);
13052                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13053                let Some(abs_path) = abs_path else {
13054                    continue;
13055                };
13056                affected_abs_paths.insert(abs_path);
13057            }
13058        });
13059
13060        let local = self.as_local().context("Expected LSP Store to be local")?;
13061        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13062            let Some(worktree) = self
13063                .worktree_store
13064                .read(cx)
13065                .worktree_for_id(*worktree_id, cx)
13066            else {
13067                continue;
13068            };
13069
13070            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13071                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13072                    let has_matching_registration =
13073                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13074                            entry.diagnostic.registration_id.as_ref()
13075                                == Some(&cleared_registration_id)
13076                        });
13077                    if has_matching_registration {
13078                        let abs_path = worktree.read(cx).absolutize(rel_path);
13079                        affected_abs_paths.insert(abs_path);
13080                    }
13081                }
13082            }
13083        }
13084
13085        if affected_abs_paths.is_empty() {
13086            return Ok(());
13087        }
13088
13089        // Send a fake diagnostic update which clears the state for the registration ID
13090        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13091            affected_abs_paths
13092                .into_iter()
13093                .map(|abs_path| DocumentDiagnosticsUpdate {
13094                    diagnostics: DocumentDiagnostics {
13095                        diagnostics: Vec::new(),
13096                        document_abs_path: abs_path,
13097                        version: None,
13098                    },
13099                    result_id: None,
13100                    registration_id: Some(cleared_registration_id.clone()),
13101                    server_id,
13102                    disk_based_sources: Cow::Borrowed(&[]),
13103                })
13104                .collect();
13105
13106        let merge_registration_id = cleared_registration_id.clone();
13107        self.merge_diagnostic_entries(
13108            clears,
13109            move |_, diagnostic, _| {
13110                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13111                    diagnostic.registration_id != Some(merge_registration_id.clone())
13112                } else {
13113                    true
13114                }
13115            },
13116            cx,
13117        )?;
13118
13119        Ok(())
13120    }
13121
13122    async fn deduplicate_range_based_lsp_requests<T>(
13123        lsp_store: &Entity<Self>,
13124        server_id: Option<LanguageServerId>,
13125        lsp_request_id: LspRequestId,
13126        proto_request: &T::ProtoRequest,
13127        range: Range<Anchor>,
13128        cx: &mut AsyncApp,
13129    ) -> Result<()>
13130    where
13131        T: LspCommand,
13132        T::ProtoRequest: proto::LspRequestMessage,
13133    {
13134        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13135        let version = deserialize_version(proto_request.buffer_version());
13136        let buffer = lsp_store.update(cx, |this, cx| {
13137            this.buffer_store.read(cx).get_existing(buffer_id)
13138        })?;
13139        buffer
13140            .update(cx, |buffer, _| buffer.wait_for_version(version))
13141            .await?;
13142        lsp_store.update(cx, |lsp_store, cx| {
13143            let buffer_snapshot = buffer.read(cx).snapshot();
13144            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13145            let chunks_queried_for = lsp_data
13146                .inlay_hints
13147                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13148                .collect::<Vec<_>>();
13149            match chunks_queried_for.as_slice() {
13150                &[chunk] => {
13151                    let key = LspKey {
13152                        request_type: TypeId::of::<T>(),
13153                        server_queried: server_id,
13154                    };
13155                    let previous_request = lsp_data
13156                        .chunk_lsp_requests
13157                        .entry(key)
13158                        .or_default()
13159                        .insert(chunk, lsp_request_id);
13160                    if let Some((previous_request, running_requests)) =
13161                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13162                    {
13163                        running_requests.remove(&previous_request);
13164                    }
13165                }
13166                _ambiguous_chunks => {
13167                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13168                    // there, a buffer version-based check will be performed and outdated requests discarded.
13169                }
13170            }
13171            anyhow::Ok(())
13172        })?;
13173
13174        Ok(())
13175    }
13176
13177    async fn query_lsp_locally<T>(
13178        lsp_store: Entity<Self>,
13179        for_server_id: Option<LanguageServerId>,
13180        sender_id: proto::PeerId,
13181        lsp_request_id: LspRequestId,
13182        proto_request: T::ProtoRequest,
13183        position: Option<Anchor>,
13184        cx: &mut AsyncApp,
13185    ) -> Result<()>
13186    where
13187        T: LspCommand + Clone,
13188        T::ProtoRequest: proto::LspRequestMessage,
13189        <T::ProtoRequest as proto::RequestMessage>::Response:
13190            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13191    {
13192        let (buffer_version, buffer) =
13193            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13194        let request =
13195            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13196        let key = LspKey {
13197            request_type: TypeId::of::<T>(),
13198            server_queried: for_server_id,
13199        };
13200        lsp_store.update(cx, |lsp_store, cx| {
13201            let request_task = match for_server_id {
13202                Some(server_id) => {
13203                    let server_task = lsp_store.request_lsp(
13204                        buffer.clone(),
13205                        LanguageServerToQuery::Other(server_id),
13206                        request.clone(),
13207                        cx,
13208                    );
13209                    cx.background_spawn(async move {
13210                        let mut responses = Vec::new();
13211                        match server_task.await {
13212                            Ok(response) => responses.push((server_id, response)),
13213                            // rust-analyzer likes to error with this when its still loading up
13214                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13215                            Err(e) => log::error!(
13216                                "Error handling response for request {request:?}: {e:#}"
13217                            ),
13218                        }
13219                        responses
13220                    })
13221                }
13222                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13223            };
13224            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13225            if T::ProtoRequest::stop_previous_requests() {
13226                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13227                    lsp_requests.clear();
13228                }
13229            }
13230            lsp_data.lsp_requests.entry(key).or_default().insert(
13231                lsp_request_id,
13232                cx.spawn(async move |lsp_store, cx| {
13233                    let response = request_task.await;
13234                    lsp_store
13235                        .update(cx, |lsp_store, cx| {
13236                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13237                            {
13238                                let response = response
13239                                    .into_iter()
13240                                    .map(|(server_id, response)| {
13241                                        (
13242                                            server_id.to_proto(),
13243                                            T::response_to_proto(
13244                                                response,
13245                                                lsp_store,
13246                                                sender_id,
13247                                                &buffer_version,
13248                                                cx,
13249                                            )
13250                                            .into(),
13251                                        )
13252                                    })
13253                                    .collect::<HashMap<_, _>>();
13254                                match client.send_lsp_response::<T::ProtoRequest>(
13255                                    project_id,
13256                                    lsp_request_id,
13257                                    response,
13258                                ) {
13259                                    Ok(()) => {}
13260                                    Err(e) => {
13261                                        log::error!("Failed to send LSP response: {e:#}",)
13262                                    }
13263                                }
13264                            }
13265                        })
13266                        .ok();
13267                }),
13268            );
13269        });
13270        Ok(())
13271    }
13272
13273    async fn wait_for_buffer_version<T>(
13274        lsp_store: &Entity<Self>,
13275        proto_request: &T::ProtoRequest,
13276        cx: &mut AsyncApp,
13277    ) -> Result<(Global, Entity<Buffer>)>
13278    where
13279        T: LspCommand,
13280        T::ProtoRequest: proto::LspRequestMessage,
13281    {
13282        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13283        let version = deserialize_version(proto_request.buffer_version());
13284        let buffer = lsp_store.update(cx, |this, cx| {
13285            this.buffer_store.read(cx).get_existing(buffer_id)
13286        })?;
13287        buffer
13288            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13289            .await?;
13290        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13291        Ok((buffer_version, buffer))
13292    }
13293
13294    fn take_text_document_sync_options(
13295        capabilities: &mut lsp::ServerCapabilities,
13296    ) -> lsp::TextDocumentSyncOptions {
13297        match capabilities.text_document_sync.take() {
13298            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13299            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13300                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13301                sync_options.change = Some(sync_kind);
13302                sync_options
13303            }
13304            None => lsp::TextDocumentSyncOptions::default(),
13305        }
13306    }
13307
13308    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13309        self.downstream_client.clone()
13310    }
13311
13312    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13313        self.worktree_store.clone()
13314    }
13315
13316    /// Gets what's stored in the LSP data for the given buffer.
13317    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13318        self.lsp_data.get_mut(&buffer_id)
13319    }
13320
13321    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13322    /// new [`BufferLspData`] will be created to replace the previous state.
13323    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13324        let (buffer_id, buffer_version) =
13325            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13326        let lsp_data = self
13327            .lsp_data
13328            .entry(buffer_id)
13329            .or_insert_with(|| BufferLspData::new(buffer, cx));
13330        if buffer_version.changed_since(&lsp_data.buffer_version) {
13331            // To send delta requests for semantic tokens, the previous tokens
13332            // need to be kept between buffer changes.
13333            let semantic_tokens = lsp_data.semantic_tokens.take();
13334            *lsp_data = BufferLspData::new(buffer, cx);
13335            lsp_data.semantic_tokens = semantic_tokens;
13336        }
13337        lsp_data
13338    }
13339}
13340
13341// Registration with registerOptions as null, should fallback to true.
13342// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13343fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13344    reg: lsp::Registration,
13345) -> Result<OneOf<bool, T>> {
13346    Ok(match reg.register_options {
13347        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13348        None => OneOf::Left(true),
13349    })
13350}
13351
13352fn subscribe_to_binary_statuses(
13353    languages: &Arc<LanguageRegistry>,
13354    cx: &mut Context<'_, LspStore>,
13355) -> Task<()> {
13356    let mut server_statuses = languages.language_server_binary_statuses();
13357    cx.spawn(async move |lsp_store, cx| {
13358        while let Some((server_name, binary_status)) = server_statuses.next().await {
13359            if lsp_store
13360                .update(cx, |_, cx| {
13361                    let mut message = None;
13362                    let binary_status = match binary_status {
13363                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13364                        BinaryStatus::CheckingForUpdate => {
13365                            proto::ServerBinaryStatus::CheckingForUpdate
13366                        }
13367                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13368                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13369                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13370                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13371                        BinaryStatus::Failed { error } => {
13372                            message = Some(error);
13373                            proto::ServerBinaryStatus::Failed
13374                        }
13375                    };
13376                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13377                        // Binary updates are about the binary that might not have any language server id at that point.
13378                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13379                        language_server_id: LanguageServerId(0),
13380                        name: Some(server_name),
13381                        message: proto::update_language_server::Variant::StatusUpdate(
13382                            proto::StatusUpdate {
13383                                message,
13384                                status: Some(proto::status_update::Status::Binary(
13385                                    binary_status as i32,
13386                                )),
13387                            },
13388                        ),
13389                    });
13390                })
13391                .is_err()
13392            {
13393                break;
13394            }
13395        }
13396    })
13397}
13398
13399fn lsp_workspace_diagnostics_refresh(
13400    registration_id: Option<String>,
13401    options: DiagnosticServerCapabilities,
13402    server: Arc<LanguageServer>,
13403    cx: &mut Context<'_, LspStore>,
13404) -> Option<WorkspaceRefreshTask> {
13405    let identifier = workspace_diagnostic_identifier(&options)?;
13406    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13407
13408    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13409    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13410    refresh_tx.try_send(()).ok();
13411
13412    let request_timeout = ProjectSettings::get_global(cx)
13413        .global_lsp_settings
13414        .get_request_timeout();
13415
13416    // 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.
13417    // This allows users to increase the duration if need be
13418    let timeout = if request_timeout != Duration::ZERO {
13419        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13420    } else {
13421        request_timeout
13422    };
13423
13424    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13425        let mut attempts = 0;
13426        let max_attempts = 50;
13427        let mut requests = 0;
13428
13429        loop {
13430            let Some(()) = refresh_rx.recv().await else {
13431                return;
13432            };
13433
13434            'request: loop {
13435                requests += 1;
13436                if attempts > max_attempts {
13437                    log::error!(
13438                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13439                    );
13440                    return;
13441                }
13442                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13443                cx.background_executor()
13444                    .timer(Duration::from_millis(backoff_millis))
13445                    .await;
13446                attempts += 1;
13447
13448                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13449                    lsp_store
13450                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13451                        .into_iter()
13452                        .filter_map(|(abs_path, result_id)| {
13453                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13454                            Some(lsp::PreviousResultId {
13455                                uri,
13456                                value: result_id.to_string(),
13457                            })
13458                        })
13459                        .collect()
13460                }) else {
13461                    return;
13462                };
13463
13464                let token = if let Some(registration_id) = &registration_id {
13465                    format!(
13466                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13467                        server.server_id(),
13468                    )
13469                } else {
13470                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13471                };
13472
13473                progress_rx.try_recv().ok();
13474                let timer = server.request_timer(timeout).fuse();
13475                let progress = pin!(progress_rx.recv().fuse());
13476                let response_result = server
13477                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13478                        lsp::WorkspaceDiagnosticParams {
13479                            previous_result_ids,
13480                            identifier: identifier.clone(),
13481                            work_done_progress_params: Default::default(),
13482                            partial_result_params: lsp::PartialResultParams {
13483                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13484                            },
13485                        },
13486                        select(timer, progress).then(|either| match either {
13487                            Either::Left((message, ..)) => ready(message).left_future(),
13488                            Either::Right(..) => pending::<String>().right_future(),
13489                        }),
13490                    )
13491                    .await;
13492
13493                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13494                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13495                match response_result {
13496                    ConnectionResult::Timeout => {
13497                        log::error!("Timeout during workspace diagnostics pull");
13498                        continue 'request;
13499                    }
13500                    ConnectionResult::ConnectionReset => {
13501                        log::error!("Server closed a workspace diagnostics pull request");
13502                        continue 'request;
13503                    }
13504                    ConnectionResult::Result(Err(e)) => {
13505                        log::error!("Error during workspace diagnostics pull: {e:#}");
13506                        break 'request;
13507                    }
13508                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13509                        attempts = 0;
13510                        if lsp_store
13511                            .update(cx, |lsp_store, cx| {
13512                                lsp_store.apply_workspace_diagnostic_report(
13513                                    server.server_id(),
13514                                    pulled_diagnostics,
13515                                    registration_id_shared.clone(),
13516                                    cx,
13517                                )
13518                            })
13519                            .is_err()
13520                        {
13521                            return;
13522                        }
13523                        break 'request;
13524                    }
13525                }
13526            }
13527        }
13528    });
13529
13530    Some(WorkspaceRefreshTask {
13531        refresh_tx,
13532        progress_tx,
13533        task: workspace_query_language_server,
13534    })
13535}
13536
13537fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13538    match &options {
13539        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13540            .identifier
13541            .as_deref()
13542            .map(SharedString::new),
13543        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13544            let diagnostic_options = &registration_options.diagnostic_options;
13545            diagnostic_options
13546                .identifier
13547                .as_deref()
13548                .map(SharedString::new)
13549        }
13550    }
13551}
13552
13553fn workspace_diagnostic_identifier(
13554    options: &DiagnosticServerCapabilities,
13555) -> Option<Option<String>> {
13556    match &options {
13557        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13558            if !diagnostic_options.workspace_diagnostics {
13559                return None;
13560            }
13561            Some(diagnostic_options.identifier.clone())
13562        }
13563        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13564            let diagnostic_options = &registration_options.diagnostic_options;
13565            if !diagnostic_options.workspace_diagnostics {
13566                return None;
13567            }
13568            Some(diagnostic_options.identifier.clone())
13569        }
13570    }
13571}
13572
13573fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13574    let CompletionSource::BufferWord {
13575        word_range,
13576        resolved,
13577    } = &mut completion.source
13578    else {
13579        return;
13580    };
13581    if *resolved {
13582        return;
13583    }
13584
13585    if completion.new_text
13586        != snapshot
13587            .text_for_range(word_range.clone())
13588            .collect::<String>()
13589    {
13590        return;
13591    }
13592
13593    let mut offset = 0;
13594    for chunk in snapshot.chunks(
13595        word_range.clone(),
13596        LanguageAwareStyling {
13597            tree_sitter: true,
13598            diagnostics: true,
13599        },
13600    ) {
13601        let end_offset = offset + chunk.text.len();
13602        if let Some(highlight_id) = chunk.syntax_highlight_id {
13603            completion
13604                .label
13605                .runs
13606                .push((offset..end_offset, highlight_id));
13607        }
13608        offset = end_offset;
13609    }
13610    *resolved = true;
13611}
13612
13613impl EventEmitter<LspStoreEvent> for LspStore {}
13614
13615fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13616    hover
13617        .contents
13618        .retain(|hover_block| !hover_block.text.trim().is_empty());
13619    if hover.contents.is_empty() {
13620        None
13621    } else {
13622        Some(hover)
13623    }
13624}
13625
13626async fn populate_labels_for_completions(
13627    new_completions: Vec<CoreCompletion>,
13628    language: Option<Arc<Language>>,
13629    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13630) -> Vec<Completion> {
13631    let lsp_completions = new_completions
13632        .iter()
13633        .filter_map(|new_completion| {
13634            new_completion
13635                .source
13636                .lsp_completion(true)
13637                .map(|lsp_completion| lsp_completion.into_owned())
13638        })
13639        .collect::<Vec<_>>();
13640
13641    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13642        lsp_adapter
13643            .labels_for_completions(&lsp_completions, language)
13644            .await
13645            .log_err()
13646            .unwrap_or_default()
13647    } else {
13648        Vec::new()
13649    }
13650    .into_iter()
13651    .fuse();
13652
13653    let mut completions = Vec::new();
13654    for completion in new_completions {
13655        match completion.source.lsp_completion(true) {
13656            Some(lsp_completion) => {
13657                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13658
13659                let mut label = labels.next().flatten().unwrap_or_else(|| {
13660                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13661                });
13662                ensure_uniform_list_compatible_label(&mut label);
13663                completions.push(Completion {
13664                    label,
13665                    documentation,
13666                    replace_range: completion.replace_range,
13667                    new_text: completion.new_text,
13668                    insert_text_mode: lsp_completion.insert_text_mode,
13669                    source: completion.source,
13670                    icon_path: None,
13671                    confirm: None,
13672                    match_start: None,
13673                    snippet_deduplication_key: None,
13674                });
13675            }
13676            None => {
13677                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13678                ensure_uniform_list_compatible_label(&mut label);
13679                completions.push(Completion {
13680                    label,
13681                    documentation: None,
13682                    replace_range: completion.replace_range,
13683                    new_text: completion.new_text,
13684                    source: completion.source,
13685                    insert_text_mode: None,
13686                    icon_path: None,
13687                    confirm: None,
13688                    match_start: None,
13689                    snippet_deduplication_key: None,
13690                });
13691            }
13692        }
13693    }
13694    completions
13695}
13696
13697#[derive(Debug)]
13698pub enum LanguageServerToQuery {
13699    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13700    FirstCapable,
13701    /// Query a specific language server.
13702    Other(LanguageServerId),
13703}
13704
13705#[derive(Default)]
13706struct RenamePathsWatchedForServer {
13707    did_rename: Vec<RenameActionPredicate>,
13708    will_rename: Vec<RenameActionPredicate>,
13709}
13710
13711impl RenamePathsWatchedForServer {
13712    fn with_did_rename_patterns(
13713        mut self,
13714        did_rename: Option<&FileOperationRegistrationOptions>,
13715    ) -> Self {
13716        if let Some(did_rename) = did_rename {
13717            self.did_rename = did_rename
13718                .filters
13719                .iter()
13720                .filter_map(|filter| filter.try_into().log_err())
13721                .collect();
13722        }
13723        self
13724    }
13725    fn with_will_rename_patterns(
13726        mut self,
13727        will_rename: Option<&FileOperationRegistrationOptions>,
13728    ) -> Self {
13729        if let Some(will_rename) = will_rename {
13730            self.will_rename = will_rename
13731                .filters
13732                .iter()
13733                .filter_map(|filter| filter.try_into().log_err())
13734                .collect();
13735        }
13736        self
13737    }
13738
13739    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13740        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13741    }
13742    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13743        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13744    }
13745}
13746
13747impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13748    type Error = globset::Error;
13749    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13750        Ok(Self {
13751            kind: ops.pattern.matches.clone(),
13752            glob: GlobBuilder::new(&ops.pattern.glob)
13753                .case_insensitive(
13754                    ops.pattern
13755                        .options
13756                        .as_ref()
13757                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13758                )
13759                .build()?
13760                .compile_matcher(),
13761        })
13762    }
13763}
13764struct RenameActionPredicate {
13765    glob: GlobMatcher,
13766    kind: Option<FileOperationPatternKind>,
13767}
13768
13769impl RenameActionPredicate {
13770    // Returns true if language server should be notified
13771    fn eval(&self, path: &str, is_dir: bool) -> bool {
13772        self.kind.as_ref().is_none_or(|kind| {
13773            let expected_kind = if is_dir {
13774                FileOperationPatternKind::Folder
13775            } else {
13776                FileOperationPatternKind::File
13777            };
13778            kind == &expected_kind
13779        }) && self.glob.is_match(path)
13780    }
13781}
13782
13783#[derive(Default)]
13784struct LanguageServerWatchedPaths {
13785    worktree_paths: HashMap<WorktreeId, GlobSet>,
13786    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13787}
13788
13789#[derive(Default)]
13790struct LanguageServerWatchedPathsBuilder {
13791    worktree_paths: HashMap<WorktreeId, GlobSet>,
13792    abs_paths: HashMap<Arc<Path>, GlobSet>,
13793}
13794
13795impl LanguageServerWatchedPathsBuilder {
13796    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13797        self.worktree_paths.insert(worktree_id, glob_set);
13798    }
13799    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13800        self.abs_paths.insert(path, glob_set);
13801    }
13802    fn build(
13803        self,
13804        fs: Arc<dyn Fs>,
13805        language_server_id: LanguageServerId,
13806        cx: &mut Context<LspStore>,
13807    ) -> LanguageServerWatchedPaths {
13808        let lsp_store = cx.weak_entity();
13809
13810        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13811        let abs_paths = self
13812            .abs_paths
13813            .into_iter()
13814            .map(|(abs_path, globset)| {
13815                let task = cx.spawn({
13816                    let abs_path = abs_path.clone();
13817                    let fs = fs.clone();
13818
13819                    let lsp_store = lsp_store.clone();
13820                    async move |_, cx| {
13821                        maybe!(async move {
13822                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13823                            while let Some(update) = push_updates.0.next().await {
13824                                let action = lsp_store
13825                                    .update(cx, |this, _| {
13826                                        let Some(local) = this.as_local() else {
13827                                            return ControlFlow::Break(());
13828                                        };
13829                                        let Some(watcher) = local
13830                                            .language_server_watched_paths
13831                                            .get(&language_server_id)
13832                                        else {
13833                                            return ControlFlow::Break(());
13834                                        };
13835                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13836                                            "Watched abs path is not registered with a watcher",
13837                                        );
13838                                        let matching_entries = update
13839                                            .into_iter()
13840                                            .filter(|event| globs.is_match(&event.path))
13841                                            .collect::<Vec<_>>();
13842                                        this.lsp_notify_abs_paths_changed(
13843                                            language_server_id,
13844                                            matching_entries,
13845                                        );
13846                                        ControlFlow::Continue(())
13847                                    })
13848                                    .ok()?;
13849
13850                                if action.is_break() {
13851                                    break;
13852                                }
13853                            }
13854                            Some(())
13855                        })
13856                        .await;
13857                    }
13858                });
13859                (abs_path, (globset, task))
13860            })
13861            .collect();
13862        LanguageServerWatchedPaths {
13863            worktree_paths: self.worktree_paths,
13864            abs_paths,
13865        }
13866    }
13867}
13868
13869struct LspBufferSnapshot {
13870    version: i32,
13871    snapshot: TextBufferSnapshot,
13872}
13873
13874/// A prompt requested by LSP server.
13875#[derive(Clone, Debug)]
13876pub struct LanguageServerPromptRequest {
13877    pub id: usize,
13878    pub level: PromptLevel,
13879    pub message: String,
13880    pub actions: Vec<MessageActionItem>,
13881    pub lsp_name: String,
13882    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13883}
13884
13885impl LanguageServerPromptRequest {
13886    pub fn new(
13887        level: PromptLevel,
13888        message: String,
13889        actions: Vec<MessageActionItem>,
13890        lsp_name: String,
13891        response_channel: smol::channel::Sender<MessageActionItem>,
13892    ) -> Self {
13893        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13894        LanguageServerPromptRequest {
13895            id,
13896            level,
13897            message,
13898            actions,
13899            lsp_name,
13900            response_channel,
13901        }
13902    }
13903    pub async fn respond(self, index: usize) -> Option<()> {
13904        if let Some(response) = self.actions.into_iter().nth(index) {
13905            self.response_channel.send(response).await.ok()
13906        } else {
13907            None
13908        }
13909    }
13910
13911    #[cfg(any(test, feature = "test-support"))]
13912    pub fn test(
13913        level: PromptLevel,
13914        message: String,
13915        actions: Vec<MessageActionItem>,
13916        lsp_name: String,
13917    ) -> Self {
13918        let (tx, _rx) = smol::channel::unbounded();
13919        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13920    }
13921}
13922impl PartialEq for LanguageServerPromptRequest {
13923    fn eq(&self, other: &Self) -> bool {
13924        self.message == other.message && self.actions == other.actions
13925    }
13926}
13927
13928#[derive(Clone, Debug, PartialEq)]
13929pub enum LanguageServerLogType {
13930    Log(MessageType),
13931    Trace { verbose_info: Option<String> },
13932    Rpc { received: bool },
13933}
13934
13935impl LanguageServerLogType {
13936    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13937        match self {
13938            Self::Log(log_type) => {
13939                use proto::log_message::LogLevel;
13940                let level = match *log_type {
13941                    MessageType::ERROR => LogLevel::Error,
13942                    MessageType::WARNING => LogLevel::Warning,
13943                    MessageType::INFO => LogLevel::Info,
13944                    MessageType::LOG => LogLevel::Log,
13945                    other => {
13946                        log::warn!("Unknown lsp log message type: {other:?}");
13947                        LogLevel::Log
13948                    }
13949                };
13950                proto::language_server_log::LogType::Log(proto::LogMessage {
13951                    level: level as i32,
13952                })
13953            }
13954            Self::Trace { verbose_info } => {
13955                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13956                    verbose_info: verbose_info.to_owned(),
13957                })
13958            }
13959            Self::Rpc { received } => {
13960                let kind = if *received {
13961                    proto::rpc_message::Kind::Received
13962                } else {
13963                    proto::rpc_message::Kind::Sent
13964                };
13965                let kind = kind as i32;
13966                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13967            }
13968        }
13969    }
13970
13971    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13972        use proto::log_message::LogLevel;
13973        use proto::rpc_message;
13974        match log_type {
13975            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13976                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13977                    LogLevel::Error => MessageType::ERROR,
13978                    LogLevel::Warning => MessageType::WARNING,
13979                    LogLevel::Info => MessageType::INFO,
13980                    LogLevel::Log => MessageType::LOG,
13981                },
13982            ),
13983            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13984                verbose_info: trace_message.verbose_info,
13985            },
13986            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13987                received: match rpc_message::Kind::from_i32(message.kind)
13988                    .unwrap_or(rpc_message::Kind::Received)
13989                {
13990                    rpc_message::Kind::Received => true,
13991                    rpc_message::Kind::Sent => false,
13992                },
13993            },
13994        }
13995    }
13996}
13997
13998pub struct WorkspaceRefreshTask {
13999    refresh_tx: mpsc::Sender<()>,
14000    progress_tx: mpsc::Sender<()>,
14001    #[allow(dead_code)]
14002    task: Task<()>,
14003}
14004
14005pub enum LanguageServerState {
14006    Starting {
14007        startup: Task<Option<Arc<LanguageServer>>>,
14008        /// List of language servers that will be added to the workspace once it's initialization completes.
14009        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
14010    },
14011
14012    Running {
14013        adapter: Arc<CachedLspAdapter>,
14014        server: Arc<LanguageServer>,
14015        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
14016        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
14017    },
14018}
14019
14020impl LanguageServerState {
14021    fn add_workspace_folder(&self, uri: Uri) {
14022        match self {
14023            LanguageServerState::Starting {
14024                pending_workspace_folders,
14025                ..
14026            } => {
14027                pending_workspace_folders.lock().insert(uri);
14028            }
14029            LanguageServerState::Running { server, .. } => {
14030                server.add_workspace_folder(uri);
14031            }
14032        }
14033    }
14034    fn _remove_workspace_folder(&self, uri: Uri) {
14035        match self {
14036            LanguageServerState::Starting {
14037                pending_workspace_folders,
14038                ..
14039            } => {
14040                pending_workspace_folders.lock().remove(&uri);
14041            }
14042            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
14043        }
14044    }
14045}
14046
14047impl std::fmt::Debug for LanguageServerState {
14048    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14049        match self {
14050            LanguageServerState::Starting { .. } => {
14051                f.debug_struct("LanguageServerState::Starting").finish()
14052            }
14053            LanguageServerState::Running { .. } => {
14054                f.debug_struct("LanguageServerState::Running").finish()
14055            }
14056        }
14057    }
14058}
14059
14060#[derive(Clone, Debug, Serialize)]
14061pub struct LanguageServerProgress {
14062    pub is_disk_based_diagnostics_progress: bool,
14063    pub is_cancellable: bool,
14064    pub title: Option<String>,
14065    pub message: Option<String>,
14066    pub percentage: Option<usize>,
14067    #[serde(skip_serializing)]
14068    pub last_update_at: Instant,
14069}
14070
14071#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14072pub struct DiagnosticSummary {
14073    pub error_count: usize,
14074    pub warning_count: usize,
14075}
14076
14077impl DiagnosticSummary {
14078    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14079        let mut this = Self {
14080            error_count: 0,
14081            warning_count: 0,
14082        };
14083
14084        for entry in diagnostics {
14085            if entry.diagnostic.is_primary {
14086                match entry.diagnostic.severity {
14087                    DiagnosticSeverity::ERROR => this.error_count += 1,
14088                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14089                    _ => {}
14090                }
14091            }
14092        }
14093
14094        this
14095    }
14096
14097    pub fn is_empty(&self) -> bool {
14098        self.error_count == 0 && self.warning_count == 0
14099    }
14100
14101    pub fn to_proto(
14102        self,
14103        language_server_id: LanguageServerId,
14104        path: &RelPath,
14105    ) -> proto::DiagnosticSummary {
14106        proto::DiagnosticSummary {
14107            path: path.to_proto(),
14108            language_server_id: language_server_id.0 as u64,
14109            error_count: self.error_count as u32,
14110            warning_count: self.warning_count as u32,
14111        }
14112    }
14113}
14114
14115#[derive(Clone, Debug)]
14116pub enum CompletionDocumentation {
14117    /// There is no documentation for this completion.
14118    Undocumented,
14119    /// A single line of documentation.
14120    SingleLine(SharedString),
14121    /// Multiple lines of plain text documentation.
14122    MultiLinePlainText(SharedString),
14123    /// Markdown documentation.
14124    MultiLineMarkdown(SharedString),
14125    /// Both single line and multiple lines of plain text documentation.
14126    SingleLineAndMultiLinePlainText {
14127        single_line: SharedString,
14128        plain_text: Option<SharedString>,
14129    },
14130}
14131
14132impl CompletionDocumentation {
14133    #[cfg(any(test, feature = "test-support"))]
14134    pub fn text(&self) -> SharedString {
14135        match self {
14136            CompletionDocumentation::Undocumented => "".into(),
14137            CompletionDocumentation::SingleLine(s) => s.clone(),
14138            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14139            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14140            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14141                single_line.clone()
14142            }
14143        }
14144    }
14145}
14146
14147impl From<lsp::Documentation> for CompletionDocumentation {
14148    fn from(docs: lsp::Documentation) -> Self {
14149        match docs {
14150            lsp::Documentation::String(text) => {
14151                if text.lines().count() <= 1 {
14152                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14153                } else {
14154                    CompletionDocumentation::MultiLinePlainText(text.into())
14155                }
14156            }
14157
14158            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14159                lsp::MarkupKind::PlainText => {
14160                    if value.lines().count() <= 1 {
14161                        CompletionDocumentation::SingleLine(value.into())
14162                    } else {
14163                        CompletionDocumentation::MultiLinePlainText(value.into())
14164                    }
14165                }
14166
14167                lsp::MarkupKind::Markdown => {
14168                    CompletionDocumentation::MultiLineMarkdown(value.into())
14169                }
14170            },
14171        }
14172    }
14173}
14174
14175pub enum ResolvedHint {
14176    Resolved(InlayHint),
14177    Resolving(Shared<Task<()>>),
14178}
14179
14180pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14181    glob.components()
14182        .take_while(|component| match component {
14183            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14184            _ => true,
14185        })
14186        .collect()
14187}
14188
14189pub struct SshLspAdapter {
14190    name: LanguageServerName,
14191    binary: LanguageServerBinary,
14192    initialization_options: Option<String>,
14193    code_action_kinds: Option<Vec<CodeActionKind>>,
14194}
14195
14196impl SshLspAdapter {
14197    pub fn new(
14198        name: LanguageServerName,
14199        binary: LanguageServerBinary,
14200        initialization_options: Option<String>,
14201        code_action_kinds: Option<String>,
14202    ) -> Self {
14203        Self {
14204            name,
14205            binary,
14206            initialization_options,
14207            code_action_kinds: code_action_kinds
14208                .as_ref()
14209                .and_then(|c| serde_json::from_str(c).ok()),
14210        }
14211    }
14212}
14213
14214impl LspInstaller for SshLspAdapter {
14215    type BinaryVersion = ();
14216    async fn check_if_user_installed(
14217        &self,
14218        _: &dyn LspAdapterDelegate,
14219        _: Option<Toolchain>,
14220        _: &AsyncApp,
14221    ) -> Option<LanguageServerBinary> {
14222        Some(self.binary.clone())
14223    }
14224
14225    async fn cached_server_binary(
14226        &self,
14227        _: PathBuf,
14228        _: &dyn LspAdapterDelegate,
14229    ) -> Option<LanguageServerBinary> {
14230        None
14231    }
14232
14233    async fn fetch_latest_server_version(
14234        &self,
14235        _: &dyn LspAdapterDelegate,
14236        _: bool,
14237        _: &mut AsyncApp,
14238    ) -> Result<()> {
14239        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14240    }
14241
14242    async fn fetch_server_binary(
14243        &self,
14244        _: (),
14245        _: PathBuf,
14246        _: &dyn LspAdapterDelegate,
14247    ) -> Result<LanguageServerBinary> {
14248        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14249    }
14250}
14251
14252#[async_trait(?Send)]
14253impl LspAdapter for SshLspAdapter {
14254    fn name(&self) -> LanguageServerName {
14255        self.name.clone()
14256    }
14257
14258    async fn initialization_options(
14259        self: Arc<Self>,
14260        _: &Arc<dyn LspAdapterDelegate>,
14261        _: &mut AsyncApp,
14262    ) -> Result<Option<serde_json::Value>> {
14263        let Some(options) = &self.initialization_options else {
14264            return Ok(None);
14265        };
14266        let result = serde_json::from_str(options)?;
14267        Ok(result)
14268    }
14269
14270    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14271        self.code_action_kinds.clone()
14272    }
14273}
14274
14275pub fn language_server_settings<'a>(
14276    delegate: &'a dyn LspAdapterDelegate,
14277    language: &LanguageServerName,
14278    cx: &'a App,
14279) -> Option<&'a LspSettings> {
14280    language_server_settings_for(
14281        SettingsLocation {
14282            worktree_id: delegate.worktree_id(),
14283            path: RelPath::empty(),
14284        },
14285        language,
14286        cx,
14287    )
14288}
14289
14290pub fn language_server_settings_for<'a>(
14291    location: SettingsLocation<'a>,
14292    language: &LanguageServerName,
14293    cx: &'a App,
14294) -> Option<&'a LspSettings> {
14295    ProjectSettings::get(Some(location), cx).lsp.get(language)
14296}
14297
14298pub struct LocalLspAdapterDelegate {
14299    lsp_store: WeakEntity<LspStore>,
14300    worktree: worktree::Snapshot,
14301    fs: Arc<dyn Fs>,
14302    http_client: Arc<dyn HttpClient>,
14303    language_registry: Arc<LanguageRegistry>,
14304    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14305}
14306
14307impl LocalLspAdapterDelegate {
14308    pub fn new(
14309        language_registry: Arc<LanguageRegistry>,
14310        environment: &Entity<ProjectEnvironment>,
14311        lsp_store: WeakEntity<LspStore>,
14312        worktree: &Entity<Worktree>,
14313        http_client: Arc<dyn HttpClient>,
14314        fs: Arc<dyn Fs>,
14315        cx: &mut App,
14316    ) -> Arc<Self> {
14317        let load_shell_env_task =
14318            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14319
14320        Arc::new(Self {
14321            lsp_store,
14322            worktree: worktree.read(cx).snapshot(),
14323            fs,
14324            http_client,
14325            language_registry,
14326            load_shell_env_task,
14327        })
14328    }
14329
14330    pub fn from_local_lsp(
14331        local: &LocalLspStore,
14332        worktree: &Entity<Worktree>,
14333        cx: &mut App,
14334    ) -> Arc<Self> {
14335        Self::new(
14336            local.languages.clone(),
14337            &local.environment,
14338            local.weak.clone(),
14339            worktree,
14340            local.http_client.clone(),
14341            local.fs.clone(),
14342            cx,
14343        )
14344    }
14345}
14346
14347#[async_trait]
14348impl LspAdapterDelegate for LocalLspAdapterDelegate {
14349    fn show_notification(&self, message: &str, cx: &mut App) {
14350        self.lsp_store
14351            .update(cx, |_, cx| {
14352                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14353            })
14354            .ok();
14355    }
14356
14357    fn http_client(&self) -> Arc<dyn HttpClient> {
14358        self.http_client.clone()
14359    }
14360
14361    fn worktree_id(&self) -> WorktreeId {
14362        self.worktree.id()
14363    }
14364
14365    fn worktree_root_path(&self) -> &Path {
14366        self.worktree.abs_path().as_ref()
14367    }
14368
14369    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14370        self.worktree.resolve_relative_path(path)
14371    }
14372
14373    async fn shell_env(&self) -> HashMap<String, String> {
14374        let task = self.load_shell_env_task.clone();
14375        task.await.unwrap_or_default()
14376    }
14377
14378    async fn npm_package_installed_version(
14379        &self,
14380        package_name: &str,
14381    ) -> Result<Option<(PathBuf, Version)>> {
14382        let local_package_directory = self.worktree_root_path();
14383        let node_modules_directory = local_package_directory.join("node_modules");
14384
14385        if let Some(version) =
14386            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14387        {
14388            return Ok(Some((node_modules_directory, version)));
14389        }
14390        let Some(npm) = self.which("npm".as_ref()).await else {
14391            log::warn!(
14392                "Failed to find npm executable for {:?}",
14393                local_package_directory
14394            );
14395            return Ok(None);
14396        };
14397
14398        let env = self.shell_env().await;
14399        let output = util::command::new_command(&npm)
14400            .args(["root", "-g"])
14401            .envs(env)
14402            .current_dir(local_package_directory)
14403            .output()
14404            .await?;
14405        let global_node_modules =
14406            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14407
14408        if let Some(version) =
14409            read_package_installed_version(global_node_modules.clone(), package_name).await?
14410        {
14411            return Ok(Some((global_node_modules, version)));
14412        }
14413        return Ok(None);
14414    }
14415
14416    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14417        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14418        if self.fs.is_file(&worktree_abs_path).await {
14419            worktree_abs_path.pop();
14420        }
14421
14422        let env = self.shell_env().await;
14423
14424        let shell_path = env.get("PATH").cloned();
14425
14426        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14427    }
14428
14429    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14430        let mut working_dir = self.worktree_root_path().to_path_buf();
14431        if self.fs.is_file(&working_dir).await {
14432            working_dir.pop();
14433        }
14434        let output = util::command::new_command(&command.path)
14435            .args(command.arguments)
14436            .envs(command.env.clone().unwrap_or_default())
14437            .current_dir(working_dir)
14438            .output()
14439            .await?;
14440
14441        anyhow::ensure!(
14442            output.status.success(),
14443            "{}, stdout: {:?}, stderr: {:?}",
14444            output.status,
14445            String::from_utf8_lossy(&output.stdout),
14446            String::from_utf8_lossy(&output.stderr)
14447        );
14448        Ok(())
14449    }
14450
14451    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14452        self.language_registry
14453            .update_lsp_binary_status(server_name, status);
14454    }
14455
14456    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14457        self.language_registry
14458            .all_lsp_adapters()
14459            .into_iter()
14460            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14461            .collect()
14462    }
14463
14464    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14465        let dir = self.language_registry.language_server_download_dir(name)?;
14466
14467        if !dir.exists() {
14468            smol::fs::create_dir_all(&dir)
14469                .await
14470                .context("failed to create container directory")
14471                .log_err()?;
14472        }
14473
14474        Some(dir)
14475    }
14476
14477    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14478        let entry = self
14479            .worktree
14480            .entry_for_path(path)
14481            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14482        let abs_path = self.worktree.absolutize(&entry.path);
14483        self.fs.load(&abs_path).await
14484    }
14485}
14486
14487async fn populate_labels_for_symbols(
14488    symbols: Vec<CoreSymbol>,
14489    language_registry: &Arc<LanguageRegistry>,
14490    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14491    output: &mut Vec<Symbol>,
14492) {
14493    #[allow(clippy::mutable_key_type)]
14494    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14495
14496    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14497    for symbol in symbols {
14498        let Some(file_name) = symbol.path.file_name() else {
14499            continue;
14500        };
14501        let language = language_registry
14502            .load_language_for_file_path(Path::new(file_name))
14503            .await
14504            .ok()
14505            .or_else(|| {
14506                unknown_paths.insert(file_name.into());
14507                None
14508            });
14509        symbols_by_language
14510            .entry(language)
14511            .or_default()
14512            .push(symbol);
14513    }
14514
14515    for unknown_path in unknown_paths {
14516        log::info!("no language found for symbol in file {unknown_path:?}");
14517    }
14518
14519    let mut label_params = Vec::new();
14520    for (language, mut symbols) in symbols_by_language {
14521        label_params.clear();
14522        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14523            name: mem::take(&mut symbol.name),
14524            kind: symbol.kind,
14525            container_name: symbol.container_name.take(),
14526        }));
14527
14528        let mut labels = Vec::new();
14529        if let Some(language) = language {
14530            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14531                language_registry
14532                    .lsp_adapters(&language.name())
14533                    .first()
14534                    .cloned()
14535            });
14536            if let Some(lsp_adapter) = lsp_adapter {
14537                labels = lsp_adapter
14538                    .labels_for_symbols(&label_params, &language)
14539                    .await
14540                    .log_err()
14541                    .unwrap_or_default();
14542            }
14543        }
14544
14545        for (
14546            (
14547                symbol,
14548                language::Symbol {
14549                    name,
14550                    container_name,
14551                    ..
14552                },
14553            ),
14554            label,
14555        ) in symbols
14556            .into_iter()
14557            .zip(label_params.drain(..))
14558            .zip(labels.into_iter().chain(iter::repeat(None)))
14559        {
14560            output.push(Symbol {
14561                language_server_name: symbol.language_server_name,
14562                source_worktree_id: symbol.source_worktree_id,
14563                source_language_server_id: symbol.source_language_server_id,
14564                path: symbol.path,
14565                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14566                name,
14567                kind: symbol.kind,
14568                range: symbol.range,
14569                container_name,
14570            });
14571        }
14572    }
14573}
14574
14575pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14576    text.lines()
14577        .map(|line| line.trim())
14578        .filter(|line| !line.is_empty())
14579        .join(separator)
14580}
14581
14582fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14583    match server.capabilities().text_document_sync.as_ref()? {
14584        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14585            // Server wants didSave but didn't specify includeText.
14586            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14587            // Server doesn't want didSave at all.
14588            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14589            // Server provided SaveOptions.
14590            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14591                Some(save_options.include_text.unwrap_or(false))
14592            }
14593        },
14594        // We do not have any save info. Kind affects didChange only.
14595        lsp::TextDocumentSyncCapability::Kind(_) => None,
14596    }
14597}
14598
14599/// Completion items are displayed in a `UniformList`.
14600/// Usually, those items are single-line strings, but in LSP responses,
14601/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14602/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14603/// 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,
14604/// breaking the completions menu presentation.
14605///
14606/// 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.
14607pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14608    let mut new_text = String::with_capacity(label.text.len());
14609    let mut offset_map = vec![0; label.text.len() + 1];
14610    let mut last_char_was_space = false;
14611    let mut new_idx = 0;
14612    let chars = label.text.char_indices().fuse();
14613    let mut newlines_removed = false;
14614
14615    for (idx, c) in chars {
14616        offset_map[idx] = new_idx;
14617
14618        match c {
14619            '\n' if last_char_was_space => {
14620                newlines_removed = true;
14621            }
14622            '\t' | ' ' if last_char_was_space => {}
14623            '\n' if !last_char_was_space => {
14624                new_text.push(' ');
14625                new_idx += 1;
14626                last_char_was_space = true;
14627                newlines_removed = true;
14628            }
14629            ' ' | '\t' => {
14630                new_text.push(' ');
14631                new_idx += 1;
14632                last_char_was_space = true;
14633            }
14634            _ => {
14635                new_text.push(c);
14636                new_idx += c.len_utf8();
14637                last_char_was_space = false;
14638            }
14639        }
14640    }
14641    offset_map[label.text.len()] = new_idx;
14642
14643    // Only modify the label if newlines were removed.
14644    if !newlines_removed {
14645        return;
14646    }
14647
14648    let last_index = new_idx;
14649    let mut run_ranges_errors = Vec::new();
14650    label.runs.retain_mut(|(range, _)| {
14651        match offset_map.get(range.start) {
14652            Some(&start) => range.start = start,
14653            None => {
14654                run_ranges_errors.push(range.clone());
14655                return false;
14656            }
14657        }
14658
14659        match offset_map.get(range.end) {
14660            Some(&end) => range.end = end,
14661            None => {
14662                run_ranges_errors.push(range.clone());
14663                range.end = last_index;
14664            }
14665        }
14666        true
14667    });
14668    if !run_ranges_errors.is_empty() {
14669        log::error!(
14670            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14671            label.text
14672        );
14673    }
14674
14675    let mut wrong_filter_range = None;
14676    if label.filter_range == (0..label.text.len()) {
14677        label.filter_range = 0..new_text.len();
14678    } else {
14679        let mut original_filter_range = Some(label.filter_range.clone());
14680        match offset_map.get(label.filter_range.start) {
14681            Some(&start) => label.filter_range.start = start,
14682            None => {
14683                wrong_filter_range = original_filter_range.take();
14684                label.filter_range.start = last_index;
14685            }
14686        }
14687
14688        match offset_map.get(label.filter_range.end) {
14689            Some(&end) => label.filter_range.end = end,
14690            None => {
14691                wrong_filter_range = original_filter_range.take();
14692                label.filter_range.end = last_index;
14693            }
14694        }
14695    }
14696    if let Some(wrong_filter_range) = wrong_filter_range {
14697        log::error!(
14698            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14699            label.text
14700        );
14701    }
14702
14703    label.text = new_text;
14704}
14705
14706/// Apply edits to the buffer that will become part of the formatting transaction.
14707/// Fails if the buffer has been edited since the start of that transaction.
14708fn extend_formatting_transaction(
14709    buffer: &FormattableBuffer,
14710    formatting_transaction_id: text::TransactionId,
14711    cx: &mut AsyncApp,
14712    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14713) -> anyhow::Result<()> {
14714    buffer.handle.update(cx, |buffer, cx| {
14715        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14716        if last_transaction_id != Some(formatting_transaction_id) {
14717            anyhow::bail!("Buffer edited while formatting. Aborting")
14718        }
14719        buffer.start_transaction();
14720        operation(buffer, cx);
14721        if let Some(transaction_id) = buffer.end_transaction(cx) {
14722            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14723        }
14724        Ok(())
14725    })
14726}