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;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticServerCapabilities,
   79    DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit,
   80    FileOperationFilter, FileOperationPatternKind, FileOperationRegistrationOptions, FileRename,
   81    FileSystemWatcher, LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary,
   82    LanguageServerBinaryOptions, LanguageServerId, LanguageServerName, LanguageServerSelector,
   83    LspRequestFuture, MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   84    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   85    WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141
  142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  143pub enum FormatTrigger {
  144    Save,
  145    Manual,
  146}
  147
  148pub enum LspFormatTarget {
  149    Buffers,
  150    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  151}
  152
  153pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  154
  155impl FormatTrigger {
  156    fn from_proto(value: i32) -> FormatTrigger {
  157        match value {
  158            0 => FormatTrigger::Save,
  159            1 => FormatTrigger::Manual,
  160            _ => FormatTrigger::Save,
  161        }
  162    }
  163}
  164
  165#[derive(Clone)]
  166struct UnifiedLanguageServer {
  167    id: LanguageServerId,
  168    project_roots: HashSet<Arc<RelPath>>,
  169}
  170
  171#[derive(Clone, Hash, PartialEq, Eq)]
  172struct LanguageServerSeed {
  173    worktree_id: WorktreeId,
  174    name: LanguageServerName,
  175    toolchain: Option<Toolchain>,
  176    settings: Arc<LspSettings>,
  177}
  178
  179#[derive(Debug)]
  180pub struct DocumentDiagnosticsUpdate<'a, D> {
  181    pub diagnostics: D,
  182    pub result_id: Option<String>,
  183    pub server_id: LanguageServerId,
  184    pub disk_based_sources: Cow<'a, [String]>,
  185}
  186
  187pub struct DocumentDiagnostics {
  188    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  189    document_abs_path: PathBuf,
  190    version: Option<i32>,
  191}
  192
  193#[derive(Default)]
  194struct DynamicRegistrations {
  195    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  196    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  197}
  198
  199pub struct LocalLspStore {
  200    weak: WeakEntity<LspStore>,
  201    worktree_store: Entity<WorktreeStore>,
  202    toolchain_store: Entity<LocalToolchainStore>,
  203    http_client: Arc<dyn HttpClient>,
  204    environment: Entity<ProjectEnvironment>,
  205    fs: Arc<dyn Fs>,
  206    languages: Arc<LanguageRegistry>,
  207    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  208    yarn: Entity<YarnPathStore>,
  209    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  210    buffers_being_formatted: HashSet<BufferId>,
  211    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  212    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  213    watched_manifest_filenames: HashSet<ManifestName>,
  214    language_server_paths_watched_for_rename:
  215        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  216    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  217    supplementary_language_servers:
  218        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  219    prettier_store: Entity<PrettierStore>,
  220    next_diagnostic_group_id: usize,
  221    diagnostics: HashMap<
  222        WorktreeId,
  223        HashMap<
  224            Arc<RelPath>,
  225            Vec<(
  226                LanguageServerId,
  227                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  228            )>,
  229        >,
  230    >,
  231    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  232    _subscription: gpui::Subscription,
  233    lsp_tree: LanguageServerTree,
  234    registered_buffers: HashMap<BufferId, usize>,
  235    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  236    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  237}
  238
  239impl LocalLspStore {
  240    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  241    pub fn running_language_server_for_id(
  242        &self,
  243        id: LanguageServerId,
  244    ) -> Option<&Arc<LanguageServer>> {
  245        let language_server_state = self.language_servers.get(&id)?;
  246
  247        match language_server_state {
  248            LanguageServerState::Running { server, .. } => Some(server),
  249            LanguageServerState::Starting { .. } => None,
  250        }
  251    }
  252
  253    fn get_or_insert_language_server(
  254        &mut self,
  255        worktree_handle: &Entity<Worktree>,
  256        delegate: Arc<LocalLspAdapterDelegate>,
  257        disposition: &Arc<LaunchDisposition>,
  258        language_name: &LanguageName,
  259        cx: &mut App,
  260    ) -> LanguageServerId {
  261        let key = LanguageServerSeed {
  262            worktree_id: worktree_handle.read(cx).id(),
  263            name: disposition.server_name.clone(),
  264            settings: disposition.settings.clone(),
  265            toolchain: disposition.toolchain.clone(),
  266        };
  267        if let Some(state) = self.language_server_ids.get_mut(&key) {
  268            state.project_roots.insert(disposition.path.path.clone());
  269            state.id
  270        } else {
  271            let adapter = self
  272                .languages
  273                .lsp_adapters(language_name)
  274                .into_iter()
  275                .find(|adapter| adapter.name() == disposition.server_name)
  276                .expect("To find LSP adapter");
  277            let new_language_server_id = self.start_language_server(
  278                worktree_handle,
  279                delegate,
  280                adapter,
  281                disposition.settings.clone(),
  282                key.clone(),
  283                cx,
  284            );
  285            if let Some(state) = self.language_server_ids.get_mut(&key) {
  286                state.project_roots.insert(disposition.path.path.clone());
  287            } else {
  288                debug_assert!(
  289                    false,
  290                    "Expected `start_language_server` to ensure that `key` exists in a map"
  291                );
  292            }
  293            new_language_server_id
  294        }
  295    }
  296
  297    fn start_language_server(
  298        &mut self,
  299        worktree_handle: &Entity<Worktree>,
  300        delegate: Arc<LocalLspAdapterDelegate>,
  301        adapter: Arc<CachedLspAdapter>,
  302        settings: Arc<LspSettings>,
  303        key: LanguageServerSeed,
  304        cx: &mut App,
  305    ) -> LanguageServerId {
  306        let worktree = worktree_handle.read(cx);
  307
  308        let root_path = worktree.abs_path();
  309        let toolchain = key.toolchain.clone();
  310        let override_options = settings.initialization_options.clone();
  311
  312        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  313
  314        let server_id = self.languages.next_language_server_id();
  315        log::trace!(
  316            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  317            adapter.name.0
  318        );
  319
  320        let binary = self.get_language_server_binary(
  321            adapter.clone(),
  322            settings,
  323            toolchain.clone(),
  324            delegate.clone(),
  325            true,
  326            cx,
  327        );
  328        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  329
  330        let pending_server = cx.spawn({
  331            let adapter = adapter.clone();
  332            let server_name = adapter.name.clone();
  333            let stderr_capture = stderr_capture.clone();
  334            #[cfg(any(test, feature = "test-support"))]
  335            let lsp_store = self.weak.clone();
  336            let pending_workspace_folders = pending_workspace_folders.clone();
  337            async move |cx| {
  338                let binary = binary.await?;
  339                #[cfg(any(test, feature = "test-support"))]
  340                if let Some(server) = lsp_store
  341                    .update(&mut cx.clone(), |this, cx| {
  342                        this.languages.create_fake_language_server(
  343                            server_id,
  344                            &server_name,
  345                            binary.clone(),
  346                            &mut cx.to_async(),
  347                        )
  348                    })
  349                    .ok()
  350                    .flatten()
  351                {
  352                    return Ok(server);
  353                }
  354
  355                let code_action_kinds = adapter.code_action_kinds();
  356                lsp::LanguageServer::new(
  357                    stderr_capture,
  358                    server_id,
  359                    server_name,
  360                    binary,
  361                    &root_path,
  362                    code_action_kinds,
  363                    Some(pending_workspace_folders),
  364                    cx,
  365                )
  366            }
  367        });
  368
  369        let startup = {
  370            let server_name = adapter.name.0.clone();
  371            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  372            let key = key.clone();
  373            let adapter = adapter.clone();
  374            let lsp_store = self.weak.clone();
  375            let pending_workspace_folders = pending_workspace_folders.clone();
  376
  377            let pull_diagnostics = ProjectSettings::get_global(cx)
  378                .diagnostics
  379                .lsp_pull_diagnostics
  380                .enabled;
  381            cx.spawn(async move |cx| {
  382                let result = async {
  383                    let language_server = pending_server.await?;
  384
  385                    let workspace_config = Self::workspace_configuration_for_adapter(
  386                        adapter.adapter.clone(),
  387                        &delegate,
  388                        toolchain,
  389                        cx,
  390                    )
  391                    .await?;
  392
  393                    let mut initialization_options = Self::initialization_options_for_adapter(
  394                        adapter.adapter.clone(),
  395                        &delegate,
  396                    )
  397                    .await?;
  398
  399                    match (&mut initialization_options, override_options) {
  400                        (Some(initialization_options), Some(override_options)) => {
  401                            merge_json_value_into(override_options, initialization_options);
  402                        }
  403                        (None, override_options) => initialization_options = override_options,
  404                        _ => {}
  405                    }
  406
  407                    let initialization_params = cx.update(|cx| {
  408                        let mut params =
  409                            language_server.default_initialize_params(pull_diagnostics, cx);
  410                        params.initialization_options = initialization_options;
  411                        adapter.adapter.prepare_initialize_params(params, cx)
  412                    })??;
  413
  414                    Self::setup_lsp_messages(
  415                        lsp_store.clone(),
  416                        &language_server,
  417                        delegate.clone(),
  418                        adapter.clone(),
  419                    );
  420
  421                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  422                        settings: workspace_config,
  423                    };
  424                    let language_server = cx
  425                        .update(|cx| {
  426                            language_server.initialize(
  427                                initialization_params,
  428                                Arc::new(did_change_configuration_params.clone()),
  429                                cx,
  430                            )
  431                        })?
  432                        .await
  433                        .inspect_err(|_| {
  434                            if let Some(lsp_store) = lsp_store.upgrade() {
  435                                lsp_store
  436                                    .update(cx, |lsp_store, cx| {
  437                                        lsp_store.cleanup_lsp_data(server_id);
  438                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  439                                    })
  440                                    .ok();
  441                            }
  442                        })?;
  443
  444                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  445                        did_change_configuration_params,
  446                    )?;
  447
  448                    anyhow::Ok(language_server)
  449                }
  450                .await;
  451
  452                match result {
  453                    Ok(server) => {
  454                        lsp_store
  455                            .update(cx, |lsp_store, cx| {
  456                                lsp_store.insert_newly_running_language_server(
  457                                    adapter,
  458                                    server.clone(),
  459                                    server_id,
  460                                    key,
  461                                    pending_workspace_folders,
  462                                    cx,
  463                                );
  464                            })
  465                            .ok();
  466                        stderr_capture.lock().take();
  467                        Some(server)
  468                    }
  469
  470                    Err(err) => {
  471                        let log = stderr_capture.lock().take().unwrap_or_default();
  472                        delegate.update_status(
  473                            adapter.name(),
  474                            BinaryStatus::Failed {
  475                                error: if log.is_empty() {
  476                                    format!("{err:#}")
  477                                } else {
  478                                    format!("{err:#}\n-- stderr --\n{log}")
  479                                },
  480                            },
  481                        );
  482                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  483                        if !log.is_empty() {
  484                            log::error!("server stderr: {log}");
  485                        }
  486                        None
  487                    }
  488                }
  489            })
  490        };
  491        let state = LanguageServerState::Starting {
  492            startup,
  493            pending_workspace_folders,
  494        };
  495
  496        self.languages
  497            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  498
  499        self.language_servers.insert(server_id, state);
  500        self.language_server_ids
  501            .entry(key)
  502            .or_insert(UnifiedLanguageServer {
  503                id: server_id,
  504                project_roots: Default::default(),
  505            });
  506        server_id
  507    }
  508
  509    fn get_language_server_binary(
  510        &self,
  511        adapter: Arc<CachedLspAdapter>,
  512        settings: Arc<LspSettings>,
  513        toolchain: Option<Toolchain>,
  514        delegate: Arc<dyn LspAdapterDelegate>,
  515        allow_binary_download: bool,
  516        cx: &mut App,
  517    ) -> Task<Result<LanguageServerBinary>> {
  518        if let Some(settings) = settings.binary.as_ref()
  519            && settings.path.is_some()
  520        {
  521            let settings = settings.clone();
  522
  523            return cx.background_spawn(async move {
  524                let mut env = delegate.shell_env().await;
  525                env.extend(settings.env.unwrap_or_default());
  526
  527                Ok(LanguageServerBinary {
  528                    path: PathBuf::from(&settings.path.unwrap()),
  529                    env: Some(env),
  530                    arguments: settings
  531                        .arguments
  532                        .unwrap_or_default()
  533                        .iter()
  534                        .map(Into::into)
  535                        .collect(),
  536                })
  537            });
  538        }
  539        let lsp_binary_options = LanguageServerBinaryOptions {
  540            allow_path_lookup: !settings
  541                .binary
  542                .as_ref()
  543                .and_then(|b| b.ignore_system_version)
  544                .unwrap_or_default(),
  545            allow_binary_download,
  546            pre_release: settings
  547                .fetch
  548                .as_ref()
  549                .and_then(|f| f.pre_release)
  550                .unwrap_or(false),
  551        };
  552
  553        cx.spawn(async move |cx| {
  554            let binary_result = adapter
  555                .clone()
  556                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  557                .await;
  558
  559            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  560
  561            let mut binary = binary_result?;
  562            let mut shell_env = delegate.shell_env().await;
  563
  564            shell_env.extend(binary.env.unwrap_or_default());
  565
  566            if let Some(settings) = settings.binary.as_ref() {
  567                if let Some(arguments) = &settings.arguments {
  568                    binary.arguments = arguments.iter().map(Into::into).collect();
  569                }
  570                if let Some(env) = &settings.env {
  571                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  572                }
  573            }
  574
  575            binary.env = Some(shell_env);
  576            Ok(binary)
  577        })
  578    }
  579
  580    fn setup_lsp_messages(
  581        lsp_store: WeakEntity<LspStore>,
  582        language_server: &LanguageServer,
  583        delegate: Arc<dyn LspAdapterDelegate>,
  584        adapter: Arc<CachedLspAdapter>,
  585    ) {
  586        let name = language_server.name();
  587        let server_id = language_server.server_id();
  588        language_server
  589            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  590                let adapter = adapter.clone();
  591                let this = lsp_store.clone();
  592                move |mut params, cx| {
  593                    let adapter = adapter.clone();
  594                    if let Some(this) = this.upgrade() {
  595                        this.update(cx, |this, cx| {
  596                            {
  597                                let buffer = params
  598                                    .uri
  599                                    .to_file_path()
  600                                    .map(|file_path| this.get_buffer(&file_path, cx))
  601                                    .ok()
  602                                    .flatten();
  603                                adapter.process_diagnostics(&mut params, server_id, buffer);
  604                            }
  605
  606                            this.merge_lsp_diagnostics(
  607                                DiagnosticSourceKind::Pushed,
  608                                vec![DocumentDiagnosticsUpdate {
  609                                    server_id,
  610                                    diagnostics: params,
  611                                    result_id: None,
  612                                    disk_based_sources: Cow::Borrowed(
  613                                        &adapter.disk_based_diagnostic_sources,
  614                                    ),
  615                                }],
  616                                |_, diagnostic, cx| match diagnostic.source_kind {
  617                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  618                                        adapter.retain_old_diagnostic(diagnostic, cx)
  619                                    }
  620                                    DiagnosticSourceKind::Pulled => true,
  621                                },
  622                                cx,
  623                            )
  624                            .log_err();
  625                        })
  626                        .ok();
  627                    }
  628                }
  629            })
  630            .detach();
  631        language_server
  632            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  633                let adapter = adapter.adapter.clone();
  634                let delegate = delegate.clone();
  635                let this = lsp_store.clone();
  636                move |params, cx| {
  637                    let adapter = adapter.clone();
  638                    let delegate = delegate.clone();
  639                    let this = this.clone();
  640                    let mut cx = cx.clone();
  641                    async move {
  642                        let toolchain_for_id = this
  643                            .update(&mut cx, |this, _| {
  644                                this.as_local()?.language_server_ids.iter().find_map(
  645                                    |(seed, value)| {
  646                                        (value.id == server_id).then(|| seed.toolchain.clone())
  647                                    },
  648                                )
  649                            })?
  650                            .context("Expected the LSP store to be in a local mode")?;
  651                        let workspace_config = Self::workspace_configuration_for_adapter(
  652                            adapter.clone(),
  653                            &delegate,
  654                            toolchain_for_id,
  655                            &mut cx,
  656                        )
  657                        .await?;
  658
  659                        Ok(params
  660                            .items
  661                            .into_iter()
  662                            .map(|item| {
  663                                if let Some(section) = &item.section {
  664                                    workspace_config
  665                                        .get(section)
  666                                        .cloned()
  667                                        .unwrap_or(serde_json::Value::Null)
  668                                } else {
  669                                    workspace_config.clone()
  670                                }
  671                            })
  672                            .collect())
  673                    }
  674                }
  675            })
  676            .detach();
  677
  678        language_server
  679            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  680                let this = lsp_store.clone();
  681                move |_, cx| {
  682                    let this = this.clone();
  683                    let cx = cx.clone();
  684                    async move {
  685                        let Some(server) =
  686                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  687                        else {
  688                            return Ok(None);
  689                        };
  690                        let root = server.workspace_folders();
  691                        Ok(Some(
  692                            root.into_iter()
  693                                .map(|uri| WorkspaceFolder {
  694                                    uri,
  695                                    name: Default::default(),
  696                                })
  697                                .collect(),
  698                        ))
  699                    }
  700                }
  701            })
  702            .detach();
  703        // Even though we don't have handling for these requests, respond to them to
  704        // avoid stalling any language server like `gopls` which waits for a response
  705        // to these requests when initializing.
  706        language_server
  707            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  708                let this = lsp_store.clone();
  709                move |params, cx| {
  710                    let this = this.clone();
  711                    let mut cx = cx.clone();
  712                    async move {
  713                        this.update(&mut cx, |this, _| {
  714                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  715                                && let lsp::NumberOrString::String(token) = params.token
  716                            {
  717                                status.progress_tokens.insert(token);
  718                            }
  719                        })?;
  720
  721                        Ok(())
  722                    }
  723                }
  724            })
  725            .detach();
  726
  727        language_server
  728            .on_request::<lsp::request::RegisterCapability, _, _>({
  729                let lsp_store = lsp_store.clone();
  730                move |params, cx| {
  731                    let lsp_store = lsp_store.clone();
  732                    let mut cx = cx.clone();
  733                    async move {
  734                        lsp_store
  735                            .update(&mut cx, |lsp_store, cx| {
  736                                if lsp_store.as_local().is_some() {
  737                                    match lsp_store
  738                                        .register_server_capabilities(server_id, params, cx)
  739                                    {
  740                                        Ok(()) => {}
  741                                        Err(e) => {
  742                                            log::error!(
  743                                                "Failed to register server capabilities: {e:#}"
  744                                            );
  745                                        }
  746                                    };
  747                                }
  748                            })
  749                            .ok();
  750                        Ok(())
  751                    }
  752                }
  753            })
  754            .detach();
  755
  756        language_server
  757            .on_request::<lsp::request::UnregisterCapability, _, _>({
  758                let lsp_store = lsp_store.clone();
  759                move |params, cx| {
  760                    let lsp_store = lsp_store.clone();
  761                    let mut cx = cx.clone();
  762                    async move {
  763                        lsp_store
  764                            .update(&mut cx, |lsp_store, cx| {
  765                                if lsp_store.as_local().is_some() {
  766                                    match lsp_store
  767                                        .unregister_server_capabilities(server_id, params, cx)
  768                                    {
  769                                        Ok(()) => {}
  770                                        Err(e) => {
  771                                            log::error!(
  772                                                "Failed to unregister server capabilities: {e:#}"
  773                                            );
  774                                        }
  775                                    }
  776                                }
  777                            })
  778                            .ok();
  779                        Ok(())
  780                    }
  781                }
  782            })
  783            .detach();
  784
  785        language_server
  786            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  787                let this = lsp_store.clone();
  788                move |params, cx| {
  789                    let mut cx = cx.clone();
  790                    let this = this.clone();
  791                    async move {
  792                        LocalLspStore::on_lsp_workspace_edit(
  793                            this.clone(),
  794                            params,
  795                            server_id,
  796                            &mut cx,
  797                        )
  798                        .await
  799                    }
  800                }
  801            })
  802            .detach();
  803
  804        language_server
  805            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  806                let lsp_store = lsp_store.clone();
  807                move |(), cx| {
  808                    let this = lsp_store.clone();
  809                    let mut cx = cx.clone();
  810                    async move {
  811                        this.update(&mut cx, |lsp_store, cx| {
  812                            cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
  813                            lsp_store
  814                                .downstream_client
  815                                .as_ref()
  816                                .map(|(client, project_id)| {
  817                                    client.send(proto::RefreshInlayHints {
  818                                        project_id: *project_id,
  819                                        server_id: server_id.to_proto(),
  820                                    })
  821                                })
  822                        })?
  823                        .transpose()?;
  824                        Ok(())
  825                    }
  826                }
  827            })
  828            .detach();
  829
  830        language_server
  831            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  832                let this = lsp_store.clone();
  833                move |(), cx| {
  834                    let this = this.clone();
  835                    let mut cx = cx.clone();
  836                    async move {
  837                        this.update(&mut cx, |this, cx| {
  838                            cx.emit(LspStoreEvent::RefreshCodeLens);
  839                            this.downstream_client.as_ref().map(|(client, project_id)| {
  840                                client.send(proto::RefreshCodeLens {
  841                                    project_id: *project_id,
  842                                })
  843                            })
  844                        })?
  845                        .transpose()?;
  846                        Ok(())
  847                    }
  848                }
  849            })
  850            .detach();
  851
  852        language_server
  853            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  854                let this = lsp_store.clone();
  855                move |(), cx| {
  856                    let this = this.clone();
  857                    let mut cx = cx.clone();
  858                    async move {
  859                        this.update(&mut cx, |lsp_store, _| {
  860                            lsp_store.pull_workspace_diagnostics(server_id);
  861                            lsp_store
  862                                .downstream_client
  863                                .as_ref()
  864                                .map(|(client, project_id)| {
  865                                    client.send(proto::PullWorkspaceDiagnostics {
  866                                        project_id: *project_id,
  867                                        server_id: server_id.to_proto(),
  868                                    })
  869                                })
  870                        })?
  871                        .transpose()?;
  872                        Ok(())
  873                    }
  874                }
  875            })
  876            .detach();
  877
  878        language_server
  879            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  880                let this = lsp_store.clone();
  881                let name = name.to_string();
  882                move |params, cx| {
  883                    let this = this.clone();
  884                    let name = name.to_string();
  885                    let mut cx = cx.clone();
  886                    async move {
  887                        let actions = params.actions.unwrap_or_default();
  888                        let (tx, rx) = smol::channel::bounded(1);
  889                        let request = LanguageServerPromptRequest {
  890                            level: match params.typ {
  891                                lsp::MessageType::ERROR => PromptLevel::Critical,
  892                                lsp::MessageType::WARNING => PromptLevel::Warning,
  893                                _ => PromptLevel::Info,
  894                            },
  895                            message: params.message,
  896                            actions,
  897                            response_channel: tx,
  898                            lsp_name: name.clone(),
  899                        };
  900
  901                        let did_update = this
  902                            .update(&mut cx, |_, cx| {
  903                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  904                            })
  905                            .is_ok();
  906                        if did_update {
  907                            let response = rx.recv().await.ok();
  908                            Ok(response)
  909                        } else {
  910                            Ok(None)
  911                        }
  912                    }
  913                }
  914            })
  915            .detach();
  916        language_server
  917            .on_notification::<lsp::notification::ShowMessage, _>({
  918                let this = lsp_store.clone();
  919                let name = name.to_string();
  920                move |params, cx| {
  921                    let this = this.clone();
  922                    let name = name.to_string();
  923                    let mut cx = cx.clone();
  924
  925                    let (tx, _) = smol::channel::bounded(1);
  926                    let request = LanguageServerPromptRequest {
  927                        level: match params.typ {
  928                            lsp::MessageType::ERROR => PromptLevel::Critical,
  929                            lsp::MessageType::WARNING => PromptLevel::Warning,
  930                            _ => PromptLevel::Info,
  931                        },
  932                        message: params.message,
  933                        actions: vec![],
  934                        response_channel: tx,
  935                        lsp_name: name,
  936                    };
  937
  938                    let _ = this.update(&mut cx, |_, cx| {
  939                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  940                    });
  941                }
  942            })
  943            .detach();
  944
  945        let disk_based_diagnostics_progress_token =
  946            adapter.disk_based_diagnostics_progress_token.clone();
  947
  948        language_server
  949            .on_notification::<lsp::notification::Progress, _>({
  950                let this = lsp_store.clone();
  951                move |params, cx| {
  952                    if let Some(this) = this.upgrade() {
  953                        this.update(cx, |this, cx| {
  954                            this.on_lsp_progress(
  955                                params,
  956                                server_id,
  957                                disk_based_diagnostics_progress_token.clone(),
  958                                cx,
  959                            );
  960                        })
  961                        .ok();
  962                    }
  963                }
  964            })
  965            .detach();
  966
  967        language_server
  968            .on_notification::<lsp::notification::LogMessage, _>({
  969                let this = lsp_store.clone();
  970                move |params, cx| {
  971                    if let Some(this) = this.upgrade() {
  972                        this.update(cx, |_, cx| {
  973                            cx.emit(LspStoreEvent::LanguageServerLog(
  974                                server_id,
  975                                LanguageServerLogType::Log(params.typ),
  976                                params.message,
  977                            ));
  978                        })
  979                        .ok();
  980                    }
  981                }
  982            })
  983            .detach();
  984
  985        language_server
  986            .on_notification::<lsp::notification::LogTrace, _>({
  987                let this = lsp_store.clone();
  988                move |params, cx| {
  989                    let mut cx = cx.clone();
  990                    if let Some(this) = this.upgrade() {
  991                        this.update(&mut cx, |_, cx| {
  992                            cx.emit(LspStoreEvent::LanguageServerLog(
  993                                server_id,
  994                                LanguageServerLogType::Trace {
  995                                    verbose_info: params.verbose,
  996                                },
  997                                params.message,
  998                            ));
  999                        })
 1000                        .ok();
 1001                    }
 1002                }
 1003            })
 1004            .detach();
 1005
 1006        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1007        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1008        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1009        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1010    }
 1011
 1012    fn shutdown_language_servers_on_quit(
 1013        &mut self,
 1014        _: &mut Context<LspStore>,
 1015    ) -> impl Future<Output = ()> + use<> {
 1016        let shutdown_futures = self
 1017            .language_servers
 1018            .drain()
 1019            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1020            .collect::<Vec<_>>();
 1021
 1022        async move {
 1023            join_all(shutdown_futures).await;
 1024        }
 1025    }
 1026
 1027    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1028        match server_state {
 1029            LanguageServerState::Running { server, .. } => {
 1030                if let Some(shutdown) = server.shutdown() {
 1031                    shutdown.await;
 1032                }
 1033            }
 1034            LanguageServerState::Starting { startup, .. } => {
 1035                if let Some(server) = startup.await
 1036                    && let Some(shutdown) = server.shutdown()
 1037                {
 1038                    shutdown.await;
 1039                }
 1040            }
 1041        }
 1042        Ok(())
 1043    }
 1044
 1045    fn language_servers_for_worktree(
 1046        &self,
 1047        worktree_id: WorktreeId,
 1048    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1049        self.language_server_ids
 1050            .iter()
 1051            .filter_map(move |(seed, state)| {
 1052                if seed.worktree_id != worktree_id {
 1053                    return None;
 1054                }
 1055
 1056                if let Some(LanguageServerState::Running { server, .. }) =
 1057                    self.language_servers.get(&state.id)
 1058                {
 1059                    Some(server)
 1060                } else {
 1061                    None
 1062                }
 1063            })
 1064    }
 1065
 1066    fn language_server_ids_for_project_path(
 1067        &self,
 1068        project_path: ProjectPath,
 1069        language: &Language,
 1070        cx: &mut App,
 1071    ) -> Vec<LanguageServerId> {
 1072        let Some(worktree) = self
 1073            .worktree_store
 1074            .read(cx)
 1075            .worktree_for_id(project_path.worktree_id, cx)
 1076        else {
 1077            return Vec::new();
 1078        };
 1079        let delegate: Arc<dyn ManifestDelegate> =
 1080            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1081
 1082        self.lsp_tree
 1083            .get(
 1084                project_path,
 1085                language.name(),
 1086                language.manifest(),
 1087                &delegate,
 1088                cx,
 1089            )
 1090            .collect::<Vec<_>>()
 1091    }
 1092
 1093    fn language_server_ids_for_buffer(
 1094        &self,
 1095        buffer: &Buffer,
 1096        cx: &mut App,
 1097    ) -> Vec<LanguageServerId> {
 1098        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1099            let worktree_id = file.worktree_id(cx);
 1100
 1101            let path: Arc<RelPath> = file
 1102                .path()
 1103                .parent()
 1104                .map(Arc::from)
 1105                .unwrap_or_else(|| file.path().clone());
 1106            let worktree_path = ProjectPath { worktree_id, path };
 1107            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1108        } else {
 1109            Vec::new()
 1110        }
 1111    }
 1112
 1113    fn language_servers_for_buffer<'a>(
 1114        &'a self,
 1115        buffer: &'a Buffer,
 1116        cx: &'a mut App,
 1117    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1118        self.language_server_ids_for_buffer(buffer, cx)
 1119            .into_iter()
 1120            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1121                LanguageServerState::Running {
 1122                    adapter, server, ..
 1123                } => Some((adapter, server)),
 1124                _ => None,
 1125            })
 1126    }
 1127
 1128    async fn execute_code_action_kind_locally(
 1129        lsp_store: WeakEntity<LspStore>,
 1130        mut buffers: Vec<Entity<Buffer>>,
 1131        kind: CodeActionKind,
 1132        push_to_history: bool,
 1133        cx: &mut AsyncApp,
 1134    ) -> anyhow::Result<ProjectTransaction> {
 1135        // Do not allow multiple concurrent code actions requests for the
 1136        // same buffer.
 1137        lsp_store.update(cx, |this, cx| {
 1138            let this = this.as_local_mut().unwrap();
 1139            buffers.retain(|buffer| {
 1140                this.buffers_being_formatted
 1141                    .insert(buffer.read(cx).remote_id())
 1142            });
 1143        })?;
 1144        let _cleanup = defer({
 1145            let this = lsp_store.clone();
 1146            let mut cx = cx.clone();
 1147            let buffers = &buffers;
 1148            move || {
 1149                this.update(&mut cx, |this, cx| {
 1150                    let this = this.as_local_mut().unwrap();
 1151                    for buffer in buffers {
 1152                        this.buffers_being_formatted
 1153                            .remove(&buffer.read(cx).remote_id());
 1154                    }
 1155                })
 1156                .ok();
 1157            }
 1158        });
 1159        let mut project_transaction = ProjectTransaction::default();
 1160
 1161        for buffer in &buffers {
 1162            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1163                buffer.update(cx, |buffer, cx| {
 1164                    lsp_store
 1165                        .as_local()
 1166                        .unwrap()
 1167                        .language_servers_for_buffer(buffer, cx)
 1168                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1169                        .collect::<Vec<_>>()
 1170                })
 1171            })?;
 1172            for (_, language_server) in adapters_and_servers.iter() {
 1173                let actions = Self::get_server_code_actions_from_action_kinds(
 1174                    &lsp_store,
 1175                    language_server.server_id(),
 1176                    vec![kind.clone()],
 1177                    buffer,
 1178                    cx,
 1179                )
 1180                .await?;
 1181                Self::execute_code_actions_on_server(
 1182                    &lsp_store,
 1183                    language_server,
 1184                    actions,
 1185                    push_to_history,
 1186                    &mut project_transaction,
 1187                    cx,
 1188                )
 1189                .await?;
 1190            }
 1191        }
 1192        Ok(project_transaction)
 1193    }
 1194
 1195    async fn format_locally(
 1196        lsp_store: WeakEntity<LspStore>,
 1197        mut buffers: Vec<FormattableBuffer>,
 1198        push_to_history: bool,
 1199        trigger: FormatTrigger,
 1200        logger: zlog::Logger,
 1201        cx: &mut AsyncApp,
 1202    ) -> anyhow::Result<ProjectTransaction> {
 1203        // Do not allow multiple concurrent formatting requests for the
 1204        // same buffer.
 1205        lsp_store.update(cx, |this, cx| {
 1206            let this = this.as_local_mut().unwrap();
 1207            buffers.retain(|buffer| {
 1208                this.buffers_being_formatted
 1209                    .insert(buffer.handle.read(cx).remote_id())
 1210            });
 1211        })?;
 1212
 1213        let _cleanup = defer({
 1214            let this = lsp_store.clone();
 1215            let mut cx = cx.clone();
 1216            let buffers = &buffers;
 1217            move || {
 1218                this.update(&mut cx, |this, cx| {
 1219                    let this = this.as_local_mut().unwrap();
 1220                    for buffer in buffers {
 1221                        this.buffers_being_formatted
 1222                            .remove(&buffer.handle.read(cx).remote_id());
 1223                    }
 1224                })
 1225                .ok();
 1226            }
 1227        });
 1228
 1229        let mut project_transaction = ProjectTransaction::default();
 1230
 1231        for buffer in &buffers {
 1232            zlog::debug!(
 1233                logger =>
 1234                "formatting buffer '{:?}'",
 1235                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1236            );
 1237            // Create an empty transaction to hold all of the formatting edits.
 1238            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1239                // ensure no transactions created while formatting are
 1240                // grouped with the previous transaction in the history
 1241                // based on the transaction group interval
 1242                buffer.finalize_last_transaction();
 1243                buffer
 1244                    .start_transaction()
 1245                    .context("transaction already open")?;
 1246                buffer.end_transaction(cx);
 1247                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1248                buffer.finalize_last_transaction();
 1249                anyhow::Ok(transaction_id)
 1250            })??;
 1251
 1252            let result = Self::format_buffer_locally(
 1253                lsp_store.clone(),
 1254                buffer,
 1255                formatting_transaction_id,
 1256                trigger,
 1257                logger,
 1258                cx,
 1259            )
 1260            .await;
 1261
 1262            buffer.handle.update(cx, |buffer, cx| {
 1263                let Some(formatting_transaction) =
 1264                    buffer.get_transaction(formatting_transaction_id).cloned()
 1265                else {
 1266                    zlog::warn!(logger => "no formatting transaction");
 1267                    return;
 1268                };
 1269                if formatting_transaction.edit_ids.is_empty() {
 1270                    zlog::debug!(logger => "no changes made while formatting");
 1271                    buffer.forget_transaction(formatting_transaction_id);
 1272                    return;
 1273                }
 1274                if !push_to_history {
 1275                    zlog::trace!(logger => "forgetting format transaction");
 1276                    buffer.forget_transaction(formatting_transaction.id);
 1277                }
 1278                project_transaction
 1279                    .0
 1280                    .insert(cx.entity(), formatting_transaction);
 1281            })?;
 1282
 1283            result?;
 1284        }
 1285
 1286        Ok(project_transaction)
 1287    }
 1288
 1289    async fn format_buffer_locally(
 1290        lsp_store: WeakEntity<LspStore>,
 1291        buffer: &FormattableBuffer,
 1292        formatting_transaction_id: clock::Lamport,
 1293        trigger: FormatTrigger,
 1294        logger: zlog::Logger,
 1295        cx: &mut AsyncApp,
 1296    ) -> Result<()> {
 1297        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1298            buffer.handle.update(cx, |buffer, cx| {
 1299                let adapters_and_servers = lsp_store
 1300                    .as_local()
 1301                    .unwrap()
 1302                    .language_servers_for_buffer(buffer, cx)
 1303                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1304                    .collect::<Vec<_>>();
 1305                let settings =
 1306                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1307                        .into_owned();
 1308                (adapters_and_servers, settings)
 1309            })
 1310        })?;
 1311
 1312        /// Apply edits to the buffer that will become part of the formatting transaction.
 1313        /// Fails if the buffer has been edited since the start of that transaction.
 1314        fn extend_formatting_transaction(
 1315            buffer: &FormattableBuffer,
 1316            formatting_transaction_id: text::TransactionId,
 1317            cx: &mut AsyncApp,
 1318            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1319        ) -> anyhow::Result<()> {
 1320            buffer.handle.update(cx, |buffer, cx| {
 1321                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1322                if last_transaction_id != Some(formatting_transaction_id) {
 1323                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1324                }
 1325                buffer.start_transaction();
 1326                operation(buffer, cx);
 1327                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1328                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1329                }
 1330                Ok(())
 1331            })?
 1332        }
 1333
 1334        // handle whitespace formatting
 1335        if settings.remove_trailing_whitespace_on_save {
 1336            zlog::trace!(logger => "removing trailing whitespace");
 1337            let diff = buffer
 1338                .handle
 1339                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1340                .await;
 1341            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1342                buffer.apply_diff(diff, cx);
 1343            })?;
 1344        }
 1345
 1346        if settings.ensure_final_newline_on_save {
 1347            zlog::trace!(logger => "ensuring final newline");
 1348            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1349                buffer.ensure_final_newline(cx);
 1350            })?;
 1351        }
 1352
 1353        // Formatter for `code_actions_on_format` that runs before
 1354        // the rest of the formatters
 1355        let mut code_actions_on_format_formatters = None;
 1356        let should_run_code_actions_on_format = !matches!(
 1357            (trigger, &settings.format_on_save),
 1358            (FormatTrigger::Save, &FormatOnSave::Off)
 1359        );
 1360        if should_run_code_actions_on_format {
 1361            let have_code_actions_to_run_on_format = settings
 1362                .code_actions_on_format
 1363                .values()
 1364                .any(|enabled| *enabled);
 1365            if have_code_actions_to_run_on_format {
 1366                zlog::trace!(logger => "going to run code actions on format");
 1367                code_actions_on_format_formatters = Some(
 1368                    settings
 1369                        .code_actions_on_format
 1370                        .iter()
 1371                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1372                        .cloned()
 1373                        .map(Formatter::CodeAction)
 1374                        .collect::<Vec<_>>(),
 1375                );
 1376            }
 1377        }
 1378
 1379        let formatters = match (trigger, &settings.format_on_save) {
 1380            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1381            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1382                settings.formatter.as_ref()
 1383            }
 1384        };
 1385
 1386        let formatters = code_actions_on_format_formatters
 1387            .iter()
 1388            .flatten()
 1389            .chain(formatters);
 1390
 1391        for formatter in formatters {
 1392            let formatter = if formatter == &Formatter::Auto {
 1393                if settings.prettier.allowed {
 1394                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1395                    &Formatter::Prettier
 1396                } else {
 1397                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1398                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1399                }
 1400            } else {
 1401                formatter
 1402            };
 1403            match formatter {
 1404                Formatter::Auto => unreachable!("Auto resolved above"),
 1405                Formatter::Prettier => {
 1406                    let logger = zlog::scoped!(logger => "prettier");
 1407                    zlog::trace!(logger => "formatting");
 1408                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1409
 1410                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1411                        lsp_store.prettier_store().unwrap().downgrade()
 1412                    })?;
 1413                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1414                        .await
 1415                        .transpose()?;
 1416                    let Some(diff) = diff else {
 1417                        zlog::trace!(logger => "No changes");
 1418                        continue;
 1419                    };
 1420
 1421                    extend_formatting_transaction(
 1422                        buffer,
 1423                        formatting_transaction_id,
 1424                        cx,
 1425                        |buffer, cx| {
 1426                            buffer.apply_diff(diff, cx);
 1427                        },
 1428                    )?;
 1429                }
 1430                Formatter::External { command, arguments } => {
 1431                    let logger = zlog::scoped!(logger => "command");
 1432                    zlog::trace!(logger => "formatting");
 1433                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1434
 1435                    let diff = Self::format_via_external_command(
 1436                        buffer,
 1437                        command.as_ref(),
 1438                        arguments.as_deref(),
 1439                        cx,
 1440                    )
 1441                    .await
 1442                    .with_context(|| {
 1443                        format!("Failed to format buffer via external command: {}", command)
 1444                    })?;
 1445                    let Some(diff) = diff else {
 1446                        zlog::trace!(logger => "No changes");
 1447                        continue;
 1448                    };
 1449
 1450                    extend_formatting_transaction(
 1451                        buffer,
 1452                        formatting_transaction_id,
 1453                        cx,
 1454                        |buffer, cx| {
 1455                            buffer.apply_diff(diff, cx);
 1456                        },
 1457                    )?;
 1458                }
 1459                Formatter::LanguageServer(specifier) => {
 1460                    let logger = zlog::scoped!(logger => "language-server");
 1461                    zlog::trace!(logger => "formatting");
 1462                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1463
 1464                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1465                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1466                        continue;
 1467                    };
 1468
 1469                    let language_server = match specifier {
 1470                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1471                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1472                                if adapter.name.0.as_ref() == name {
 1473                                    Some(server.clone())
 1474                                } else {
 1475                                    None
 1476                                }
 1477                            })
 1478                        }
 1479                        settings::LanguageServerFormatterSpecifier::Current => {
 1480                            adapters_and_servers.first().map(|e| e.1.clone())
 1481                        }
 1482                    };
 1483
 1484                    let Some(language_server) = language_server else {
 1485                        log::debug!(
 1486                            "No language server found to format buffer '{:?}'. Skipping",
 1487                            buffer_path_abs.as_path().to_string_lossy()
 1488                        );
 1489                        continue;
 1490                    };
 1491
 1492                    zlog::trace!(
 1493                        logger =>
 1494                        "Formatting buffer '{:?}' using language server '{:?}'",
 1495                        buffer_path_abs.as_path().to_string_lossy(),
 1496                        language_server.name()
 1497                    );
 1498
 1499                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1500                        zlog::trace!(logger => "formatting ranges");
 1501                        Self::format_ranges_via_lsp(
 1502                            &lsp_store,
 1503                            &buffer.handle,
 1504                            ranges,
 1505                            buffer_path_abs,
 1506                            &language_server,
 1507                            &settings,
 1508                            cx,
 1509                        )
 1510                        .await
 1511                        .context("Failed to format ranges via language server")?
 1512                    } else {
 1513                        zlog::trace!(logger => "formatting full");
 1514                        Self::format_via_lsp(
 1515                            &lsp_store,
 1516                            &buffer.handle,
 1517                            buffer_path_abs,
 1518                            &language_server,
 1519                            &settings,
 1520                            cx,
 1521                        )
 1522                        .await
 1523                        .context("failed to format via language server")?
 1524                    };
 1525
 1526                    if edits.is_empty() {
 1527                        zlog::trace!(logger => "No changes");
 1528                        continue;
 1529                    }
 1530                    extend_formatting_transaction(
 1531                        buffer,
 1532                        formatting_transaction_id,
 1533                        cx,
 1534                        |buffer, cx| {
 1535                            buffer.edit(edits, None, cx);
 1536                        },
 1537                    )?;
 1538                }
 1539                Formatter::CodeAction(code_action_name) => {
 1540                    let logger = zlog::scoped!(logger => "code-actions");
 1541                    zlog::trace!(logger => "formatting");
 1542                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1543
 1544                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1545                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1546                        continue;
 1547                    };
 1548
 1549                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1550                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1551
 1552                    let mut actions_and_servers = Vec::new();
 1553
 1554                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1555                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1556                            &lsp_store,
 1557                            language_server.server_id(),
 1558                            vec![code_action_kind.clone()],
 1559                            &buffer.handle,
 1560                            cx,
 1561                        )
 1562                        .await
 1563                        .with_context(|| {
 1564                            format!(
 1565                                "Failed to resolve code action {:?} with language server {}",
 1566                                code_action_kind,
 1567                                language_server.name()
 1568                            )
 1569                        });
 1570                        let Ok(actions) = actions_result else {
 1571                            // note: it may be better to set result to the error and break formatters here
 1572                            // but for now we try to execute the actions that we can resolve and skip the rest
 1573                            zlog::error!(
 1574                                logger =>
 1575                                "Failed to resolve code action {:?} with language server {}",
 1576                                code_action_kind,
 1577                                language_server.name()
 1578                            );
 1579                            continue;
 1580                        };
 1581                        for action in actions {
 1582                            actions_and_servers.push((action, index));
 1583                        }
 1584                    }
 1585
 1586                    if actions_and_servers.is_empty() {
 1587                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1588                        continue;
 1589                    }
 1590
 1591                    'actions: for (mut action, server_index) in actions_and_servers {
 1592                        let server = &adapters_and_servers[server_index].1;
 1593
 1594                        let describe_code_action = |action: &CodeAction| {
 1595                            format!(
 1596                                "code action '{}' with title \"{}\" on server {}",
 1597                                action
 1598                                    .lsp_action
 1599                                    .action_kind()
 1600                                    .unwrap_or("unknown".into())
 1601                                    .as_str(),
 1602                                action.lsp_action.title(),
 1603                                server.name(),
 1604                            )
 1605                        };
 1606
 1607                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1608
 1609                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1610                            zlog::error!(
 1611                                logger =>
 1612                                "Failed to resolve {}. Error: {}",
 1613                                describe_code_action(&action),
 1614                                err
 1615                            );
 1616                            continue;
 1617                        }
 1618
 1619                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1620                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1621                            // but filters out and logs warnings for code actions that require unreasonably
 1622                            // difficult handling on our part, such as:
 1623                            // - applying edits that call commands
 1624                            //   which can result in arbitrary workspace edits being sent from the server that
 1625                            //   have no way of being tied back to the command that initiated them (i.e. we
 1626                            //   can't know which edits are part of the format request, or if the server is done sending
 1627                            //   actions in response to the command)
 1628                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1629                            //   as we then would need to handle such changes correctly in the local history as well
 1630                            //   as the remote history through the ProjectTransaction
 1631                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1632                            // Supporting these actions is not impossible, but not supported as of yet.
 1633                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1634                                zlog::trace!(
 1635                                    logger =>
 1636                                    "No changes for code action. Skipping {}",
 1637                                    describe_code_action(&action),
 1638                                );
 1639                                continue;
 1640                            }
 1641
 1642                            let mut operations = Vec::new();
 1643                            if let Some(document_changes) = edit.document_changes {
 1644                                match document_changes {
 1645                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1646                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1647                                    ),
 1648                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1649                                }
 1650                            } else if let Some(changes) = edit.changes {
 1651                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1652                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1653                                        text_document:
 1654                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1655                                                uri,
 1656                                                version: None,
 1657                                            },
 1658                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1659                                    })
 1660                                }));
 1661                            }
 1662
 1663                            let mut edits = Vec::with_capacity(operations.len());
 1664
 1665                            if operations.is_empty() {
 1666                                zlog::trace!(
 1667                                    logger =>
 1668                                    "No changes for code action. Skipping {}",
 1669                                    describe_code_action(&action),
 1670                                );
 1671                                continue;
 1672                            }
 1673                            for operation in operations {
 1674                                let op = match operation {
 1675                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1676                                    lsp::DocumentChangeOperation::Op(_) => {
 1677                                        zlog::warn!(
 1678                                            logger =>
 1679                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1680                                            describe_code_action(&action),
 1681                                        );
 1682                                        continue 'actions;
 1683                                    }
 1684                                };
 1685                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1686                                    zlog::warn!(
 1687                                        logger =>
 1688                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1689                                        &op.text_document.uri,
 1690                                        describe_code_action(&action),
 1691                                    );
 1692                                    continue 'actions;
 1693                                };
 1694                                if &file_path != buffer_path_abs {
 1695                                    zlog::warn!(
 1696                                        logger =>
 1697                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1698                                        file_path,
 1699                                        buffer_path_abs,
 1700                                        describe_code_action(&action),
 1701                                    );
 1702                                    continue 'actions;
 1703                                }
 1704
 1705                                let mut lsp_edits = Vec::new();
 1706                                for edit in op.edits {
 1707                                    match edit {
 1708                                        Edit::Plain(edit) => {
 1709                                            if !lsp_edits.contains(&edit) {
 1710                                                lsp_edits.push(edit);
 1711                                            }
 1712                                        }
 1713                                        Edit::Annotated(edit) => {
 1714                                            if !lsp_edits.contains(&edit.text_edit) {
 1715                                                lsp_edits.push(edit.text_edit);
 1716                                            }
 1717                                        }
 1718                                        Edit::Snippet(_) => {
 1719                                            zlog::warn!(
 1720                                                logger =>
 1721                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1722                                                describe_code_action(&action),
 1723                                            );
 1724                                            continue 'actions;
 1725                                        }
 1726                                    }
 1727                                }
 1728                                let edits_result = lsp_store
 1729                                    .update(cx, |lsp_store, cx| {
 1730                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1731                                            &buffer.handle,
 1732                                            lsp_edits,
 1733                                            server.server_id(),
 1734                                            op.text_document.version,
 1735                                            cx,
 1736                                        )
 1737                                    })?
 1738                                    .await;
 1739                                let Ok(resolved_edits) = edits_result else {
 1740                                    zlog::warn!(
 1741                                        logger =>
 1742                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1743                                        buffer_path_abs.as_path(),
 1744                                        describe_code_action(&action),
 1745                                    );
 1746                                    continue 'actions;
 1747                                };
 1748                                edits.extend(resolved_edits);
 1749                            }
 1750
 1751                            if edits.is_empty() {
 1752                                zlog::warn!(logger => "No edits resolved from LSP");
 1753                                continue;
 1754                            }
 1755
 1756                            extend_formatting_transaction(
 1757                                buffer,
 1758                                formatting_transaction_id,
 1759                                cx,
 1760                                |buffer, cx| {
 1761                                    zlog::info!(
 1762                                        "Applying edits {edits:?}. Content: {:?}",
 1763                                        buffer.text()
 1764                                    );
 1765                                    buffer.edit(edits, None, cx);
 1766                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1767                                },
 1768                            )?;
 1769                        }
 1770
 1771                        if let Some(command) = action.lsp_action.command() {
 1772                            zlog::warn!(
 1773                                logger =>
 1774                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1775                                &command.command,
 1776                            );
 1777
 1778                            // bail early if command is invalid
 1779                            let server_capabilities = server.capabilities();
 1780                            let available_commands = server_capabilities
 1781                                .execute_command_provider
 1782                                .as_ref()
 1783                                .map(|options| options.commands.as_slice())
 1784                                .unwrap_or_default();
 1785                            if !available_commands.contains(&command.command) {
 1786                                zlog::warn!(
 1787                                    logger =>
 1788                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1789                                    command.command,
 1790                                    server.name(),
 1791                                );
 1792                                continue;
 1793                            }
 1794
 1795                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1796                            extend_formatting_transaction(
 1797                                buffer,
 1798                                formatting_transaction_id,
 1799                                cx,
 1800                                |_, _| {},
 1801                            )?;
 1802                            zlog::info!(logger => "Executing command {}", &command.command);
 1803
 1804                            lsp_store.update(cx, |this, _| {
 1805                                this.as_local_mut()
 1806                                    .unwrap()
 1807                                    .last_workspace_edits_by_language_server
 1808                                    .remove(&server.server_id());
 1809                            })?;
 1810
 1811                            let execute_command_result = server
 1812                                .request::<lsp::request::ExecuteCommand>(
 1813                                    lsp::ExecuteCommandParams {
 1814                                        command: command.command.clone(),
 1815                                        arguments: command.arguments.clone().unwrap_or_default(),
 1816                                        ..Default::default()
 1817                                    },
 1818                                )
 1819                                .await
 1820                                .into_response();
 1821
 1822                            if execute_command_result.is_err() {
 1823                                zlog::error!(
 1824                                    logger =>
 1825                                    "Failed to execute command '{}' as part of {}",
 1826                                    &command.command,
 1827                                    describe_code_action(&action),
 1828                                );
 1829                                continue 'actions;
 1830                            }
 1831
 1832                            let mut project_transaction_command =
 1833                                lsp_store.update(cx, |this, _| {
 1834                                    this.as_local_mut()
 1835                                        .unwrap()
 1836                                        .last_workspace_edits_by_language_server
 1837                                        .remove(&server.server_id())
 1838                                        .unwrap_or_default()
 1839                                })?;
 1840
 1841                            if let Some(transaction) =
 1842                                project_transaction_command.0.remove(&buffer.handle)
 1843                            {
 1844                                zlog::trace!(
 1845                                    logger =>
 1846                                    "Successfully captured {} edits that resulted from command {}",
 1847                                    transaction.edit_ids.len(),
 1848                                    &command.command,
 1849                                );
 1850                                let transaction_id_project_transaction = transaction.id;
 1851                                buffer.handle.update(cx, |buffer, _| {
 1852                                    // it may have been removed from history if push_to_history was
 1853                                    // false in deserialize_workspace_edit. If so push it so we
 1854                                    // can merge it with the format transaction
 1855                                    // and pop the combined transaction off the history stack
 1856                                    // later if push_to_history is false
 1857                                    if buffer.get_transaction(transaction.id).is_none() {
 1858                                        buffer.push_transaction(transaction, Instant::now());
 1859                                    }
 1860                                    buffer.merge_transactions(
 1861                                        transaction_id_project_transaction,
 1862                                        formatting_transaction_id,
 1863                                    );
 1864                                })?;
 1865                            }
 1866
 1867                            if !project_transaction_command.0.is_empty() {
 1868                                let mut extra_buffers = String::new();
 1869                                for buffer in project_transaction_command.0.keys() {
 1870                                    buffer
 1871                                        .read_with(cx, |b, cx| {
 1872                                            if let Some(path) = b.project_path(cx) {
 1873                                                if !extra_buffers.is_empty() {
 1874                                                    extra_buffers.push_str(", ");
 1875                                                }
 1876                                                extra_buffers.push_str(path.path.as_unix_str());
 1877                                            }
 1878                                        })
 1879                                        .ok();
 1880                                }
 1881                                zlog::warn!(
 1882                                    logger =>
 1883                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1884                                    &command.command,
 1885                                    extra_buffers,
 1886                                );
 1887                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1888                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1889                                // add it so it's included, and merge it into the format transaction when its created later
 1890                            }
 1891                        }
 1892                    }
 1893                }
 1894            }
 1895        }
 1896
 1897        Ok(())
 1898    }
 1899
 1900    pub async fn format_ranges_via_lsp(
 1901        this: &WeakEntity<LspStore>,
 1902        buffer_handle: &Entity<Buffer>,
 1903        ranges: &[Range<Anchor>],
 1904        abs_path: &Path,
 1905        language_server: &Arc<LanguageServer>,
 1906        settings: &LanguageSettings,
 1907        cx: &mut AsyncApp,
 1908    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1909        let capabilities = &language_server.capabilities();
 1910        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1911        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1912            anyhow::bail!(
 1913                "{} language server does not support range formatting",
 1914                language_server.name()
 1915            );
 1916        }
 1917
 1918        let uri = file_path_to_lsp_url(abs_path)?;
 1919        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1920
 1921        let lsp_edits = {
 1922            let mut lsp_ranges = Vec::new();
 1923            this.update(cx, |_this, cx| {
 1924                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1925                // not have been sent to the language server. This seems like a fairly systemic
 1926                // issue, though, the resolution probably is not specific to formatting.
 1927                //
 1928                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1929                // LSP.
 1930                let snapshot = buffer_handle.read(cx).snapshot();
 1931                for range in ranges {
 1932                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1933                }
 1934                anyhow::Ok(())
 1935            })??;
 1936
 1937            let mut edits = None;
 1938            for range in lsp_ranges {
 1939                if let Some(mut edit) = language_server
 1940                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1941                        text_document: text_document.clone(),
 1942                        range,
 1943                        options: lsp_command::lsp_formatting_options(settings),
 1944                        work_done_progress_params: Default::default(),
 1945                    })
 1946                    .await
 1947                    .into_response()?
 1948                {
 1949                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1950                }
 1951            }
 1952            edits
 1953        };
 1954
 1955        if let Some(lsp_edits) = lsp_edits {
 1956            this.update(cx, |this, cx| {
 1957                this.as_local_mut().unwrap().edits_from_lsp(
 1958                    buffer_handle,
 1959                    lsp_edits,
 1960                    language_server.server_id(),
 1961                    None,
 1962                    cx,
 1963                )
 1964            })?
 1965            .await
 1966        } else {
 1967            Ok(Vec::with_capacity(0))
 1968        }
 1969    }
 1970
 1971    async fn format_via_lsp(
 1972        this: &WeakEntity<LspStore>,
 1973        buffer: &Entity<Buffer>,
 1974        abs_path: &Path,
 1975        language_server: &Arc<LanguageServer>,
 1976        settings: &LanguageSettings,
 1977        cx: &mut AsyncApp,
 1978    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1979        let logger = zlog::scoped!("lsp_format");
 1980        zlog::info!(logger => "Formatting via LSP");
 1981
 1982        let uri = file_path_to_lsp_url(abs_path)?;
 1983        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1984        let capabilities = &language_server.capabilities();
 1985
 1986        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1987        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1988
 1989        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1990            let _timer = zlog::time!(logger => "format-full");
 1991            language_server
 1992                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1993                    text_document,
 1994                    options: lsp_command::lsp_formatting_options(settings),
 1995                    work_done_progress_params: Default::default(),
 1996                })
 1997                .await
 1998                .into_response()?
 1999        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2000            let _timer = zlog::time!(logger => "format-range");
 2001            let buffer_start = lsp::Position::new(0, 0);
 2002            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2003            language_server
 2004                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2005                    text_document: text_document.clone(),
 2006                    range: lsp::Range::new(buffer_start, buffer_end),
 2007                    options: lsp_command::lsp_formatting_options(settings),
 2008                    work_done_progress_params: Default::default(),
 2009                })
 2010                .await
 2011                .into_response()?
 2012        } else {
 2013            None
 2014        };
 2015
 2016        if let Some(lsp_edits) = lsp_edits {
 2017            this.update(cx, |this, cx| {
 2018                this.as_local_mut().unwrap().edits_from_lsp(
 2019                    buffer,
 2020                    lsp_edits,
 2021                    language_server.server_id(),
 2022                    None,
 2023                    cx,
 2024                )
 2025            })?
 2026            .await
 2027        } else {
 2028            Ok(Vec::with_capacity(0))
 2029        }
 2030    }
 2031
 2032    async fn format_via_external_command(
 2033        buffer: &FormattableBuffer,
 2034        command: &str,
 2035        arguments: Option<&[String]>,
 2036        cx: &mut AsyncApp,
 2037    ) -> Result<Option<Diff>> {
 2038        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2039            let file = File::from_dyn(buffer.file())?;
 2040            let worktree = file.worktree.read(cx);
 2041            let mut worktree_path = worktree.abs_path().to_path_buf();
 2042            if worktree.root_entry()?.is_file() {
 2043                worktree_path.pop();
 2044            }
 2045            Some(worktree_path)
 2046        })?;
 2047
 2048        let mut child = util::command::new_smol_command(command);
 2049
 2050        if let Some(buffer_env) = buffer.env.as_ref() {
 2051            child.envs(buffer_env);
 2052        }
 2053
 2054        if let Some(working_dir_path) = working_dir_path {
 2055            child.current_dir(working_dir_path);
 2056        }
 2057
 2058        if let Some(arguments) = arguments {
 2059            child.args(arguments.iter().map(|arg| {
 2060                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2061                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2062                } else {
 2063                    arg.replace("{buffer_path}", "Untitled")
 2064                }
 2065            }));
 2066        }
 2067
 2068        let mut child = child
 2069            .stdin(smol::process::Stdio::piped())
 2070            .stdout(smol::process::Stdio::piped())
 2071            .stderr(smol::process::Stdio::piped())
 2072            .spawn()?;
 2073
 2074        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2075        let text = buffer
 2076            .handle
 2077            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2078        for chunk in text.chunks() {
 2079            stdin.write_all(chunk.as_bytes()).await?;
 2080        }
 2081        stdin.flush().await?;
 2082
 2083        let output = child.output().await?;
 2084        anyhow::ensure!(
 2085            output.status.success(),
 2086            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2087            output.status.code(),
 2088            String::from_utf8_lossy(&output.stdout),
 2089            String::from_utf8_lossy(&output.stderr),
 2090        );
 2091
 2092        let stdout = String::from_utf8(output.stdout)?;
 2093        Ok(Some(
 2094            buffer
 2095                .handle
 2096                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2097                .await,
 2098        ))
 2099    }
 2100
 2101    async fn try_resolve_code_action(
 2102        lang_server: &LanguageServer,
 2103        action: &mut CodeAction,
 2104    ) -> anyhow::Result<()> {
 2105        match &mut action.lsp_action {
 2106            LspAction::Action(lsp_action) => {
 2107                if !action.resolved
 2108                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2109                    && lsp_action.data.is_some()
 2110                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2111                {
 2112                    *lsp_action = Box::new(
 2113                        lang_server
 2114                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2115                            .await
 2116                            .into_response()?,
 2117                    );
 2118                }
 2119            }
 2120            LspAction::CodeLens(lens) => {
 2121                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2122                    *lens = lang_server
 2123                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2124                        .await
 2125                        .into_response()?;
 2126                }
 2127            }
 2128            LspAction::Command(_) => {}
 2129        }
 2130
 2131        action.resolved = true;
 2132        anyhow::Ok(())
 2133    }
 2134
 2135    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2136        let buffer = buffer_handle.read(cx);
 2137
 2138        let file = buffer.file().cloned();
 2139
 2140        let Some(file) = File::from_dyn(file.as_ref()) else {
 2141            return;
 2142        };
 2143        if !file.is_local() {
 2144            return;
 2145        }
 2146        let path = ProjectPath::from_file(file, cx);
 2147        let worktree_id = file.worktree_id(cx);
 2148        let language = buffer.language().cloned();
 2149
 2150        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2151            for (server_id, diagnostics) in
 2152                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2153            {
 2154                self.update_buffer_diagnostics(
 2155                    buffer_handle,
 2156                    server_id,
 2157                    None,
 2158                    None,
 2159                    diagnostics,
 2160                    Vec::new(),
 2161                    cx,
 2162                )
 2163                .log_err();
 2164            }
 2165        }
 2166        let Some(language) = language else {
 2167            return;
 2168        };
 2169        let Some(snapshot) = self
 2170            .worktree_store
 2171            .read(cx)
 2172            .worktree_for_id(worktree_id, cx)
 2173            .map(|worktree| worktree.read(cx).snapshot())
 2174        else {
 2175            return;
 2176        };
 2177        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2178
 2179        for server_id in
 2180            self.lsp_tree
 2181                .get(path, language.name(), language.manifest(), &delegate, cx)
 2182        {
 2183            let server = self
 2184                .language_servers
 2185                .get(&server_id)
 2186                .and_then(|server_state| {
 2187                    if let LanguageServerState::Running { server, .. } = server_state {
 2188                        Some(server.clone())
 2189                    } else {
 2190                        None
 2191                    }
 2192                });
 2193            let server = match server {
 2194                Some(server) => server,
 2195                None => continue,
 2196            };
 2197
 2198            buffer_handle.update(cx, |buffer, cx| {
 2199                buffer.set_completion_triggers(
 2200                    server.server_id(),
 2201                    server
 2202                        .capabilities()
 2203                        .completion_provider
 2204                        .as_ref()
 2205                        .and_then(|provider| {
 2206                            provider
 2207                                .trigger_characters
 2208                                .as_ref()
 2209                                .map(|characters| characters.iter().cloned().collect())
 2210                        })
 2211                        .unwrap_or_default(),
 2212                    cx,
 2213                );
 2214            });
 2215        }
 2216    }
 2217
 2218    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2219        buffer.update(cx, |buffer, cx| {
 2220            let Some(language) = buffer.language() else {
 2221                return;
 2222            };
 2223            let path = ProjectPath {
 2224                worktree_id: old_file.worktree_id(cx),
 2225                path: old_file.path.clone(),
 2226            };
 2227            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2228                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2229                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2230            }
 2231        });
 2232    }
 2233
 2234    fn update_buffer_diagnostics(
 2235        &mut self,
 2236        buffer: &Entity<Buffer>,
 2237        server_id: LanguageServerId,
 2238        result_id: Option<String>,
 2239        version: Option<i32>,
 2240        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2241        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2242        cx: &mut Context<LspStore>,
 2243    ) -> Result<()> {
 2244        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2245            Ordering::Equal
 2246                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2247                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2248                .then_with(|| a.severity.cmp(&b.severity))
 2249                .then_with(|| a.message.cmp(&b.message))
 2250        }
 2251
 2252        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2253        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2254        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2255
 2256        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2257            Ordering::Equal
 2258                .then_with(|| a.range.start.cmp(&b.range.start))
 2259                .then_with(|| b.range.end.cmp(&a.range.end))
 2260                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2261        });
 2262
 2263        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2264
 2265        let edits_since_save = std::cell::LazyCell::new(|| {
 2266            let saved_version = buffer.read(cx).saved_version();
 2267            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2268        });
 2269
 2270        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2271
 2272        for (new_diagnostic, entry) in diagnostics {
 2273            let start;
 2274            let end;
 2275            if new_diagnostic && entry.diagnostic.is_disk_based {
 2276                // Some diagnostics are based on files on disk instead of buffers'
 2277                // current contents. Adjust these diagnostics' ranges to reflect
 2278                // any unsaved edits.
 2279                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2280                // and were properly adjusted on reuse.
 2281                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2282                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2283            } else {
 2284                start = entry.range.start;
 2285                end = entry.range.end;
 2286            }
 2287
 2288            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2289                ..snapshot.clip_point_utf16(end, Bias::Right);
 2290
 2291            // Expand empty ranges by one codepoint
 2292            if range.start == range.end {
 2293                // This will be go to the next boundary when being clipped
 2294                range.end.column += 1;
 2295                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2296                if range.start == range.end && range.end.column > 0 {
 2297                    range.start.column -= 1;
 2298                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2299                }
 2300            }
 2301
 2302            sanitized_diagnostics.push(DiagnosticEntry {
 2303                range,
 2304                diagnostic: entry.diagnostic,
 2305            });
 2306        }
 2307        drop(edits_since_save);
 2308
 2309        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2310        buffer.update(cx, |buffer, cx| {
 2311            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2312                self.buffer_pull_diagnostics_result_ids
 2313                    .entry(server_id)
 2314                    .or_default()
 2315                    .insert(abs_path, result_id);
 2316            }
 2317
 2318            buffer.update_diagnostics(server_id, set, cx)
 2319        });
 2320
 2321        Ok(())
 2322    }
 2323
 2324    fn register_language_server_for_invisible_worktree(
 2325        &mut self,
 2326        worktree: &Entity<Worktree>,
 2327        language_server_id: LanguageServerId,
 2328        cx: &mut App,
 2329    ) {
 2330        let worktree = worktree.read(cx);
 2331        let worktree_id = worktree.id();
 2332        debug_assert!(!worktree.is_visible());
 2333        let Some(mut origin_seed) = self
 2334            .language_server_ids
 2335            .iter()
 2336            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2337        else {
 2338            return;
 2339        };
 2340        origin_seed.worktree_id = worktree_id;
 2341        self.language_server_ids
 2342            .entry(origin_seed)
 2343            .or_insert_with(|| UnifiedLanguageServer {
 2344                id: language_server_id,
 2345                project_roots: Default::default(),
 2346            });
 2347    }
 2348
 2349    fn register_buffer_with_language_servers(
 2350        &mut self,
 2351        buffer_handle: &Entity<Buffer>,
 2352        only_register_servers: HashSet<LanguageServerSelector>,
 2353        cx: &mut Context<LspStore>,
 2354    ) {
 2355        let buffer = buffer_handle.read(cx);
 2356        let buffer_id = buffer.remote_id();
 2357
 2358        let Some(file) = File::from_dyn(buffer.file()) else {
 2359            return;
 2360        };
 2361        if !file.is_local() {
 2362            return;
 2363        }
 2364
 2365        let abs_path = file.abs_path(cx);
 2366        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2367            return;
 2368        };
 2369        let initial_snapshot = buffer.text_snapshot();
 2370        let worktree_id = file.worktree_id(cx);
 2371
 2372        let Some(language) = buffer.language().cloned() else {
 2373            return;
 2374        };
 2375        let path: Arc<RelPath> = file
 2376            .path()
 2377            .parent()
 2378            .map(Arc::from)
 2379            .unwrap_or_else(|| file.path().clone());
 2380        let Some(worktree) = self
 2381            .worktree_store
 2382            .read(cx)
 2383            .worktree_for_id(worktree_id, cx)
 2384        else {
 2385            return;
 2386        };
 2387        let language_name = language.name();
 2388        let (reused, delegate, servers) = self
 2389            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2390            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2391            .unwrap_or_else(|| {
 2392                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2393                let delegate: Arc<dyn ManifestDelegate> =
 2394                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2395
 2396                let servers = self
 2397                    .lsp_tree
 2398                    .walk(
 2399                        ProjectPath { worktree_id, path },
 2400                        language.name(),
 2401                        language.manifest(),
 2402                        &delegate,
 2403                        cx,
 2404                    )
 2405                    .collect::<Vec<_>>();
 2406                (false, lsp_delegate, servers)
 2407            });
 2408        let servers_and_adapters = servers
 2409            .into_iter()
 2410            .filter_map(|server_node| {
 2411                if reused && server_node.server_id().is_none() {
 2412                    return None;
 2413                }
 2414                if !only_register_servers.is_empty() {
 2415                    if let Some(server_id) = server_node.server_id()
 2416                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2417                    {
 2418                        return None;
 2419                    }
 2420                    if let Some(name) = server_node.name()
 2421                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2422                    {
 2423                        return None;
 2424                    }
 2425                }
 2426
 2427                let server_id = server_node.server_id_or_init(|disposition| {
 2428                    let path = &disposition.path;
 2429
 2430                    {
 2431                        let absolute_path = worktree.read(cx).absolutize(&path.path);
 2432                        let uri = absolute_path
 2433                            .is_dir()
 2434                            .then(|| Uri::from_file_path(absolute_path))
 2435                            .transpose();
 2436
 2437                        let server_id = self.get_or_insert_language_server(
 2438                            &worktree,
 2439                            delegate.clone(),
 2440                            disposition,
 2441                            &language_name,
 2442                            cx,
 2443                        );
 2444
 2445                        if let Some(state) = self.language_servers.get(&server_id)
 2446                            && let Ok(Some(uri)) = uri
 2447                        {
 2448                            state.add_workspace_folder(uri);
 2449                        };
 2450                        server_id
 2451                    }
 2452                })?;
 2453                let server_state = self.language_servers.get(&server_id)?;
 2454                if let LanguageServerState::Running {
 2455                    server, adapter, ..
 2456                } = server_state
 2457                {
 2458                    Some((server.clone(), adapter.clone()))
 2459                } else {
 2460                    None
 2461                }
 2462            })
 2463            .collect::<Vec<_>>();
 2464        for (server, adapter) in servers_and_adapters {
 2465            buffer_handle.update(cx, |buffer, cx| {
 2466                buffer.set_completion_triggers(
 2467                    server.server_id(),
 2468                    server
 2469                        .capabilities()
 2470                        .completion_provider
 2471                        .as_ref()
 2472                        .and_then(|provider| {
 2473                            provider
 2474                                .trigger_characters
 2475                                .as_ref()
 2476                                .map(|characters| characters.iter().cloned().collect())
 2477                        })
 2478                        .unwrap_or_default(),
 2479                    cx,
 2480                );
 2481            });
 2482
 2483            let snapshot = LspBufferSnapshot {
 2484                version: 0,
 2485                snapshot: initial_snapshot.clone(),
 2486            };
 2487
 2488            let mut registered = false;
 2489            self.buffer_snapshots
 2490                .entry(buffer_id)
 2491                .or_default()
 2492                .entry(server.server_id())
 2493                .or_insert_with(|| {
 2494                    registered = true;
 2495                    server.register_buffer(
 2496                        uri.clone(),
 2497                        adapter.language_id(&language.name()),
 2498                        0,
 2499                        initial_snapshot.text(),
 2500                    );
 2501
 2502                    vec![snapshot]
 2503                });
 2504
 2505            self.buffers_opened_in_servers
 2506                .entry(buffer_id)
 2507                .or_default()
 2508                .insert(server.server_id());
 2509            if registered {
 2510                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2511                    language_server_id: server.server_id(),
 2512                    name: None,
 2513                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2514                        proto::RegisteredForBuffer {
 2515                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2516                            buffer_id: buffer_id.to_proto(),
 2517                        },
 2518                    ),
 2519                });
 2520            }
 2521        }
 2522    }
 2523
 2524    fn reuse_existing_language_server<'lang_name>(
 2525        &self,
 2526        server_tree: &LanguageServerTree,
 2527        worktree: &Entity<Worktree>,
 2528        language_name: &'lang_name LanguageName,
 2529        cx: &mut App,
 2530    ) -> Option<(
 2531        Arc<LocalLspAdapterDelegate>,
 2532        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2533    )> {
 2534        if worktree.read(cx).is_visible() {
 2535            return None;
 2536        }
 2537
 2538        let worktree_store = self.worktree_store.read(cx);
 2539        let servers = server_tree
 2540            .instances
 2541            .iter()
 2542            .filter(|(worktree_id, _)| {
 2543                worktree_store
 2544                    .worktree_for_id(**worktree_id, cx)
 2545                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2546            })
 2547            .flat_map(|(worktree_id, servers)| {
 2548                servers
 2549                    .roots
 2550                    .iter()
 2551                    .flat_map(|(_, language_servers)| language_servers)
 2552                    .map(move |(_, (server_node, server_languages))| {
 2553                        (worktree_id, server_node, server_languages)
 2554                    })
 2555                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2556                    .map(|(worktree_id, server_node, _)| {
 2557                        (
 2558                            *worktree_id,
 2559                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2560                        )
 2561                    })
 2562            })
 2563            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2564                acc.entry(worktree_id)
 2565                    .or_insert_with(Vec::new)
 2566                    .push(server_node);
 2567                acc
 2568            })
 2569            .into_values()
 2570            .max_by_key(|servers| servers.len())?;
 2571
 2572        let worktree_id = worktree.read(cx).id();
 2573        let apply = move |tree: &mut LanguageServerTree| {
 2574            for server_node in &servers {
 2575                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2576            }
 2577            servers
 2578        };
 2579
 2580        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2581        Some((delegate, apply))
 2582    }
 2583
 2584    pub(crate) fn unregister_old_buffer_from_language_servers(
 2585        &mut self,
 2586        buffer: &Entity<Buffer>,
 2587        old_file: &File,
 2588        cx: &mut App,
 2589    ) {
 2590        let old_path = match old_file.as_local() {
 2591            Some(local) => local.abs_path(cx),
 2592            None => return,
 2593        };
 2594
 2595        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2596            debug_panic!("{old_path:?} is not parseable as an URI");
 2597            return;
 2598        };
 2599        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2600    }
 2601
 2602    pub(crate) fn unregister_buffer_from_language_servers(
 2603        &mut self,
 2604        buffer: &Entity<Buffer>,
 2605        file_url: &lsp::Uri,
 2606        cx: &mut App,
 2607    ) {
 2608        buffer.update(cx, |buffer, cx| {
 2609            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2610
 2611            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2612                language_server.unregister_buffer(file_url.clone());
 2613            }
 2614        });
 2615    }
 2616
 2617    fn buffer_snapshot_for_lsp_version(
 2618        &mut self,
 2619        buffer: &Entity<Buffer>,
 2620        server_id: LanguageServerId,
 2621        version: Option<i32>,
 2622        cx: &App,
 2623    ) -> Result<TextBufferSnapshot> {
 2624        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2625
 2626        if let Some(version) = version {
 2627            let buffer_id = buffer.read(cx).remote_id();
 2628            let snapshots = if let Some(snapshots) = self
 2629                .buffer_snapshots
 2630                .get_mut(&buffer_id)
 2631                .and_then(|m| m.get_mut(&server_id))
 2632            {
 2633                snapshots
 2634            } else if version == 0 {
 2635                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2636                // We detect this case and treat it as if the version was `None`.
 2637                return Ok(buffer.read(cx).text_snapshot());
 2638            } else {
 2639                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2640            };
 2641
 2642            let found_snapshot = snapshots
 2643                    .binary_search_by_key(&version, |e| e.version)
 2644                    .map(|ix| snapshots[ix].snapshot.clone())
 2645                    .map_err(|_| {
 2646                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2647                    })?;
 2648
 2649            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2650            Ok(found_snapshot)
 2651        } else {
 2652            Ok((buffer.read(cx)).text_snapshot())
 2653        }
 2654    }
 2655
 2656    async fn get_server_code_actions_from_action_kinds(
 2657        lsp_store: &WeakEntity<LspStore>,
 2658        language_server_id: LanguageServerId,
 2659        code_action_kinds: Vec<lsp::CodeActionKind>,
 2660        buffer: &Entity<Buffer>,
 2661        cx: &mut AsyncApp,
 2662    ) -> Result<Vec<CodeAction>> {
 2663        let actions = lsp_store
 2664            .update(cx, move |this, cx| {
 2665                let request = GetCodeActions {
 2666                    range: text::Anchor::MIN..text::Anchor::MAX,
 2667                    kinds: Some(code_action_kinds),
 2668                };
 2669                let server = LanguageServerToQuery::Other(language_server_id);
 2670                this.request_lsp(buffer.clone(), server, request, cx)
 2671            })?
 2672            .await?;
 2673        Ok(actions)
 2674    }
 2675
 2676    pub async fn execute_code_actions_on_server(
 2677        lsp_store: &WeakEntity<LspStore>,
 2678        language_server: &Arc<LanguageServer>,
 2679
 2680        actions: Vec<CodeAction>,
 2681        push_to_history: bool,
 2682        project_transaction: &mut ProjectTransaction,
 2683        cx: &mut AsyncApp,
 2684    ) -> anyhow::Result<()> {
 2685        for mut action in actions {
 2686            Self::try_resolve_code_action(language_server, &mut action)
 2687                .await
 2688                .context("resolving a formatting code action")?;
 2689
 2690            if let Some(edit) = action.lsp_action.edit() {
 2691                if edit.changes.is_none() && edit.document_changes.is_none() {
 2692                    continue;
 2693                }
 2694
 2695                let new = Self::deserialize_workspace_edit(
 2696                    lsp_store.upgrade().context("project dropped")?,
 2697                    edit.clone(),
 2698                    push_to_history,
 2699                    language_server.clone(),
 2700                    cx,
 2701                )
 2702                .await?;
 2703                project_transaction.0.extend(new.0);
 2704            }
 2705
 2706            if let Some(command) = action.lsp_action.command() {
 2707                let server_capabilities = language_server.capabilities();
 2708                let available_commands = server_capabilities
 2709                    .execute_command_provider
 2710                    .as_ref()
 2711                    .map(|options| options.commands.as_slice())
 2712                    .unwrap_or_default();
 2713                if available_commands.contains(&command.command) {
 2714                    lsp_store.update(cx, |lsp_store, _| {
 2715                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2716                            mode.last_workspace_edits_by_language_server
 2717                                .remove(&language_server.server_id());
 2718                        }
 2719                    })?;
 2720
 2721                    language_server
 2722                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2723                            command: command.command.clone(),
 2724                            arguments: command.arguments.clone().unwrap_or_default(),
 2725                            ..Default::default()
 2726                        })
 2727                        .await
 2728                        .into_response()
 2729                        .context("execute command")?;
 2730
 2731                    lsp_store.update(cx, |this, _| {
 2732                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2733                            project_transaction.0.extend(
 2734                                mode.last_workspace_edits_by_language_server
 2735                                    .remove(&language_server.server_id())
 2736                                    .unwrap_or_default()
 2737                                    .0,
 2738                            )
 2739                        }
 2740                    })?;
 2741                } else {
 2742                    log::warn!(
 2743                        "Cannot execute a command {} not listed in the language server capabilities",
 2744                        command.command
 2745                    )
 2746                }
 2747            }
 2748        }
 2749        Ok(())
 2750    }
 2751
 2752    pub async fn deserialize_text_edits(
 2753        this: Entity<LspStore>,
 2754        buffer_to_edit: Entity<Buffer>,
 2755        edits: Vec<lsp::TextEdit>,
 2756        push_to_history: bool,
 2757        _: Arc<CachedLspAdapter>,
 2758        language_server: Arc<LanguageServer>,
 2759        cx: &mut AsyncApp,
 2760    ) -> Result<Option<Transaction>> {
 2761        let edits = this
 2762            .update(cx, |this, cx| {
 2763                this.as_local_mut().unwrap().edits_from_lsp(
 2764                    &buffer_to_edit,
 2765                    edits,
 2766                    language_server.server_id(),
 2767                    None,
 2768                    cx,
 2769                )
 2770            })?
 2771            .await?;
 2772
 2773        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2774            buffer.finalize_last_transaction();
 2775            buffer.start_transaction();
 2776            for (range, text) in edits {
 2777                buffer.edit([(range, text)], None, cx);
 2778            }
 2779
 2780            if buffer.end_transaction(cx).is_some() {
 2781                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2782                if !push_to_history {
 2783                    buffer.forget_transaction(transaction.id);
 2784                }
 2785                Some(transaction)
 2786            } else {
 2787                None
 2788            }
 2789        })?;
 2790
 2791        Ok(transaction)
 2792    }
 2793
 2794    #[allow(clippy::type_complexity)]
 2795    pub(crate) fn edits_from_lsp(
 2796        &mut self,
 2797        buffer: &Entity<Buffer>,
 2798        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2799        server_id: LanguageServerId,
 2800        version: Option<i32>,
 2801        cx: &mut Context<LspStore>,
 2802    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2803        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2804        cx.background_spawn(async move {
 2805            let snapshot = snapshot?;
 2806            let mut lsp_edits = lsp_edits
 2807                .into_iter()
 2808                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2809                .collect::<Vec<_>>();
 2810
 2811            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2812
 2813            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2814            let mut edits = Vec::new();
 2815            while let Some((range, mut new_text)) = lsp_edits.next() {
 2816                // Clip invalid ranges provided by the language server.
 2817                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2818                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2819
 2820                // Combine any LSP edits that are adjacent.
 2821                //
 2822                // Also, combine LSP edits that are separated from each other by only
 2823                // a newline. This is important because for some code actions,
 2824                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2825                // are separated by unchanged newline characters.
 2826                //
 2827                // In order for the diffing logic below to work properly, any edits that
 2828                // cancel each other out must be combined into one.
 2829                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2830                    if next_range.start.0 > range.end {
 2831                        if next_range.start.0.row > range.end.row + 1
 2832                            || next_range.start.0.column > 0
 2833                            || snapshot.clip_point_utf16(
 2834                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2835                                Bias::Left,
 2836                            ) > range.end
 2837                        {
 2838                            break;
 2839                        }
 2840                        new_text.push('\n');
 2841                    }
 2842                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2843                    new_text.push_str(next_text);
 2844                    lsp_edits.next();
 2845                }
 2846
 2847                // For multiline edits, perform a diff of the old and new text so that
 2848                // we can identify the changes more precisely, preserving the locations
 2849                // of any anchors positioned in the unchanged regions.
 2850                if range.end.row > range.start.row {
 2851                    let offset = range.start.to_offset(&snapshot);
 2852                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2853                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2854                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2855                        (
 2856                            snapshot.anchor_after(offset + range.start)
 2857                                ..snapshot.anchor_before(offset + range.end),
 2858                            replacement,
 2859                        )
 2860                    }));
 2861                } else if range.end == range.start {
 2862                    let anchor = snapshot.anchor_after(range.start);
 2863                    edits.push((anchor..anchor, new_text.into()));
 2864                } else {
 2865                    let edit_start = snapshot.anchor_after(range.start);
 2866                    let edit_end = snapshot.anchor_before(range.end);
 2867                    edits.push((edit_start..edit_end, new_text.into()));
 2868                }
 2869            }
 2870
 2871            Ok(edits)
 2872        })
 2873    }
 2874
 2875    pub(crate) async fn deserialize_workspace_edit(
 2876        this: Entity<LspStore>,
 2877        edit: lsp::WorkspaceEdit,
 2878        push_to_history: bool,
 2879        language_server: Arc<LanguageServer>,
 2880        cx: &mut AsyncApp,
 2881    ) -> Result<ProjectTransaction> {
 2882        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2883
 2884        let mut operations = Vec::new();
 2885        if let Some(document_changes) = edit.document_changes {
 2886            match document_changes {
 2887                lsp::DocumentChanges::Edits(edits) => {
 2888                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2889                }
 2890                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2891            }
 2892        } else if let Some(changes) = edit.changes {
 2893            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2894                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2895                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2896                        uri,
 2897                        version: None,
 2898                    },
 2899                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2900                })
 2901            }));
 2902        }
 2903
 2904        let mut project_transaction = ProjectTransaction::default();
 2905        for operation in operations {
 2906            match operation {
 2907                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2908                    let abs_path = op
 2909                        .uri
 2910                        .to_file_path()
 2911                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2912
 2913                    if let Some(parent_path) = abs_path.parent() {
 2914                        fs.create_dir(parent_path).await?;
 2915                    }
 2916                    if abs_path.ends_with("/") {
 2917                        fs.create_dir(&abs_path).await?;
 2918                    } else {
 2919                        fs.create_file(
 2920                            &abs_path,
 2921                            op.options
 2922                                .map(|options| fs::CreateOptions {
 2923                                    overwrite: options.overwrite.unwrap_or(false),
 2924                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2925                                })
 2926                                .unwrap_or_default(),
 2927                        )
 2928                        .await?;
 2929                    }
 2930                }
 2931
 2932                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2933                    let source_abs_path = op
 2934                        .old_uri
 2935                        .to_file_path()
 2936                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2937                    let target_abs_path = op
 2938                        .new_uri
 2939                        .to_file_path()
 2940                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2941                    fs.rename(
 2942                        &source_abs_path,
 2943                        &target_abs_path,
 2944                        op.options
 2945                            .map(|options| fs::RenameOptions {
 2946                                overwrite: options.overwrite.unwrap_or(false),
 2947                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2948                            })
 2949                            .unwrap_or_default(),
 2950                    )
 2951                    .await?;
 2952                }
 2953
 2954                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2955                    let abs_path = op
 2956                        .uri
 2957                        .to_file_path()
 2958                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2959                    let options = op
 2960                        .options
 2961                        .map(|options| fs::RemoveOptions {
 2962                            recursive: options.recursive.unwrap_or(false),
 2963                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2964                        })
 2965                        .unwrap_or_default();
 2966                    if abs_path.ends_with("/") {
 2967                        fs.remove_dir(&abs_path, options).await?;
 2968                    } else {
 2969                        fs.remove_file(&abs_path, options).await?;
 2970                    }
 2971                }
 2972
 2973                lsp::DocumentChangeOperation::Edit(op) => {
 2974                    let buffer_to_edit = this
 2975                        .update(cx, |this, cx| {
 2976                            this.open_local_buffer_via_lsp(
 2977                                op.text_document.uri.clone(),
 2978                                language_server.server_id(),
 2979                                cx,
 2980                            )
 2981                        })?
 2982                        .await?;
 2983
 2984                    let edits = this
 2985                        .update(cx, |this, cx| {
 2986                            let path = buffer_to_edit.read(cx).project_path(cx);
 2987                            let active_entry = this.active_entry;
 2988                            let is_active_entry = path.is_some_and(|project_path| {
 2989                                this.worktree_store
 2990                                    .read(cx)
 2991                                    .entry_for_path(&project_path, cx)
 2992                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2993                            });
 2994                            let local = this.as_local_mut().unwrap();
 2995
 2996                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2997                            for edit in op.edits {
 2998                                match edit {
 2999                                    Edit::Plain(edit) => {
 3000                                        if !edits.contains(&edit) {
 3001                                            edits.push(edit)
 3002                                        }
 3003                                    }
 3004                                    Edit::Annotated(edit) => {
 3005                                        if !edits.contains(&edit.text_edit) {
 3006                                            edits.push(edit.text_edit)
 3007                                        }
 3008                                    }
 3009                                    Edit::Snippet(edit) => {
 3010                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3011                                        else {
 3012                                            continue;
 3013                                        };
 3014
 3015                                        if is_active_entry {
 3016                                            snippet_edits.push((edit.range, snippet));
 3017                                        } else {
 3018                                            // Since this buffer is not focused, apply a normal edit.
 3019                                            let new_edit = TextEdit {
 3020                                                range: edit.range,
 3021                                                new_text: snippet.text,
 3022                                            };
 3023                                            if !edits.contains(&new_edit) {
 3024                                                edits.push(new_edit);
 3025                                            }
 3026                                        }
 3027                                    }
 3028                                }
 3029                            }
 3030                            if !snippet_edits.is_empty() {
 3031                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3032                                let version = if let Some(buffer_version) = op.text_document.version
 3033                                {
 3034                                    local
 3035                                        .buffer_snapshot_for_lsp_version(
 3036                                            &buffer_to_edit,
 3037                                            language_server.server_id(),
 3038                                            Some(buffer_version),
 3039                                            cx,
 3040                                        )
 3041                                        .ok()
 3042                                        .map(|snapshot| snapshot.version)
 3043                                } else {
 3044                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3045                                };
 3046
 3047                                let most_recent_edit =
 3048                                    version.and_then(|version| version.most_recent());
 3049                                // Check if the edit that triggered that edit has been made by this participant.
 3050
 3051                                if let Some(most_recent_edit) = most_recent_edit {
 3052                                    cx.emit(LspStoreEvent::SnippetEdit {
 3053                                        buffer_id,
 3054                                        edits: snippet_edits,
 3055                                        most_recent_edit,
 3056                                    });
 3057                                }
 3058                            }
 3059
 3060                            local.edits_from_lsp(
 3061                                &buffer_to_edit,
 3062                                edits,
 3063                                language_server.server_id(),
 3064                                op.text_document.version,
 3065                                cx,
 3066                            )
 3067                        })?
 3068                        .await?;
 3069
 3070                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3071                        buffer.finalize_last_transaction();
 3072                        buffer.start_transaction();
 3073                        for (range, text) in edits {
 3074                            buffer.edit([(range, text)], None, cx);
 3075                        }
 3076
 3077                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3078                            if push_to_history {
 3079                                buffer.finalize_last_transaction();
 3080                                buffer.get_transaction(transaction_id).cloned()
 3081                            } else {
 3082                                buffer.forget_transaction(transaction_id)
 3083                            }
 3084                        })
 3085                    })?;
 3086                    if let Some(transaction) = transaction {
 3087                        project_transaction.0.insert(buffer_to_edit, transaction);
 3088                    }
 3089                }
 3090            }
 3091        }
 3092
 3093        Ok(project_transaction)
 3094    }
 3095
 3096    async fn on_lsp_workspace_edit(
 3097        this: WeakEntity<LspStore>,
 3098        params: lsp::ApplyWorkspaceEditParams,
 3099        server_id: LanguageServerId,
 3100        cx: &mut AsyncApp,
 3101    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3102        let this = this.upgrade().context("project project closed")?;
 3103        let language_server = this
 3104            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3105            .context("language server not found")?;
 3106        let transaction = Self::deserialize_workspace_edit(
 3107            this.clone(),
 3108            params.edit,
 3109            true,
 3110            language_server.clone(),
 3111            cx,
 3112        )
 3113        .await
 3114        .log_err();
 3115        this.update(cx, |this, _| {
 3116            if let Some(transaction) = transaction {
 3117                this.as_local_mut()
 3118                    .unwrap()
 3119                    .last_workspace_edits_by_language_server
 3120                    .insert(server_id, transaction);
 3121            }
 3122        })?;
 3123        Ok(lsp::ApplyWorkspaceEditResponse {
 3124            applied: true,
 3125            failed_change: None,
 3126            failure_reason: None,
 3127        })
 3128    }
 3129
 3130    fn remove_worktree(
 3131        &mut self,
 3132        id_to_remove: WorktreeId,
 3133        cx: &mut Context<LspStore>,
 3134    ) -> Vec<LanguageServerId> {
 3135        self.diagnostics.remove(&id_to_remove);
 3136        self.prettier_store.update(cx, |prettier_store, cx| {
 3137            prettier_store.remove_worktree(id_to_remove, cx);
 3138        });
 3139
 3140        let mut servers_to_remove = BTreeSet::default();
 3141        let mut servers_to_preserve = HashSet::default();
 3142        for (seed, state) in &self.language_server_ids {
 3143            if seed.worktree_id == id_to_remove {
 3144                servers_to_remove.insert(state.id);
 3145            } else {
 3146                servers_to_preserve.insert(state.id);
 3147            }
 3148        }
 3149        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3150        self.language_server_ids
 3151            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3152        for server_id_to_remove in &servers_to_remove {
 3153            self.language_server_watched_paths
 3154                .remove(server_id_to_remove);
 3155            self.language_server_paths_watched_for_rename
 3156                .remove(server_id_to_remove);
 3157            self.last_workspace_edits_by_language_server
 3158                .remove(server_id_to_remove);
 3159            self.language_servers.remove(server_id_to_remove);
 3160            self.buffer_pull_diagnostics_result_ids
 3161                .remove(server_id_to_remove);
 3162            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3163                buffer_servers.remove(server_id_to_remove);
 3164            }
 3165            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3166        }
 3167        servers_to_remove.into_iter().collect()
 3168    }
 3169
 3170    fn rebuild_watched_paths_inner<'a>(
 3171        &'a self,
 3172        language_server_id: LanguageServerId,
 3173        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3174        cx: &mut Context<LspStore>,
 3175    ) -> LanguageServerWatchedPathsBuilder {
 3176        let worktrees = self
 3177            .worktree_store
 3178            .read(cx)
 3179            .worktrees()
 3180            .filter_map(|worktree| {
 3181                self.language_servers_for_worktree(worktree.read(cx).id())
 3182                    .find(|server| server.server_id() == language_server_id)
 3183                    .map(|_| worktree)
 3184            })
 3185            .collect::<Vec<_>>();
 3186
 3187        let mut worktree_globs = HashMap::default();
 3188        let mut abs_globs = HashMap::default();
 3189        log::trace!(
 3190            "Processing new watcher paths for language server with id {}",
 3191            language_server_id
 3192        );
 3193
 3194        for watcher in watchers {
 3195            if let Some((worktree, literal_prefix, pattern)) =
 3196                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3197            {
 3198                worktree.update(cx, |worktree, _| {
 3199                    if let Some((tree, glob)) =
 3200                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3201                    {
 3202                        tree.add_path_prefix_to_scan(literal_prefix);
 3203                        worktree_globs
 3204                            .entry(tree.id())
 3205                            .or_insert_with(GlobSetBuilder::new)
 3206                            .add(glob);
 3207                    }
 3208                });
 3209            } else {
 3210                let (path, pattern) = match &watcher.glob_pattern {
 3211                    lsp::GlobPattern::String(s) => {
 3212                        let watcher_path = SanitizedPath::new(s);
 3213                        let path = glob_literal_prefix(watcher_path.as_path());
 3214                        let pattern = watcher_path
 3215                            .as_path()
 3216                            .strip_prefix(&path)
 3217                            .map(|p| p.to_string_lossy().into_owned())
 3218                            .unwrap_or_else(|e| {
 3219                                debug_panic!(
 3220                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3221                                    s,
 3222                                    path.display(),
 3223                                    e
 3224                                );
 3225                                watcher_path.as_path().to_string_lossy().into_owned()
 3226                            });
 3227                        (path, pattern)
 3228                    }
 3229                    lsp::GlobPattern::Relative(rp) => {
 3230                        let Ok(mut base_uri) = match &rp.base_uri {
 3231                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3232                            lsp::OneOf::Right(base_uri) => base_uri,
 3233                        }
 3234                        .to_file_path() else {
 3235                            continue;
 3236                        };
 3237
 3238                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3239                        let pattern = Path::new(&rp.pattern)
 3240                            .strip_prefix(&path)
 3241                            .map(|p| p.to_string_lossy().into_owned())
 3242                            .unwrap_or_else(|e| {
 3243                                debug_panic!(
 3244                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3245                                    rp.pattern,
 3246                                    path.display(),
 3247                                    e
 3248                                );
 3249                                rp.pattern.clone()
 3250                            });
 3251                        base_uri.push(path);
 3252                        (base_uri, pattern)
 3253                    }
 3254                };
 3255
 3256                if let Some(glob) = Glob::new(&pattern).log_err() {
 3257                    if !path
 3258                        .components()
 3259                        .any(|c| matches!(c, path::Component::Normal(_)))
 3260                    {
 3261                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3262                        // rather than adding a new watcher for `/`.
 3263                        for worktree in &worktrees {
 3264                            worktree_globs
 3265                                .entry(worktree.read(cx).id())
 3266                                .or_insert_with(GlobSetBuilder::new)
 3267                                .add(glob.clone());
 3268                        }
 3269                    } else {
 3270                        abs_globs
 3271                            .entry(path.into())
 3272                            .or_insert_with(GlobSetBuilder::new)
 3273                            .add(glob);
 3274                    }
 3275                }
 3276            }
 3277        }
 3278
 3279        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3280        for (worktree_id, builder) in worktree_globs {
 3281            if let Ok(globset) = builder.build() {
 3282                watch_builder.watch_worktree(worktree_id, globset);
 3283            }
 3284        }
 3285        for (abs_path, builder) in abs_globs {
 3286            if let Ok(globset) = builder.build() {
 3287                watch_builder.watch_abs_path(abs_path, globset);
 3288            }
 3289        }
 3290        watch_builder
 3291    }
 3292
 3293    fn worktree_and_path_for_file_watcher(
 3294        worktrees: &[Entity<Worktree>],
 3295        watcher: &FileSystemWatcher,
 3296        cx: &App,
 3297    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3298        worktrees.iter().find_map(|worktree| {
 3299            let tree = worktree.read(cx);
 3300            let worktree_root_path = tree.abs_path();
 3301            let path_style = tree.path_style();
 3302            match &watcher.glob_pattern {
 3303                lsp::GlobPattern::String(s) => {
 3304                    let watcher_path = SanitizedPath::new(s);
 3305                    let relative = watcher_path
 3306                        .as_path()
 3307                        .strip_prefix(&worktree_root_path)
 3308                        .ok()?;
 3309                    let literal_prefix = glob_literal_prefix(relative);
 3310                    Some((
 3311                        worktree.clone(),
 3312                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3313                        relative.to_string_lossy().into_owned(),
 3314                    ))
 3315                }
 3316                lsp::GlobPattern::Relative(rp) => {
 3317                    let base_uri = match &rp.base_uri {
 3318                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3319                        lsp::OneOf::Right(base_uri) => base_uri,
 3320                    }
 3321                    .to_file_path()
 3322                    .ok()?;
 3323                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3324                    let mut literal_prefix = relative.to_owned();
 3325                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3326                    Some((
 3327                        worktree.clone(),
 3328                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3329                        rp.pattern.clone(),
 3330                    ))
 3331                }
 3332            }
 3333        })
 3334    }
 3335
 3336    fn rebuild_watched_paths(
 3337        &mut self,
 3338        language_server_id: LanguageServerId,
 3339        cx: &mut Context<LspStore>,
 3340    ) {
 3341        let Some(registrations) = self
 3342            .language_server_dynamic_registrations
 3343            .get(&language_server_id)
 3344        else {
 3345            return;
 3346        };
 3347
 3348        let watch_builder = self.rebuild_watched_paths_inner(
 3349            language_server_id,
 3350            registrations.did_change_watched_files.values().flatten(),
 3351            cx,
 3352        );
 3353        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3354        self.language_server_watched_paths
 3355            .insert(language_server_id, watcher);
 3356
 3357        cx.notify();
 3358    }
 3359
 3360    fn on_lsp_did_change_watched_files(
 3361        &mut self,
 3362        language_server_id: LanguageServerId,
 3363        registration_id: &str,
 3364        params: DidChangeWatchedFilesRegistrationOptions,
 3365        cx: &mut Context<LspStore>,
 3366    ) {
 3367        let registrations = self
 3368            .language_server_dynamic_registrations
 3369            .entry(language_server_id)
 3370            .or_default();
 3371
 3372        registrations
 3373            .did_change_watched_files
 3374            .insert(registration_id.to_string(), params.watchers);
 3375
 3376        self.rebuild_watched_paths(language_server_id, cx);
 3377    }
 3378
 3379    fn on_lsp_unregister_did_change_watched_files(
 3380        &mut self,
 3381        language_server_id: LanguageServerId,
 3382        registration_id: &str,
 3383        cx: &mut Context<LspStore>,
 3384    ) {
 3385        let registrations = self
 3386            .language_server_dynamic_registrations
 3387            .entry(language_server_id)
 3388            .or_default();
 3389
 3390        if registrations
 3391            .did_change_watched_files
 3392            .remove(registration_id)
 3393            .is_some()
 3394        {
 3395            log::info!(
 3396                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3397                language_server_id,
 3398                registration_id
 3399            );
 3400        } else {
 3401            log::warn!(
 3402                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3403                language_server_id,
 3404                registration_id
 3405            );
 3406        }
 3407
 3408        self.rebuild_watched_paths(language_server_id, cx);
 3409    }
 3410
 3411    async fn initialization_options_for_adapter(
 3412        adapter: Arc<dyn LspAdapter>,
 3413        delegate: &Arc<dyn LspAdapterDelegate>,
 3414    ) -> Result<Option<serde_json::Value>> {
 3415        let Some(mut initialization_config) =
 3416            adapter.clone().initialization_options(delegate).await?
 3417        else {
 3418            return Ok(None);
 3419        };
 3420
 3421        for other_adapter in delegate.registered_lsp_adapters() {
 3422            if other_adapter.name() == adapter.name() {
 3423                continue;
 3424            }
 3425            if let Ok(Some(target_config)) = other_adapter
 3426                .clone()
 3427                .additional_initialization_options(adapter.name(), delegate)
 3428                .await
 3429            {
 3430                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3431            }
 3432        }
 3433
 3434        Ok(Some(initialization_config))
 3435    }
 3436
 3437    async fn workspace_configuration_for_adapter(
 3438        adapter: Arc<dyn LspAdapter>,
 3439        delegate: &Arc<dyn LspAdapterDelegate>,
 3440        toolchain: Option<Toolchain>,
 3441        cx: &mut AsyncApp,
 3442    ) -> Result<serde_json::Value> {
 3443        let mut workspace_config = adapter
 3444            .clone()
 3445            .workspace_configuration(delegate, toolchain, cx)
 3446            .await?;
 3447
 3448        for other_adapter in delegate.registered_lsp_adapters() {
 3449            if other_adapter.name() == adapter.name() {
 3450                continue;
 3451            }
 3452            if let Ok(Some(target_config)) = other_adapter
 3453                .clone()
 3454                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3455                .await
 3456            {
 3457                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3458            }
 3459        }
 3460
 3461        Ok(workspace_config)
 3462    }
 3463
 3464    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3465        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3466            Some(server.clone())
 3467        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3468            Some(Arc::clone(server))
 3469        } else {
 3470            None
 3471        }
 3472    }
 3473}
 3474
 3475fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3476    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3477        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3478            language_server_id: server.server_id(),
 3479            name: Some(server.name()),
 3480            message: proto::update_language_server::Variant::MetadataUpdated(
 3481                proto::ServerMetadataUpdated {
 3482                    capabilities: Some(capabilities),
 3483                },
 3484            ),
 3485        });
 3486    }
 3487}
 3488
 3489#[derive(Debug)]
 3490pub struct FormattableBuffer {
 3491    handle: Entity<Buffer>,
 3492    abs_path: Option<PathBuf>,
 3493    env: Option<HashMap<String, String>>,
 3494    ranges: Option<Vec<Range<Anchor>>>,
 3495}
 3496
 3497pub struct RemoteLspStore {
 3498    upstream_client: Option<AnyProtoClient>,
 3499    upstream_project_id: u64,
 3500}
 3501
 3502pub(crate) enum LspStoreMode {
 3503    Local(LocalLspStore),   // ssh host and collab host
 3504    Remote(RemoteLspStore), // collab guest
 3505}
 3506
 3507impl LspStoreMode {
 3508    fn is_local(&self) -> bool {
 3509        matches!(self, LspStoreMode::Local(_))
 3510    }
 3511}
 3512
 3513pub struct LspStore {
 3514    mode: LspStoreMode,
 3515    last_formatting_failure: Option<String>,
 3516    downstream_client: Option<(AnyProtoClient, u64)>,
 3517    nonce: u128,
 3518    buffer_store: Entity<BufferStore>,
 3519    worktree_store: Entity<WorktreeStore>,
 3520    pub languages: Arc<LanguageRegistry>,
 3521    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3522    active_entry: Option<ProjectEntryId>,
 3523    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3524    _maintain_buffer_languages: Task<()>,
 3525    diagnostic_summaries:
 3526        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3527    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3528    lsp_data: HashMap<BufferId, BufferLspData>,
 3529    next_hint_id: Arc<AtomicUsize>,
 3530}
 3531
 3532#[derive(Debug)]
 3533pub struct BufferLspData {
 3534    buffer_version: Global,
 3535    document_colors: Option<DocumentColorData>,
 3536    code_lens: Option<CodeLensData>,
 3537    inlay_hints: BufferInlayHints,
 3538    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3539    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3540}
 3541
 3542#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3543struct LspKey {
 3544    request_type: TypeId,
 3545    server_queried: Option<LanguageServerId>,
 3546}
 3547
 3548impl BufferLspData {
 3549    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3550        Self {
 3551            buffer_version: buffer.read(cx).version(),
 3552            document_colors: None,
 3553            code_lens: None,
 3554            inlay_hints: BufferInlayHints::new(buffer, cx),
 3555            lsp_requests: HashMap::default(),
 3556            chunk_lsp_requests: HashMap::default(),
 3557        }
 3558    }
 3559
 3560    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3561        if let Some(document_colors) = &mut self.document_colors {
 3562            document_colors.colors.remove(&for_server);
 3563            document_colors.cache_version += 1;
 3564        }
 3565
 3566        if let Some(code_lens) = &mut self.code_lens {
 3567            code_lens.lens.remove(&for_server);
 3568        }
 3569
 3570        self.inlay_hints.remove_server_data(for_server);
 3571    }
 3572
 3573    #[cfg(any(test, feature = "test-support"))]
 3574    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3575        &self.inlay_hints
 3576    }
 3577}
 3578
 3579#[derive(Debug, Default, Clone)]
 3580pub struct DocumentColors {
 3581    pub colors: HashSet<DocumentColor>,
 3582    pub cache_version: Option<usize>,
 3583}
 3584
 3585type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3586type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3587
 3588#[derive(Debug, Default)]
 3589struct DocumentColorData {
 3590    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3591    cache_version: usize,
 3592    colors_update: Option<(Global, DocumentColorTask)>,
 3593}
 3594
 3595#[derive(Debug, Default)]
 3596struct CodeLensData {
 3597    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3598    update: Option<(Global, CodeLensTask)>,
 3599}
 3600
 3601#[derive(Debug)]
 3602pub enum LspStoreEvent {
 3603    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3604    LanguageServerRemoved(LanguageServerId),
 3605    LanguageServerUpdate {
 3606        language_server_id: LanguageServerId,
 3607        name: Option<LanguageServerName>,
 3608        message: proto::update_language_server::Variant,
 3609    },
 3610    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3611    LanguageServerPrompt(LanguageServerPromptRequest),
 3612    LanguageDetected {
 3613        buffer: Entity<Buffer>,
 3614        new_language: Option<Arc<Language>>,
 3615    },
 3616    Notification(String),
 3617    RefreshInlayHints(LanguageServerId),
 3618    RefreshCodeLens,
 3619    DiagnosticsUpdated {
 3620        server_id: LanguageServerId,
 3621        paths: Vec<ProjectPath>,
 3622    },
 3623    DiskBasedDiagnosticsStarted {
 3624        language_server_id: LanguageServerId,
 3625    },
 3626    DiskBasedDiagnosticsFinished {
 3627        language_server_id: LanguageServerId,
 3628    },
 3629    SnippetEdit {
 3630        buffer_id: BufferId,
 3631        edits: Vec<(lsp::Range, Snippet)>,
 3632        most_recent_edit: clock::Lamport,
 3633    },
 3634}
 3635
 3636#[derive(Clone, Debug, Serialize)]
 3637pub struct LanguageServerStatus {
 3638    pub name: LanguageServerName,
 3639    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3640    pub has_pending_diagnostic_updates: bool,
 3641    progress_tokens: HashSet<String>,
 3642    pub worktree: Option<WorktreeId>,
 3643}
 3644
 3645#[derive(Clone, Debug)]
 3646struct CoreSymbol {
 3647    pub language_server_name: LanguageServerName,
 3648    pub source_worktree_id: WorktreeId,
 3649    pub source_language_server_id: LanguageServerId,
 3650    pub path: SymbolLocation,
 3651    pub name: String,
 3652    pub kind: lsp::SymbolKind,
 3653    pub range: Range<Unclipped<PointUtf16>>,
 3654}
 3655
 3656#[derive(Clone, Debug, PartialEq, Eq)]
 3657pub enum SymbolLocation {
 3658    InProject(ProjectPath),
 3659    OutsideProject {
 3660        abs_path: Arc<Path>,
 3661        signature: [u8; 32],
 3662    },
 3663}
 3664
 3665impl SymbolLocation {
 3666    fn file_name(&self) -> Option<&str> {
 3667        match self {
 3668            Self::InProject(path) => path.path.file_name(),
 3669            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3670        }
 3671    }
 3672}
 3673
 3674impl LspStore {
 3675    pub fn init(client: &AnyProtoClient) {
 3676        client.add_entity_request_handler(Self::handle_lsp_query);
 3677        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3678        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3679        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3680        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3681        client.add_entity_message_handler(Self::handle_start_language_server);
 3682        client.add_entity_message_handler(Self::handle_update_language_server);
 3683        client.add_entity_message_handler(Self::handle_language_server_log);
 3684        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3685        client.add_entity_request_handler(Self::handle_format_buffers);
 3686        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3687        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3688        client.add_entity_request_handler(Self::handle_apply_code_action);
 3689        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3690        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3691        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3692        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3693        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3694        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3695        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3696        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3697        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3698        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3699        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3700        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3701        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3702        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3703        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3704        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3705        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3706
 3707        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3708        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3709        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3710        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3711        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3712        client.add_entity_request_handler(
 3713            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3714        );
 3715        client.add_entity_request_handler(
 3716            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3717        );
 3718        client.add_entity_request_handler(
 3719            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3720        );
 3721    }
 3722
 3723    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3724        match &self.mode {
 3725            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3726            _ => None,
 3727        }
 3728    }
 3729
 3730    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3731        match &self.mode {
 3732            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3733            _ => None,
 3734        }
 3735    }
 3736
 3737    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3738        match &mut self.mode {
 3739            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3740            _ => None,
 3741        }
 3742    }
 3743
 3744    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3745        match &self.mode {
 3746            LspStoreMode::Remote(RemoteLspStore {
 3747                upstream_client: Some(upstream_client),
 3748                upstream_project_id,
 3749                ..
 3750            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3751
 3752            LspStoreMode::Remote(RemoteLspStore {
 3753                upstream_client: None,
 3754                ..
 3755            }) => None,
 3756            LspStoreMode::Local(_) => None,
 3757        }
 3758    }
 3759
 3760    pub fn new_local(
 3761        buffer_store: Entity<BufferStore>,
 3762        worktree_store: Entity<WorktreeStore>,
 3763        prettier_store: Entity<PrettierStore>,
 3764        toolchain_store: Entity<LocalToolchainStore>,
 3765        environment: Entity<ProjectEnvironment>,
 3766        manifest_tree: Entity<ManifestTree>,
 3767        languages: Arc<LanguageRegistry>,
 3768        http_client: Arc<dyn HttpClient>,
 3769        fs: Arc<dyn Fs>,
 3770        cx: &mut Context<Self>,
 3771    ) -> Self {
 3772        let yarn = YarnPathStore::new(fs.clone(), cx);
 3773        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3774            .detach();
 3775        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3776            .detach();
 3777        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3778            .detach();
 3779        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3780            .detach();
 3781        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3782            .detach();
 3783        subscribe_to_binary_statuses(&languages, cx).detach();
 3784
 3785        let _maintain_workspace_config = {
 3786            let (sender, receiver) = watch::channel();
 3787            (Self::maintain_workspace_config(receiver, cx), sender)
 3788        };
 3789
 3790        Self {
 3791            mode: LspStoreMode::Local(LocalLspStore {
 3792                weak: cx.weak_entity(),
 3793                worktree_store: worktree_store.clone(),
 3794
 3795                supplementary_language_servers: Default::default(),
 3796                languages: languages.clone(),
 3797                language_server_ids: Default::default(),
 3798                language_servers: Default::default(),
 3799                last_workspace_edits_by_language_server: Default::default(),
 3800                language_server_watched_paths: Default::default(),
 3801                language_server_paths_watched_for_rename: Default::default(),
 3802                language_server_dynamic_registrations: Default::default(),
 3803                buffers_being_formatted: Default::default(),
 3804                buffer_snapshots: Default::default(),
 3805                prettier_store,
 3806                environment,
 3807                http_client,
 3808                fs,
 3809                yarn,
 3810                next_diagnostic_group_id: Default::default(),
 3811                diagnostics: Default::default(),
 3812                _subscription: cx.on_app_quit(|this, cx| {
 3813                    this.as_local_mut()
 3814                        .unwrap()
 3815                        .shutdown_language_servers_on_quit(cx)
 3816                }),
 3817                lsp_tree: LanguageServerTree::new(
 3818                    manifest_tree,
 3819                    languages.clone(),
 3820                    toolchain_store.clone(),
 3821                ),
 3822                toolchain_store,
 3823                registered_buffers: HashMap::default(),
 3824                buffers_opened_in_servers: HashMap::default(),
 3825                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3826                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3827                    .manifest_file_names(),
 3828            }),
 3829            last_formatting_failure: None,
 3830            downstream_client: None,
 3831            buffer_store,
 3832            worktree_store,
 3833            languages: languages.clone(),
 3834            language_server_statuses: Default::default(),
 3835            nonce: StdRng::from_os_rng().random(),
 3836            diagnostic_summaries: HashMap::default(),
 3837            lsp_server_capabilities: HashMap::default(),
 3838            lsp_data: HashMap::default(),
 3839            next_hint_id: Arc::default(),
 3840            active_entry: None,
 3841            _maintain_workspace_config,
 3842            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3843        }
 3844    }
 3845
 3846    fn send_lsp_proto_request<R: LspCommand>(
 3847        &self,
 3848        buffer: Entity<Buffer>,
 3849        client: AnyProtoClient,
 3850        upstream_project_id: u64,
 3851        request: R,
 3852        cx: &mut Context<LspStore>,
 3853    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3854        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3855            return Task::ready(Ok(R::Response::default()));
 3856        }
 3857        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3858        cx.spawn(async move |this, cx| {
 3859            let response = client.request(message).await?;
 3860            let this = this.upgrade().context("project dropped")?;
 3861            request
 3862                .response_from_proto(response, this, buffer, cx.clone())
 3863                .await
 3864        })
 3865    }
 3866
 3867    pub(super) fn new_remote(
 3868        buffer_store: Entity<BufferStore>,
 3869        worktree_store: Entity<WorktreeStore>,
 3870        languages: Arc<LanguageRegistry>,
 3871        upstream_client: AnyProtoClient,
 3872        project_id: u64,
 3873        cx: &mut Context<Self>,
 3874    ) -> Self {
 3875        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3876            .detach();
 3877        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3878            .detach();
 3879        subscribe_to_binary_statuses(&languages, cx).detach();
 3880        let _maintain_workspace_config = {
 3881            let (sender, receiver) = watch::channel();
 3882            (Self::maintain_workspace_config(receiver, cx), sender)
 3883        };
 3884        Self {
 3885            mode: LspStoreMode::Remote(RemoteLspStore {
 3886                upstream_client: Some(upstream_client),
 3887                upstream_project_id: project_id,
 3888            }),
 3889            downstream_client: None,
 3890            last_formatting_failure: None,
 3891            buffer_store,
 3892            worktree_store,
 3893            languages: languages.clone(),
 3894            language_server_statuses: Default::default(),
 3895            nonce: StdRng::from_os_rng().random(),
 3896            diagnostic_summaries: HashMap::default(),
 3897            lsp_server_capabilities: HashMap::default(),
 3898            next_hint_id: Arc::default(),
 3899            lsp_data: HashMap::default(),
 3900            active_entry: None,
 3901
 3902            _maintain_workspace_config,
 3903            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3904        }
 3905    }
 3906
 3907    fn on_buffer_store_event(
 3908        &mut self,
 3909        _: Entity<BufferStore>,
 3910        event: &BufferStoreEvent,
 3911        cx: &mut Context<Self>,
 3912    ) {
 3913        match event {
 3914            BufferStoreEvent::BufferAdded(buffer) => {
 3915                self.on_buffer_added(buffer, cx).log_err();
 3916            }
 3917            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3918                let buffer_id = buffer.read(cx).remote_id();
 3919                if let Some(local) = self.as_local_mut()
 3920                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3921                {
 3922                    local.reset_buffer(buffer, old_file, cx);
 3923
 3924                    if local.registered_buffers.contains_key(&buffer_id) {
 3925                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3926                    }
 3927                }
 3928
 3929                self.detect_language_for_buffer(buffer, cx);
 3930                if let Some(local) = self.as_local_mut() {
 3931                    local.initialize_buffer(buffer, cx);
 3932                    if local.registered_buffers.contains_key(&buffer_id) {
 3933                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3934                    }
 3935                }
 3936            }
 3937            _ => {}
 3938        }
 3939    }
 3940
 3941    fn on_worktree_store_event(
 3942        &mut self,
 3943        _: Entity<WorktreeStore>,
 3944        event: &WorktreeStoreEvent,
 3945        cx: &mut Context<Self>,
 3946    ) {
 3947        match event {
 3948            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3949                if !worktree.read(cx).is_local() {
 3950                    return;
 3951                }
 3952                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3953                    worktree::Event::UpdatedEntries(changes) => {
 3954                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3955                    }
 3956                    worktree::Event::UpdatedGitRepositories(_)
 3957                    | worktree::Event::DeletedEntry(_) => {}
 3958                })
 3959                .detach()
 3960            }
 3961            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3962            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3963                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3964            }
 3965            WorktreeStoreEvent::WorktreeReleased(..)
 3966            | WorktreeStoreEvent::WorktreeOrderChanged
 3967            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3968            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3969            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3970        }
 3971    }
 3972
 3973    fn on_prettier_store_event(
 3974        &mut self,
 3975        _: Entity<PrettierStore>,
 3976        event: &PrettierStoreEvent,
 3977        cx: &mut Context<Self>,
 3978    ) {
 3979        match event {
 3980            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3981                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3982            }
 3983            PrettierStoreEvent::LanguageServerAdded {
 3984                new_server_id,
 3985                name,
 3986                prettier_server,
 3987            } => {
 3988                self.register_supplementary_language_server(
 3989                    *new_server_id,
 3990                    name.clone(),
 3991                    prettier_server.clone(),
 3992                    cx,
 3993                );
 3994            }
 3995        }
 3996    }
 3997
 3998    fn on_toolchain_store_event(
 3999        &mut self,
 4000        _: Entity<LocalToolchainStore>,
 4001        event: &ToolchainStoreEvent,
 4002        _: &mut Context<Self>,
 4003    ) {
 4004        if let ToolchainStoreEvent::ToolchainActivated = event {
 4005            self.request_workspace_config_refresh()
 4006        }
 4007    }
 4008
 4009    fn request_workspace_config_refresh(&mut self) {
 4010        *self._maintain_workspace_config.1.borrow_mut() = ();
 4011    }
 4012
 4013    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4014        self.as_local().map(|local| local.prettier_store.clone())
 4015    }
 4016
 4017    fn on_buffer_event(
 4018        &mut self,
 4019        buffer: Entity<Buffer>,
 4020        event: &language::BufferEvent,
 4021        cx: &mut Context<Self>,
 4022    ) {
 4023        match event {
 4024            language::BufferEvent::Edited => {
 4025                self.on_buffer_edited(buffer, cx);
 4026            }
 4027
 4028            language::BufferEvent::Saved => {
 4029                self.on_buffer_saved(buffer, cx);
 4030            }
 4031
 4032            _ => {}
 4033        }
 4034    }
 4035
 4036    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4037        buffer
 4038            .read(cx)
 4039            .set_language_registry(self.languages.clone());
 4040
 4041        cx.subscribe(buffer, |this, buffer, event, cx| {
 4042            this.on_buffer_event(buffer, event, cx);
 4043        })
 4044        .detach();
 4045
 4046        self.detect_language_for_buffer(buffer, cx);
 4047        if let Some(local) = self.as_local_mut() {
 4048            local.initialize_buffer(buffer, cx);
 4049        }
 4050
 4051        Ok(())
 4052    }
 4053
 4054    pub(crate) fn register_buffer_with_language_servers(
 4055        &mut self,
 4056        buffer: &Entity<Buffer>,
 4057        only_register_servers: HashSet<LanguageServerSelector>,
 4058        ignore_refcounts: bool,
 4059        cx: &mut Context<Self>,
 4060    ) -> OpenLspBufferHandle {
 4061        let buffer_id = buffer.read(cx).remote_id();
 4062        let handle = cx.new(|_| buffer.clone());
 4063        if let Some(local) = self.as_local_mut() {
 4064            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4065            if !ignore_refcounts {
 4066                *refcount += 1;
 4067            }
 4068
 4069            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4070            // 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
 4071            // 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
 4072            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4073            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4074                return handle;
 4075            };
 4076            if !file.is_local() {
 4077                return handle;
 4078            }
 4079
 4080            if ignore_refcounts || *refcount == 1 {
 4081                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4082            }
 4083            if !ignore_refcounts {
 4084                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4085                    let refcount = {
 4086                        let local = lsp_store.as_local_mut().unwrap();
 4087                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4088                            debug_panic!("bad refcounting");
 4089                            return;
 4090                        };
 4091
 4092                        *refcount -= 1;
 4093                        *refcount
 4094                    };
 4095                    if refcount == 0 {
 4096                        lsp_store.lsp_data.remove(&buffer_id);
 4097                        let local = lsp_store.as_local_mut().unwrap();
 4098                        local.registered_buffers.remove(&buffer_id);
 4099                        local.buffers_opened_in_servers.remove(&buffer_id);
 4100                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4101                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4102                        }
 4103                    }
 4104                })
 4105                .detach();
 4106            }
 4107        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4108            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4109            cx.background_spawn(async move {
 4110                upstream_client
 4111                    .request(proto::RegisterBufferWithLanguageServers {
 4112                        project_id: upstream_project_id,
 4113                        buffer_id,
 4114                        only_servers: only_register_servers
 4115                            .into_iter()
 4116                            .map(|selector| {
 4117                                let selector = match selector {
 4118                                    LanguageServerSelector::Id(language_server_id) => {
 4119                                        proto::language_server_selector::Selector::ServerId(
 4120                                            language_server_id.to_proto(),
 4121                                        )
 4122                                    }
 4123                                    LanguageServerSelector::Name(language_server_name) => {
 4124                                        proto::language_server_selector::Selector::Name(
 4125                                            language_server_name.to_string(),
 4126                                        )
 4127                                    }
 4128                                };
 4129                                proto::LanguageServerSelector {
 4130                                    selector: Some(selector),
 4131                                }
 4132                            })
 4133                            .collect(),
 4134                    })
 4135                    .await
 4136            })
 4137            .detach();
 4138        } else {
 4139            panic!("oops!");
 4140        }
 4141        handle
 4142    }
 4143
 4144    fn maintain_buffer_languages(
 4145        languages: Arc<LanguageRegistry>,
 4146        cx: &mut Context<Self>,
 4147    ) -> Task<()> {
 4148        let mut subscription = languages.subscribe();
 4149        let mut prev_reload_count = languages.reload_count();
 4150        cx.spawn(async move |this, cx| {
 4151            while let Some(()) = subscription.next().await {
 4152                if let Some(this) = this.upgrade() {
 4153                    // If the language registry has been reloaded, then remove and
 4154                    // re-assign the languages on all open buffers.
 4155                    let reload_count = languages.reload_count();
 4156                    if reload_count > prev_reload_count {
 4157                        prev_reload_count = reload_count;
 4158                        this.update(cx, |this, cx| {
 4159                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4160                                for buffer in buffer_store.buffers() {
 4161                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4162                                    {
 4163                                        buffer
 4164                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4165                                        if let Some(local) = this.as_local_mut() {
 4166                                            local.reset_buffer(&buffer, &f, cx);
 4167
 4168                                            if local
 4169                                                .registered_buffers
 4170                                                .contains_key(&buffer.read(cx).remote_id())
 4171                                                && let Some(file_url) =
 4172                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4173                                            {
 4174                                                local.unregister_buffer_from_language_servers(
 4175                                                    &buffer, &file_url, cx,
 4176                                                );
 4177                                            }
 4178                                        }
 4179                                    }
 4180                                }
 4181                            });
 4182                        })
 4183                        .ok();
 4184                    }
 4185
 4186                    this.update(cx, |this, cx| {
 4187                        let mut plain_text_buffers = Vec::new();
 4188                        let mut buffers_with_unknown_injections = Vec::new();
 4189                        for handle in this.buffer_store.read(cx).buffers() {
 4190                            let buffer = handle.read(cx);
 4191                            if buffer.language().is_none()
 4192                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4193                            {
 4194                                plain_text_buffers.push(handle);
 4195                            } else if buffer.contains_unknown_injections() {
 4196                                buffers_with_unknown_injections.push(handle);
 4197                            }
 4198                        }
 4199
 4200                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4201                        // and reused later in the invisible worktrees.
 4202                        plain_text_buffers.sort_by_key(|buffer| {
 4203                            Reverse(
 4204                                File::from_dyn(buffer.read(cx).file())
 4205                                    .map(|file| file.worktree.read(cx).is_visible()),
 4206                            )
 4207                        });
 4208
 4209                        for buffer in plain_text_buffers {
 4210                            this.detect_language_for_buffer(&buffer, cx);
 4211                            if let Some(local) = this.as_local_mut() {
 4212                                local.initialize_buffer(&buffer, cx);
 4213                                if local
 4214                                    .registered_buffers
 4215                                    .contains_key(&buffer.read(cx).remote_id())
 4216                                {
 4217                                    local.register_buffer_with_language_servers(
 4218                                        &buffer,
 4219                                        HashSet::default(),
 4220                                        cx,
 4221                                    );
 4222                                }
 4223                            }
 4224                        }
 4225
 4226                        for buffer in buffers_with_unknown_injections {
 4227                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4228                        }
 4229                    })
 4230                    .ok();
 4231                }
 4232            }
 4233        })
 4234    }
 4235
 4236    fn detect_language_for_buffer(
 4237        &mut self,
 4238        buffer_handle: &Entity<Buffer>,
 4239        cx: &mut Context<Self>,
 4240    ) -> Option<language::AvailableLanguage> {
 4241        // If the buffer has a language, set it and start the language server if we haven't already.
 4242        let buffer = buffer_handle.read(cx);
 4243        let file = buffer.file()?;
 4244
 4245        let content = buffer.as_rope();
 4246        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4247        if let Some(available_language) = &available_language {
 4248            if let Some(Ok(Ok(new_language))) = self
 4249                .languages
 4250                .load_language(available_language)
 4251                .now_or_never()
 4252            {
 4253                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4254            }
 4255        } else {
 4256            cx.emit(LspStoreEvent::LanguageDetected {
 4257                buffer: buffer_handle.clone(),
 4258                new_language: None,
 4259            });
 4260        }
 4261
 4262        available_language
 4263    }
 4264
 4265    pub(crate) fn set_language_for_buffer(
 4266        &mut self,
 4267        buffer_entity: &Entity<Buffer>,
 4268        new_language: Arc<Language>,
 4269        cx: &mut Context<Self>,
 4270    ) {
 4271        let buffer = buffer_entity.read(cx);
 4272        let buffer_file = buffer.file().cloned();
 4273        let buffer_id = buffer.remote_id();
 4274        if let Some(local_store) = self.as_local_mut()
 4275            && local_store.registered_buffers.contains_key(&buffer_id)
 4276            && let Some(abs_path) =
 4277                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4278            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4279        {
 4280            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4281        }
 4282        buffer_entity.update(cx, |buffer, cx| {
 4283            if buffer
 4284                .language()
 4285                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4286            {
 4287                buffer.set_language(Some(new_language.clone()), cx);
 4288            }
 4289        });
 4290
 4291        let settings =
 4292            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4293        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4294
 4295        let worktree_id = if let Some(file) = buffer_file {
 4296            let worktree = file.worktree.clone();
 4297
 4298            if let Some(local) = self.as_local_mut()
 4299                && local.registered_buffers.contains_key(&buffer_id)
 4300            {
 4301                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4302            }
 4303            Some(worktree.read(cx).id())
 4304        } else {
 4305            None
 4306        };
 4307
 4308        if settings.prettier.allowed
 4309            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4310        {
 4311            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4312            if let Some(prettier_store) = prettier_store {
 4313                prettier_store.update(cx, |prettier_store, cx| {
 4314                    prettier_store.install_default_prettier(
 4315                        worktree_id,
 4316                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4317                        cx,
 4318                    )
 4319                })
 4320            }
 4321        }
 4322
 4323        cx.emit(LspStoreEvent::LanguageDetected {
 4324            buffer: buffer_entity.clone(),
 4325            new_language: Some(new_language),
 4326        })
 4327    }
 4328
 4329    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4330        self.buffer_store.clone()
 4331    }
 4332
 4333    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4334        self.active_entry = active_entry;
 4335    }
 4336
 4337    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4338        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4339            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4340        {
 4341            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4342                summaries
 4343                    .iter()
 4344                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4345            });
 4346            if let Some(summary) = summaries.next() {
 4347                client
 4348                    .send(proto::UpdateDiagnosticSummary {
 4349                        project_id: downstream_project_id,
 4350                        worktree_id: worktree.id().to_proto(),
 4351                        summary: Some(summary),
 4352                        more_summaries: summaries.collect(),
 4353                    })
 4354                    .log_err();
 4355            }
 4356        }
 4357    }
 4358
 4359    fn is_capable_for_proto_request<R>(
 4360        &self,
 4361        buffer: &Entity<Buffer>,
 4362        request: &R,
 4363        cx: &App,
 4364    ) -> bool
 4365    where
 4366        R: LspCommand,
 4367    {
 4368        self.check_if_capable_for_proto_request(
 4369            buffer,
 4370            |capabilities| {
 4371                request.check_capabilities(AdapterServerCapabilities {
 4372                    server_capabilities: capabilities.clone(),
 4373                    code_action_kinds: None,
 4374                })
 4375            },
 4376            cx,
 4377        )
 4378    }
 4379
 4380    fn check_if_capable_for_proto_request<F>(
 4381        &self,
 4382        buffer: &Entity<Buffer>,
 4383        check: F,
 4384        cx: &App,
 4385    ) -> bool
 4386    where
 4387        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4388    {
 4389        let Some(language) = buffer.read(cx).language().cloned() else {
 4390            return false;
 4391        };
 4392        let relevant_language_servers = self
 4393            .languages
 4394            .lsp_adapters(&language.name())
 4395            .into_iter()
 4396            .map(|lsp_adapter| lsp_adapter.name())
 4397            .collect::<HashSet<_>>();
 4398        self.language_server_statuses
 4399            .iter()
 4400            .filter_map(|(server_id, server_status)| {
 4401                relevant_language_servers
 4402                    .contains(&server_status.name)
 4403                    .then_some(server_id)
 4404            })
 4405            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4406            .any(check)
 4407    }
 4408
 4409    pub fn request_lsp<R>(
 4410        &mut self,
 4411        buffer: Entity<Buffer>,
 4412        server: LanguageServerToQuery,
 4413        request: R,
 4414        cx: &mut Context<Self>,
 4415    ) -> Task<Result<R::Response>>
 4416    where
 4417        R: LspCommand,
 4418        <R::LspRequest as lsp::request::Request>::Result: Send,
 4419        <R::LspRequest as lsp::request::Request>::Params: Send,
 4420    {
 4421        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4422            return self.send_lsp_proto_request(
 4423                buffer,
 4424                upstream_client,
 4425                upstream_project_id,
 4426                request,
 4427                cx,
 4428            );
 4429        }
 4430
 4431        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4432            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4433                local
 4434                    .language_servers_for_buffer(buffer, cx)
 4435                    .find(|(_, server)| {
 4436                        request.check_capabilities(server.adapter_server_capabilities())
 4437                    })
 4438                    .map(|(_, server)| server.clone())
 4439            }),
 4440            LanguageServerToQuery::Other(id) => self
 4441                .language_server_for_local_buffer(buffer, id, cx)
 4442                .and_then(|(_, server)| {
 4443                    request
 4444                        .check_capabilities(server.adapter_server_capabilities())
 4445                        .then(|| Arc::clone(server))
 4446                }),
 4447        }) else {
 4448            return Task::ready(Ok(Default::default()));
 4449        };
 4450
 4451        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4452
 4453        let Some(file) = file else {
 4454            return Task::ready(Ok(Default::default()));
 4455        };
 4456
 4457        let lsp_params = match request.to_lsp_params_or_response(
 4458            &file.abs_path(cx),
 4459            buffer.read(cx),
 4460            &language_server,
 4461            cx,
 4462        ) {
 4463            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4464            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4465
 4466            Err(err) => {
 4467                let message = format!(
 4468                    "{} via {} failed: {}",
 4469                    request.display_name(),
 4470                    language_server.name(),
 4471                    err
 4472                );
 4473                log::warn!("{message}");
 4474                return Task::ready(Err(anyhow!(message)));
 4475            }
 4476        };
 4477
 4478        let status = request.status();
 4479        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4480            return Task::ready(Ok(Default::default()));
 4481        }
 4482        cx.spawn(async move |this, cx| {
 4483            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4484
 4485            let id = lsp_request.id();
 4486            let _cleanup = if status.is_some() {
 4487                cx.update(|cx| {
 4488                    this.update(cx, |this, cx| {
 4489                        this.on_lsp_work_start(
 4490                            language_server.server_id(),
 4491                            id.to_string(),
 4492                            LanguageServerProgress {
 4493                                is_disk_based_diagnostics_progress: false,
 4494                                is_cancellable: false,
 4495                                title: None,
 4496                                message: status.clone(),
 4497                                percentage: None,
 4498                                last_update_at: cx.background_executor().now(),
 4499                            },
 4500                            cx,
 4501                        );
 4502                    })
 4503                })
 4504                .log_err();
 4505
 4506                Some(defer(|| {
 4507                    cx.update(|cx| {
 4508                        this.update(cx, |this, cx| {
 4509                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4510                        })
 4511                    })
 4512                    .log_err();
 4513                }))
 4514            } else {
 4515                None
 4516            };
 4517
 4518            let result = lsp_request.await.into_response();
 4519
 4520            let response = result.map_err(|err| {
 4521                let message = format!(
 4522                    "{} via {} failed: {}",
 4523                    request.display_name(),
 4524                    language_server.name(),
 4525                    err
 4526                );
 4527                log::warn!("{message}");
 4528                anyhow::anyhow!(message)
 4529            })?;
 4530
 4531            request
 4532                .response_from_lsp(
 4533                    response,
 4534                    this.upgrade().context("no app context")?,
 4535                    buffer,
 4536                    language_server.server_id(),
 4537                    cx.clone(),
 4538                )
 4539                .await
 4540        })
 4541    }
 4542
 4543    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4544        let mut language_formatters_to_check = Vec::new();
 4545        for buffer in self.buffer_store.read(cx).buffers() {
 4546            let buffer = buffer.read(cx);
 4547            let buffer_file = File::from_dyn(buffer.file());
 4548            let buffer_language = buffer.language();
 4549            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4550            if buffer_language.is_some() {
 4551                language_formatters_to_check.push((
 4552                    buffer_file.map(|f| f.worktree_id(cx)),
 4553                    settings.into_owned(),
 4554                ));
 4555            }
 4556        }
 4557
 4558        self.request_workspace_config_refresh();
 4559
 4560        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4561            prettier_store.update(cx, |prettier_store, cx| {
 4562                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4563            })
 4564        }
 4565
 4566        cx.notify();
 4567    }
 4568
 4569    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4570        let buffer_store = self.buffer_store.clone();
 4571        let Some(local) = self.as_local_mut() else {
 4572            return;
 4573        };
 4574        let mut adapters = BTreeMap::default();
 4575        let get_adapter = {
 4576            let languages = local.languages.clone();
 4577            let environment = local.environment.clone();
 4578            let weak = local.weak.clone();
 4579            let worktree_store = local.worktree_store.clone();
 4580            let http_client = local.http_client.clone();
 4581            let fs = local.fs.clone();
 4582            move |worktree_id, cx: &mut App| {
 4583                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4584                Some(LocalLspAdapterDelegate::new(
 4585                    languages.clone(),
 4586                    &environment,
 4587                    weak.clone(),
 4588                    &worktree,
 4589                    http_client.clone(),
 4590                    fs.clone(),
 4591                    cx,
 4592                ))
 4593            }
 4594        };
 4595
 4596        let mut messages_to_report = Vec::new();
 4597        let (new_tree, to_stop) = {
 4598            let mut rebase = local.lsp_tree.rebase();
 4599            let buffers = buffer_store
 4600                .read(cx)
 4601                .buffers()
 4602                .filter_map(|buffer| {
 4603                    let raw_buffer = buffer.read(cx);
 4604                    if !local
 4605                        .registered_buffers
 4606                        .contains_key(&raw_buffer.remote_id())
 4607                    {
 4608                        return None;
 4609                    }
 4610                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4611                    let language = raw_buffer.language().cloned()?;
 4612                    Some((file, language, raw_buffer.remote_id()))
 4613                })
 4614                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4615            for (file, language, buffer_id) in buffers {
 4616                let worktree_id = file.worktree_id(cx);
 4617                let Some(worktree) = local
 4618                    .worktree_store
 4619                    .read(cx)
 4620                    .worktree_for_id(worktree_id, cx)
 4621                else {
 4622                    continue;
 4623                };
 4624
 4625                if let Some((_, apply)) = local.reuse_existing_language_server(
 4626                    rebase.server_tree(),
 4627                    &worktree,
 4628                    &language.name(),
 4629                    cx,
 4630                ) {
 4631                    (apply)(rebase.server_tree());
 4632                } else if let Some(lsp_delegate) = adapters
 4633                    .entry(worktree_id)
 4634                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4635                    .clone()
 4636                {
 4637                    let delegate =
 4638                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4639                    let path = file
 4640                        .path()
 4641                        .parent()
 4642                        .map(Arc::from)
 4643                        .unwrap_or_else(|| file.path().clone());
 4644                    let worktree_path = ProjectPath { worktree_id, path };
 4645                    let abs_path = file.abs_path(cx);
 4646                    let nodes = rebase
 4647                        .walk(
 4648                            worktree_path,
 4649                            language.name(),
 4650                            language.manifest(),
 4651                            delegate.clone(),
 4652                            cx,
 4653                        )
 4654                        .collect::<Vec<_>>();
 4655                    for node in nodes {
 4656                        let server_id = node.server_id_or_init(|disposition| {
 4657                            let path = &disposition.path;
 4658                            let absolute_path = worktree.read(cx).absolutize(&path.path);
 4659                            let uri = absolute_path
 4660                                .is_dir()
 4661                                .then(|| Uri::from_file_path(absolute_path))
 4662                                .transpose();
 4663                            let key = LanguageServerSeed {
 4664                                worktree_id,
 4665                                name: disposition.server_name.clone(),
 4666                                settings: disposition.settings.clone(),
 4667                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4668                                    path.worktree_id,
 4669                                    &path.path,
 4670                                    language.name(),
 4671                                ),
 4672                            };
 4673                            local.language_server_ids.remove(&key);
 4674
 4675                            let server_id = local.get_or_insert_language_server(
 4676                                &worktree,
 4677                                lsp_delegate.clone(),
 4678                                disposition,
 4679                                &language.name(),
 4680                                cx,
 4681                            );
 4682                            if let Some(state) = local.language_servers.get(&server_id)
 4683                                && let Ok(Some(uri)) = uri
 4684                            {
 4685                                state.add_workspace_folder(uri);
 4686                            };
 4687                            server_id
 4688                        });
 4689
 4690                        if let Some(language_server_id) = server_id {
 4691                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4692                                language_server_id,
 4693                                name: node.name(),
 4694                                message:
 4695                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4696                                        proto::RegisteredForBuffer {
 4697                                            buffer_abs_path: abs_path
 4698                                                .to_string_lossy()
 4699                                                .into_owned(),
 4700                                            buffer_id: buffer_id.to_proto(),
 4701                                        },
 4702                                    ),
 4703                            });
 4704                        }
 4705                    }
 4706                } else {
 4707                    continue;
 4708                }
 4709            }
 4710            rebase.finish()
 4711        };
 4712        for message in messages_to_report {
 4713            cx.emit(message);
 4714        }
 4715        local.lsp_tree = new_tree;
 4716        for (id, _) in to_stop {
 4717            self.stop_local_language_server(id, cx).detach();
 4718        }
 4719    }
 4720
 4721    pub fn apply_code_action(
 4722        &self,
 4723        buffer_handle: Entity<Buffer>,
 4724        mut action: CodeAction,
 4725        push_to_history: bool,
 4726        cx: &mut Context<Self>,
 4727    ) -> Task<Result<ProjectTransaction>> {
 4728        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4729            let request = proto::ApplyCodeAction {
 4730                project_id,
 4731                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4732                action: Some(Self::serialize_code_action(&action)),
 4733            };
 4734            let buffer_store = self.buffer_store();
 4735            cx.spawn(async move |_, cx| {
 4736                let response = upstream_client
 4737                    .request(request)
 4738                    .await?
 4739                    .transaction
 4740                    .context("missing transaction")?;
 4741
 4742                buffer_store
 4743                    .update(cx, |buffer_store, cx| {
 4744                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4745                    })?
 4746                    .await
 4747            })
 4748        } else if self.mode.is_local() {
 4749            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4750                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4751                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4752            }) else {
 4753                return Task::ready(Ok(ProjectTransaction::default()));
 4754            };
 4755            cx.spawn(async move |this,  cx| {
 4756                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4757                    .await
 4758                    .context("resolving a code action")?;
 4759                if let Some(edit) = action.lsp_action.edit()
 4760                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4761                        return LocalLspStore::deserialize_workspace_edit(
 4762                            this.upgrade().context("no app present")?,
 4763                            edit.clone(),
 4764                            push_to_history,
 4765
 4766                            lang_server.clone(),
 4767                            cx,
 4768                        )
 4769                        .await;
 4770                    }
 4771
 4772                if let Some(command) = action.lsp_action.command() {
 4773                    let server_capabilities = lang_server.capabilities();
 4774                    let available_commands = server_capabilities
 4775                        .execute_command_provider
 4776                        .as_ref()
 4777                        .map(|options| options.commands.as_slice())
 4778                        .unwrap_or_default();
 4779                    if available_commands.contains(&command.command) {
 4780                        this.update(cx, |this, _| {
 4781                            this.as_local_mut()
 4782                                .unwrap()
 4783                                .last_workspace_edits_by_language_server
 4784                                .remove(&lang_server.server_id());
 4785                        })?;
 4786
 4787                        let _result = lang_server
 4788                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4789                                command: command.command.clone(),
 4790                                arguments: command.arguments.clone().unwrap_or_default(),
 4791                                ..lsp::ExecuteCommandParams::default()
 4792                            })
 4793                            .await.into_response()
 4794                            .context("execute command")?;
 4795
 4796                        return this.update(cx, |this, _| {
 4797                            this.as_local_mut()
 4798                                .unwrap()
 4799                                .last_workspace_edits_by_language_server
 4800                                .remove(&lang_server.server_id())
 4801                                .unwrap_or_default()
 4802                        });
 4803                    } else {
 4804                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4805                    }
 4806                }
 4807
 4808                Ok(ProjectTransaction::default())
 4809            })
 4810        } else {
 4811            Task::ready(Err(anyhow!("no upstream client and not local")))
 4812        }
 4813    }
 4814
 4815    pub fn apply_code_action_kind(
 4816        &mut self,
 4817        buffers: HashSet<Entity<Buffer>>,
 4818        kind: CodeActionKind,
 4819        push_to_history: bool,
 4820        cx: &mut Context<Self>,
 4821    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4822        if self.as_local().is_some() {
 4823            cx.spawn(async move |lsp_store, cx| {
 4824                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4825                let result = LocalLspStore::execute_code_action_kind_locally(
 4826                    lsp_store.clone(),
 4827                    buffers,
 4828                    kind,
 4829                    push_to_history,
 4830                    cx,
 4831                )
 4832                .await;
 4833                lsp_store.update(cx, |lsp_store, _| {
 4834                    lsp_store.update_last_formatting_failure(&result);
 4835                })?;
 4836                result
 4837            })
 4838        } else if let Some((client, project_id)) = self.upstream_client() {
 4839            let buffer_store = self.buffer_store();
 4840            cx.spawn(async move |lsp_store, cx| {
 4841                let result = client
 4842                    .request(proto::ApplyCodeActionKind {
 4843                        project_id,
 4844                        kind: kind.as_str().to_owned(),
 4845                        buffer_ids: buffers
 4846                            .iter()
 4847                            .map(|buffer| {
 4848                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4849                            })
 4850                            .collect::<Result<_>>()?,
 4851                    })
 4852                    .await
 4853                    .and_then(|result| result.transaction.context("missing transaction"));
 4854                lsp_store.update(cx, |lsp_store, _| {
 4855                    lsp_store.update_last_formatting_failure(&result);
 4856                })?;
 4857
 4858                let transaction_response = result?;
 4859                buffer_store
 4860                    .update(cx, |buffer_store, cx| {
 4861                        buffer_store.deserialize_project_transaction(
 4862                            transaction_response,
 4863                            push_to_history,
 4864                            cx,
 4865                        )
 4866                    })?
 4867                    .await
 4868            })
 4869        } else {
 4870            Task::ready(Ok(ProjectTransaction::default()))
 4871        }
 4872    }
 4873
 4874    pub fn resolved_hint(
 4875        &mut self,
 4876        buffer_id: BufferId,
 4877        id: InlayId,
 4878        cx: &mut Context<Self>,
 4879    ) -> Option<ResolvedHint> {
 4880        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4881
 4882        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4883        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4884        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4885        let (server_id, resolve_data) = match &hint.resolve_state {
 4886            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4887            ResolveState::Resolving => {
 4888                return Some(ResolvedHint::Resolving(
 4889                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4890                ));
 4891            }
 4892            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4893        };
 4894
 4895        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4896        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4897        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4898            id,
 4899            cx.spawn(async move |lsp_store, cx| {
 4900                let resolved_hint = resolve_task.await;
 4901                lsp_store
 4902                    .update(cx, |lsp_store, _| {
 4903                        if let Some(old_inlay_hint) = lsp_store
 4904                            .lsp_data
 4905                            .get_mut(&buffer_id)
 4906                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4907                        {
 4908                            match resolved_hint {
 4909                                Ok(resolved_hint) => {
 4910                                    *old_inlay_hint = resolved_hint;
 4911                                }
 4912                                Err(e) => {
 4913                                    old_inlay_hint.resolve_state =
 4914                                        ResolveState::CanResolve(server_id, resolve_data);
 4915                                    log::error!("Inlay hint resolve failed: {e:#}");
 4916                                }
 4917                            }
 4918                        }
 4919                    })
 4920                    .ok();
 4921            })
 4922            .shared(),
 4923        );
 4924        debug_assert!(
 4925            previous_task.is_none(),
 4926            "Did not change hint's resolve state after spawning its resolve"
 4927        );
 4928        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4929        None
 4930    }
 4931
 4932    fn resolve_inlay_hint(
 4933        &self,
 4934        mut hint: InlayHint,
 4935        buffer: Entity<Buffer>,
 4936        server_id: LanguageServerId,
 4937        cx: &mut Context<Self>,
 4938    ) -> Task<anyhow::Result<InlayHint>> {
 4939        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4940            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4941            {
 4942                hint.resolve_state = ResolveState::Resolved;
 4943                return Task::ready(Ok(hint));
 4944            }
 4945            let request = proto::ResolveInlayHint {
 4946                project_id,
 4947                buffer_id: buffer.read(cx).remote_id().into(),
 4948                language_server_id: server_id.0 as u64,
 4949                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4950            };
 4951            cx.background_spawn(async move {
 4952                let response = upstream_client
 4953                    .request(request)
 4954                    .await
 4955                    .context("inlay hints proto request")?;
 4956                match response.hint {
 4957                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4958                        .context("inlay hints proto resolve response conversion"),
 4959                    None => Ok(hint),
 4960                }
 4961            })
 4962        } else {
 4963            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4964                self.language_server_for_local_buffer(buffer, server_id, cx)
 4965                    .map(|(_, server)| server.clone())
 4966            }) else {
 4967                return Task::ready(Ok(hint));
 4968            };
 4969            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4970                return Task::ready(Ok(hint));
 4971            }
 4972            let buffer_snapshot = buffer.read(cx).snapshot();
 4973            cx.spawn(async move |_, cx| {
 4974                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4975                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4976                );
 4977                let resolved_hint = resolve_task
 4978                    .await
 4979                    .into_response()
 4980                    .context("inlay hint resolve LSP request")?;
 4981                let resolved_hint = InlayHints::lsp_to_project_hint(
 4982                    resolved_hint,
 4983                    &buffer,
 4984                    server_id,
 4985                    ResolveState::Resolved,
 4986                    false,
 4987                    cx,
 4988                )
 4989                .await?;
 4990                Ok(resolved_hint)
 4991            })
 4992        }
 4993    }
 4994
 4995    pub fn resolve_color_presentation(
 4996        &mut self,
 4997        mut color: DocumentColor,
 4998        buffer: Entity<Buffer>,
 4999        server_id: LanguageServerId,
 5000        cx: &mut Context<Self>,
 5001    ) -> Task<Result<DocumentColor>> {
 5002        if color.resolved {
 5003            return Task::ready(Ok(color));
 5004        }
 5005
 5006        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5007            let start = color.lsp_range.start;
 5008            let end = color.lsp_range.end;
 5009            let request = proto::GetColorPresentation {
 5010                project_id,
 5011                server_id: server_id.to_proto(),
 5012                buffer_id: buffer.read(cx).remote_id().into(),
 5013                color: Some(proto::ColorInformation {
 5014                    red: color.color.red,
 5015                    green: color.color.green,
 5016                    blue: color.color.blue,
 5017                    alpha: color.color.alpha,
 5018                    lsp_range_start: Some(proto::PointUtf16 {
 5019                        row: start.line,
 5020                        column: start.character,
 5021                    }),
 5022                    lsp_range_end: Some(proto::PointUtf16 {
 5023                        row: end.line,
 5024                        column: end.character,
 5025                    }),
 5026                }),
 5027            };
 5028            cx.background_spawn(async move {
 5029                let response = upstream_client
 5030                    .request(request)
 5031                    .await
 5032                    .context("color presentation proto request")?;
 5033                color.resolved = true;
 5034                color.color_presentations = response
 5035                    .presentations
 5036                    .into_iter()
 5037                    .map(|presentation| ColorPresentation {
 5038                        label: SharedString::from(presentation.label),
 5039                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5040                        additional_text_edits: presentation
 5041                            .additional_text_edits
 5042                            .into_iter()
 5043                            .filter_map(deserialize_lsp_edit)
 5044                            .collect(),
 5045                    })
 5046                    .collect();
 5047                Ok(color)
 5048            })
 5049        } else {
 5050            let path = match buffer
 5051                .update(cx, |buffer, cx| {
 5052                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5053                })
 5054                .context("buffer with the missing path")
 5055            {
 5056                Ok(path) => path,
 5057                Err(e) => return Task::ready(Err(e)),
 5058            };
 5059            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5060                self.language_server_for_local_buffer(buffer, server_id, cx)
 5061                    .map(|(_, server)| server.clone())
 5062            }) else {
 5063                return Task::ready(Ok(color));
 5064            };
 5065            cx.background_spawn(async move {
 5066                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5067                    lsp::ColorPresentationParams {
 5068                        text_document: make_text_document_identifier(&path)?,
 5069                        color: color.color,
 5070                        range: color.lsp_range,
 5071                        work_done_progress_params: Default::default(),
 5072                        partial_result_params: Default::default(),
 5073                    },
 5074                );
 5075                color.color_presentations = resolve_task
 5076                    .await
 5077                    .into_response()
 5078                    .context("color presentation resolve LSP request")?
 5079                    .into_iter()
 5080                    .map(|presentation| ColorPresentation {
 5081                        label: SharedString::from(presentation.label),
 5082                        text_edit: presentation.text_edit,
 5083                        additional_text_edits: presentation
 5084                            .additional_text_edits
 5085                            .unwrap_or_default(),
 5086                    })
 5087                    .collect();
 5088                color.resolved = true;
 5089                Ok(color)
 5090            })
 5091        }
 5092    }
 5093
 5094    pub(crate) fn linked_edits(
 5095        &mut self,
 5096        buffer: &Entity<Buffer>,
 5097        position: Anchor,
 5098        cx: &mut Context<Self>,
 5099    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5100        let snapshot = buffer.read(cx).snapshot();
 5101        let scope = snapshot.language_scope_at(position);
 5102        let Some(server_id) = self
 5103            .as_local()
 5104            .and_then(|local| {
 5105                buffer.update(cx, |buffer, cx| {
 5106                    local
 5107                        .language_servers_for_buffer(buffer, cx)
 5108                        .filter(|(_, server)| {
 5109                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5110                        })
 5111                        .filter(|(adapter, _)| {
 5112                            scope
 5113                                .as_ref()
 5114                                .map(|scope| scope.language_allowed(&adapter.name))
 5115                                .unwrap_or(true)
 5116                        })
 5117                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5118                        .next()
 5119                })
 5120            })
 5121            .or_else(|| {
 5122                self.upstream_client()
 5123                    .is_some()
 5124                    .then_some(LanguageServerToQuery::FirstCapable)
 5125            })
 5126            .filter(|_| {
 5127                maybe!({
 5128                    let language = buffer.read(cx).language_at(position)?;
 5129                    Some(
 5130                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5131                            .linked_edits,
 5132                    )
 5133                }) == Some(true)
 5134            })
 5135        else {
 5136            return Task::ready(Ok(Vec::new()));
 5137        };
 5138
 5139        self.request_lsp(
 5140            buffer.clone(),
 5141            server_id,
 5142            LinkedEditingRange { position },
 5143            cx,
 5144        )
 5145    }
 5146
 5147    fn apply_on_type_formatting(
 5148        &mut self,
 5149        buffer: Entity<Buffer>,
 5150        position: Anchor,
 5151        trigger: String,
 5152        cx: &mut Context<Self>,
 5153    ) -> Task<Result<Option<Transaction>>> {
 5154        if let Some((client, project_id)) = self.upstream_client() {
 5155            if !self.check_if_capable_for_proto_request(
 5156                &buffer,
 5157                |capabilities| {
 5158                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5159                },
 5160                cx,
 5161            ) {
 5162                return Task::ready(Ok(None));
 5163            }
 5164            let request = proto::OnTypeFormatting {
 5165                project_id,
 5166                buffer_id: buffer.read(cx).remote_id().into(),
 5167                position: Some(serialize_anchor(&position)),
 5168                trigger,
 5169                version: serialize_version(&buffer.read(cx).version()),
 5170            };
 5171            cx.background_spawn(async move {
 5172                client
 5173                    .request(request)
 5174                    .await?
 5175                    .transaction
 5176                    .map(language::proto::deserialize_transaction)
 5177                    .transpose()
 5178            })
 5179        } else if let Some(local) = self.as_local_mut() {
 5180            let buffer_id = buffer.read(cx).remote_id();
 5181            local.buffers_being_formatted.insert(buffer_id);
 5182            cx.spawn(async move |this, cx| {
 5183                let _cleanup = defer({
 5184                    let this = this.clone();
 5185                    let mut cx = cx.clone();
 5186                    move || {
 5187                        this.update(&mut cx, |this, _| {
 5188                            if let Some(local) = this.as_local_mut() {
 5189                                local.buffers_being_formatted.remove(&buffer_id);
 5190                            }
 5191                        })
 5192                        .ok();
 5193                    }
 5194                });
 5195
 5196                buffer
 5197                    .update(cx, |buffer, _| {
 5198                        buffer.wait_for_edits(Some(position.timestamp))
 5199                    })?
 5200                    .await?;
 5201                this.update(cx, |this, cx| {
 5202                    let position = position.to_point_utf16(buffer.read(cx));
 5203                    this.on_type_format(buffer, position, trigger, false, cx)
 5204                })?
 5205                .await
 5206            })
 5207        } else {
 5208            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5209        }
 5210    }
 5211
 5212    pub fn on_type_format<T: ToPointUtf16>(
 5213        &mut self,
 5214        buffer: Entity<Buffer>,
 5215        position: T,
 5216        trigger: String,
 5217        push_to_history: bool,
 5218        cx: &mut Context<Self>,
 5219    ) -> Task<Result<Option<Transaction>>> {
 5220        let position = position.to_point_utf16(buffer.read(cx));
 5221        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5222    }
 5223
 5224    fn on_type_format_impl(
 5225        &mut self,
 5226        buffer: Entity<Buffer>,
 5227        position: PointUtf16,
 5228        trigger: String,
 5229        push_to_history: bool,
 5230        cx: &mut Context<Self>,
 5231    ) -> Task<Result<Option<Transaction>>> {
 5232        let options = buffer.update(cx, |buffer, cx| {
 5233            lsp_command::lsp_formatting_options(
 5234                language_settings(
 5235                    buffer.language_at(position).map(|l| l.name()),
 5236                    buffer.file(),
 5237                    cx,
 5238                )
 5239                .as_ref(),
 5240            )
 5241        });
 5242
 5243        cx.spawn(async move |this, cx| {
 5244            if let Some(waiter) =
 5245                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5246            {
 5247                waiter.await?;
 5248            }
 5249            cx.update(|cx| {
 5250                this.update(cx, |this, cx| {
 5251                    this.request_lsp(
 5252                        buffer.clone(),
 5253                        LanguageServerToQuery::FirstCapable,
 5254                        OnTypeFormatting {
 5255                            position,
 5256                            trigger,
 5257                            options,
 5258                            push_to_history,
 5259                        },
 5260                        cx,
 5261                    )
 5262                })
 5263            })??
 5264            .await
 5265        })
 5266    }
 5267
 5268    pub fn definitions(
 5269        &mut self,
 5270        buffer: &Entity<Buffer>,
 5271        position: PointUtf16,
 5272        cx: &mut Context<Self>,
 5273    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5274        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5275            let request = GetDefinitions { position };
 5276            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5277                return Task::ready(Ok(None));
 5278            }
 5279            let request_task = upstream_client.request_lsp(
 5280                project_id,
 5281                None,
 5282                LSP_REQUEST_TIMEOUT,
 5283                cx.background_executor().clone(),
 5284                request.to_proto(project_id, buffer.read(cx)),
 5285            );
 5286            let buffer = buffer.clone();
 5287            cx.spawn(async move |weak_project, cx| {
 5288                let Some(project) = weak_project.upgrade() else {
 5289                    return Ok(None);
 5290                };
 5291                let Some(responses) = request_task.await? else {
 5292                    return Ok(None);
 5293                };
 5294                let actions = join_all(responses.payload.into_iter().map(|response| {
 5295                    GetDefinitions { position }.response_from_proto(
 5296                        response.response,
 5297                        project.clone(),
 5298                        buffer.clone(),
 5299                        cx.clone(),
 5300                    )
 5301                }))
 5302                .await;
 5303
 5304                Ok(Some(
 5305                    actions
 5306                        .into_iter()
 5307                        .collect::<Result<Vec<Vec<_>>>>()?
 5308                        .into_iter()
 5309                        .flatten()
 5310                        .dedup()
 5311                        .collect(),
 5312                ))
 5313            })
 5314        } else {
 5315            let definitions_task = self.request_multiple_lsp_locally(
 5316                buffer,
 5317                Some(position),
 5318                GetDefinitions { position },
 5319                cx,
 5320            );
 5321            cx.background_spawn(async move {
 5322                Ok(Some(
 5323                    definitions_task
 5324                        .await
 5325                        .into_iter()
 5326                        .flat_map(|(_, definitions)| definitions)
 5327                        .dedup()
 5328                        .collect(),
 5329                ))
 5330            })
 5331        }
 5332    }
 5333
 5334    pub fn declarations(
 5335        &mut self,
 5336        buffer: &Entity<Buffer>,
 5337        position: PointUtf16,
 5338        cx: &mut Context<Self>,
 5339    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5340        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5341            let request = GetDeclarations { position };
 5342            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5343                return Task::ready(Ok(None));
 5344            }
 5345            let request_task = upstream_client.request_lsp(
 5346                project_id,
 5347                None,
 5348                LSP_REQUEST_TIMEOUT,
 5349                cx.background_executor().clone(),
 5350                request.to_proto(project_id, buffer.read(cx)),
 5351            );
 5352            let buffer = buffer.clone();
 5353            cx.spawn(async move |weak_project, cx| {
 5354                let Some(project) = weak_project.upgrade() else {
 5355                    return Ok(None);
 5356                };
 5357                let Some(responses) = request_task.await? else {
 5358                    return Ok(None);
 5359                };
 5360                let actions = join_all(responses.payload.into_iter().map(|response| {
 5361                    GetDeclarations { position }.response_from_proto(
 5362                        response.response,
 5363                        project.clone(),
 5364                        buffer.clone(),
 5365                        cx.clone(),
 5366                    )
 5367                }))
 5368                .await;
 5369
 5370                Ok(Some(
 5371                    actions
 5372                        .into_iter()
 5373                        .collect::<Result<Vec<Vec<_>>>>()?
 5374                        .into_iter()
 5375                        .flatten()
 5376                        .dedup()
 5377                        .collect(),
 5378                ))
 5379            })
 5380        } else {
 5381            let declarations_task = self.request_multiple_lsp_locally(
 5382                buffer,
 5383                Some(position),
 5384                GetDeclarations { position },
 5385                cx,
 5386            );
 5387            cx.background_spawn(async move {
 5388                Ok(Some(
 5389                    declarations_task
 5390                        .await
 5391                        .into_iter()
 5392                        .flat_map(|(_, declarations)| declarations)
 5393                        .dedup()
 5394                        .collect(),
 5395                ))
 5396            })
 5397        }
 5398    }
 5399
 5400    pub fn type_definitions(
 5401        &mut self,
 5402        buffer: &Entity<Buffer>,
 5403        position: PointUtf16,
 5404        cx: &mut Context<Self>,
 5405    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5406        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5407            let request = GetTypeDefinitions { position };
 5408            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5409                return Task::ready(Ok(None));
 5410            }
 5411            let request_task = upstream_client.request_lsp(
 5412                project_id,
 5413                None,
 5414                LSP_REQUEST_TIMEOUT,
 5415                cx.background_executor().clone(),
 5416                request.to_proto(project_id, buffer.read(cx)),
 5417            );
 5418            let buffer = buffer.clone();
 5419            cx.spawn(async move |weak_project, cx| {
 5420                let Some(project) = weak_project.upgrade() else {
 5421                    return Ok(None);
 5422                };
 5423                let Some(responses) = request_task.await? else {
 5424                    return Ok(None);
 5425                };
 5426                let actions = join_all(responses.payload.into_iter().map(|response| {
 5427                    GetTypeDefinitions { position }.response_from_proto(
 5428                        response.response,
 5429                        project.clone(),
 5430                        buffer.clone(),
 5431                        cx.clone(),
 5432                    )
 5433                }))
 5434                .await;
 5435
 5436                Ok(Some(
 5437                    actions
 5438                        .into_iter()
 5439                        .collect::<Result<Vec<Vec<_>>>>()?
 5440                        .into_iter()
 5441                        .flatten()
 5442                        .dedup()
 5443                        .collect(),
 5444                ))
 5445            })
 5446        } else {
 5447            let type_definitions_task = self.request_multiple_lsp_locally(
 5448                buffer,
 5449                Some(position),
 5450                GetTypeDefinitions { position },
 5451                cx,
 5452            );
 5453            cx.background_spawn(async move {
 5454                Ok(Some(
 5455                    type_definitions_task
 5456                        .await
 5457                        .into_iter()
 5458                        .flat_map(|(_, type_definitions)| type_definitions)
 5459                        .dedup()
 5460                        .collect(),
 5461                ))
 5462            })
 5463        }
 5464    }
 5465
 5466    pub fn implementations(
 5467        &mut self,
 5468        buffer: &Entity<Buffer>,
 5469        position: PointUtf16,
 5470        cx: &mut Context<Self>,
 5471    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5472        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5473            let request = GetImplementations { position };
 5474            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5475                return Task::ready(Ok(None));
 5476            }
 5477            let request_task = upstream_client.request_lsp(
 5478                project_id,
 5479                None,
 5480                LSP_REQUEST_TIMEOUT,
 5481                cx.background_executor().clone(),
 5482                request.to_proto(project_id, buffer.read(cx)),
 5483            );
 5484            let buffer = buffer.clone();
 5485            cx.spawn(async move |weak_project, cx| {
 5486                let Some(project) = weak_project.upgrade() else {
 5487                    return Ok(None);
 5488                };
 5489                let Some(responses) = request_task.await? else {
 5490                    return Ok(None);
 5491                };
 5492                let actions = join_all(responses.payload.into_iter().map(|response| {
 5493                    GetImplementations { position }.response_from_proto(
 5494                        response.response,
 5495                        project.clone(),
 5496                        buffer.clone(),
 5497                        cx.clone(),
 5498                    )
 5499                }))
 5500                .await;
 5501
 5502                Ok(Some(
 5503                    actions
 5504                        .into_iter()
 5505                        .collect::<Result<Vec<Vec<_>>>>()?
 5506                        .into_iter()
 5507                        .flatten()
 5508                        .dedup()
 5509                        .collect(),
 5510                ))
 5511            })
 5512        } else {
 5513            let implementations_task = self.request_multiple_lsp_locally(
 5514                buffer,
 5515                Some(position),
 5516                GetImplementations { position },
 5517                cx,
 5518            );
 5519            cx.background_spawn(async move {
 5520                Ok(Some(
 5521                    implementations_task
 5522                        .await
 5523                        .into_iter()
 5524                        .flat_map(|(_, implementations)| implementations)
 5525                        .dedup()
 5526                        .collect(),
 5527                ))
 5528            })
 5529        }
 5530    }
 5531
 5532    pub fn references(
 5533        &mut self,
 5534        buffer: &Entity<Buffer>,
 5535        position: PointUtf16,
 5536        cx: &mut Context<Self>,
 5537    ) -> Task<Result<Option<Vec<Location>>>> {
 5538        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5539            let request = GetReferences { position };
 5540            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5541                return Task::ready(Ok(None));
 5542            }
 5543
 5544            let request_task = upstream_client.request_lsp(
 5545                project_id,
 5546                None,
 5547                LSP_REQUEST_TIMEOUT,
 5548                cx.background_executor().clone(),
 5549                request.to_proto(project_id, buffer.read(cx)),
 5550            );
 5551            let buffer = buffer.clone();
 5552            cx.spawn(async move |weak_project, cx| {
 5553                let Some(project) = weak_project.upgrade() else {
 5554                    return Ok(None);
 5555                };
 5556                let Some(responses) = request_task.await? else {
 5557                    return Ok(None);
 5558                };
 5559
 5560                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5561                    GetReferences { position }.response_from_proto(
 5562                        lsp_response.response,
 5563                        project.clone(),
 5564                        buffer.clone(),
 5565                        cx.clone(),
 5566                    )
 5567                }))
 5568                .await
 5569                .into_iter()
 5570                .collect::<Result<Vec<Vec<_>>>>()?
 5571                .into_iter()
 5572                .flatten()
 5573                .dedup()
 5574                .collect();
 5575                Ok(Some(locations))
 5576            })
 5577        } else {
 5578            let references_task = self.request_multiple_lsp_locally(
 5579                buffer,
 5580                Some(position),
 5581                GetReferences { position },
 5582                cx,
 5583            );
 5584            cx.background_spawn(async move {
 5585                Ok(Some(
 5586                    references_task
 5587                        .await
 5588                        .into_iter()
 5589                        .flat_map(|(_, references)| references)
 5590                        .dedup()
 5591                        .collect(),
 5592                ))
 5593            })
 5594        }
 5595    }
 5596
 5597    pub fn code_actions(
 5598        &mut self,
 5599        buffer: &Entity<Buffer>,
 5600        range: Range<Anchor>,
 5601        kinds: Option<Vec<CodeActionKind>>,
 5602        cx: &mut Context<Self>,
 5603    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5604        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5605            let request = GetCodeActions {
 5606                range: range.clone(),
 5607                kinds: kinds.clone(),
 5608            };
 5609            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5610                return Task::ready(Ok(None));
 5611            }
 5612            let request_task = upstream_client.request_lsp(
 5613                project_id,
 5614                None,
 5615                LSP_REQUEST_TIMEOUT,
 5616                cx.background_executor().clone(),
 5617                request.to_proto(project_id, buffer.read(cx)),
 5618            );
 5619            let buffer = buffer.clone();
 5620            cx.spawn(async move |weak_project, cx| {
 5621                let Some(project) = weak_project.upgrade() else {
 5622                    return Ok(None);
 5623                };
 5624                let Some(responses) = request_task.await? else {
 5625                    return Ok(None);
 5626                };
 5627                let actions = join_all(responses.payload.into_iter().map(|response| {
 5628                    GetCodeActions {
 5629                        range: range.clone(),
 5630                        kinds: kinds.clone(),
 5631                    }
 5632                    .response_from_proto(
 5633                        response.response,
 5634                        project.clone(),
 5635                        buffer.clone(),
 5636                        cx.clone(),
 5637                    )
 5638                }))
 5639                .await;
 5640
 5641                Ok(Some(
 5642                    actions
 5643                        .into_iter()
 5644                        .collect::<Result<Vec<Vec<_>>>>()?
 5645                        .into_iter()
 5646                        .flatten()
 5647                        .collect(),
 5648                ))
 5649            })
 5650        } else {
 5651            let all_actions_task = self.request_multiple_lsp_locally(
 5652                buffer,
 5653                Some(range.start),
 5654                GetCodeActions { range, kinds },
 5655                cx,
 5656            );
 5657            cx.background_spawn(async move {
 5658                Ok(Some(
 5659                    all_actions_task
 5660                        .await
 5661                        .into_iter()
 5662                        .flat_map(|(_, actions)| actions)
 5663                        .collect(),
 5664                ))
 5665            })
 5666        }
 5667    }
 5668
 5669    pub fn code_lens_actions(
 5670        &mut self,
 5671        buffer: &Entity<Buffer>,
 5672        cx: &mut Context<Self>,
 5673    ) -> CodeLensTask {
 5674        let version_queried_for = buffer.read(cx).version();
 5675        let buffer_id = buffer.read(cx).remote_id();
 5676        let existing_servers = self.as_local().map(|local| {
 5677            local
 5678                .buffers_opened_in_servers
 5679                .get(&buffer_id)
 5680                .cloned()
 5681                .unwrap_or_default()
 5682        });
 5683
 5684        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5685            if let Some(cached_lens) = &lsp_data.code_lens {
 5686                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5687                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5688                        existing_servers != cached_lens.lens.keys().copied().collect()
 5689                    });
 5690                    if !has_different_servers {
 5691                        return Task::ready(Ok(Some(
 5692                            cached_lens.lens.values().flatten().cloned().collect(),
 5693                        )))
 5694                        .shared();
 5695                    }
 5696                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5697                    if !version_queried_for.changed_since(updating_for) {
 5698                        return running_update.clone();
 5699                    }
 5700                }
 5701            }
 5702        }
 5703
 5704        let lens_lsp_data = self
 5705            .latest_lsp_data(buffer, cx)
 5706            .code_lens
 5707            .get_or_insert_default();
 5708        let buffer = buffer.clone();
 5709        let query_version_queried_for = version_queried_for.clone();
 5710        let new_task = cx
 5711            .spawn(async move |lsp_store, cx| {
 5712                cx.background_executor()
 5713                    .timer(Duration::from_millis(30))
 5714                    .await;
 5715                let fetched_lens = lsp_store
 5716                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5717                    .map_err(Arc::new)?
 5718                    .await
 5719                    .context("fetching code lens")
 5720                    .map_err(Arc::new);
 5721                let fetched_lens = match fetched_lens {
 5722                    Ok(fetched_lens) => fetched_lens,
 5723                    Err(e) => {
 5724                        lsp_store
 5725                            .update(cx, |lsp_store, _| {
 5726                                if let Some(lens_lsp_data) = lsp_store
 5727                                    .lsp_data
 5728                                    .get_mut(&buffer_id)
 5729                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5730                                {
 5731                                    lens_lsp_data.update = None;
 5732                                }
 5733                            })
 5734                            .ok();
 5735                        return Err(e);
 5736                    }
 5737                };
 5738
 5739                lsp_store
 5740                    .update(cx, |lsp_store, _| {
 5741                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5742                        let code_lens = lsp_data.code_lens.as_mut()?;
 5743                        if let Some(fetched_lens) = fetched_lens {
 5744                            if lsp_data.buffer_version == query_version_queried_for {
 5745                                code_lens.lens.extend(fetched_lens);
 5746                            } else if !lsp_data
 5747                                .buffer_version
 5748                                .changed_since(&query_version_queried_for)
 5749                            {
 5750                                lsp_data.buffer_version = query_version_queried_for;
 5751                                code_lens.lens = fetched_lens;
 5752                            }
 5753                        }
 5754                        code_lens.update = None;
 5755                        Some(code_lens.lens.values().flatten().cloned().collect())
 5756                    })
 5757                    .map_err(Arc::new)
 5758            })
 5759            .shared();
 5760        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5761        new_task
 5762    }
 5763
 5764    fn fetch_code_lens(
 5765        &mut self,
 5766        buffer: &Entity<Buffer>,
 5767        cx: &mut Context<Self>,
 5768    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5769        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5770            let request = GetCodeLens;
 5771            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5772                return Task::ready(Ok(None));
 5773            }
 5774            let request_task = upstream_client.request_lsp(
 5775                project_id,
 5776                None,
 5777                LSP_REQUEST_TIMEOUT,
 5778                cx.background_executor().clone(),
 5779                request.to_proto(project_id, buffer.read(cx)),
 5780            );
 5781            let buffer = buffer.clone();
 5782            cx.spawn(async move |weak_lsp_store, cx| {
 5783                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5784                    return Ok(None);
 5785                };
 5786                let Some(responses) = request_task.await? else {
 5787                    return Ok(None);
 5788                };
 5789
 5790                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5791                    let lsp_store = lsp_store.clone();
 5792                    let buffer = buffer.clone();
 5793                    let cx = cx.clone();
 5794                    async move {
 5795                        (
 5796                            LanguageServerId::from_proto(response.server_id),
 5797                            GetCodeLens
 5798                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5799                                .await,
 5800                        )
 5801                    }
 5802                }))
 5803                .await;
 5804
 5805                let mut has_errors = false;
 5806                let code_lens_actions = code_lens_actions
 5807                    .into_iter()
 5808                    .filter_map(|(server_id, code_lens)| match code_lens {
 5809                        Ok(code_lens) => Some((server_id, code_lens)),
 5810                        Err(e) => {
 5811                            has_errors = true;
 5812                            log::error!("{e:#}");
 5813                            None
 5814                        }
 5815                    })
 5816                    .collect::<HashMap<_, _>>();
 5817                anyhow::ensure!(
 5818                    !has_errors || !code_lens_actions.is_empty(),
 5819                    "Failed to fetch code lens"
 5820                );
 5821                Ok(Some(code_lens_actions))
 5822            })
 5823        } else {
 5824            let code_lens_actions_task =
 5825                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5826            cx.background_spawn(async move {
 5827                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5828            })
 5829        }
 5830    }
 5831
 5832    #[inline(never)]
 5833    pub fn completions(
 5834        &self,
 5835        buffer: &Entity<Buffer>,
 5836        position: PointUtf16,
 5837        context: CompletionContext,
 5838        cx: &mut Context<Self>,
 5839    ) -> Task<Result<Vec<CompletionResponse>>> {
 5840        let language_registry = self.languages.clone();
 5841
 5842        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5843            let request = GetCompletions { position, context };
 5844            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5845                return Task::ready(Ok(Vec::new()));
 5846            }
 5847            let task = self.send_lsp_proto_request(
 5848                buffer.clone(),
 5849                upstream_client,
 5850                project_id,
 5851                request,
 5852                cx,
 5853            );
 5854            let language = buffer.read(cx).language().cloned();
 5855
 5856            // In the future, we should provide project guests with the names of LSP adapters,
 5857            // so that they can use the correct LSP adapter when computing labels. For now,
 5858            // guests just use the first LSP adapter associated with the buffer's language.
 5859            let lsp_adapter = language.as_ref().and_then(|language| {
 5860                language_registry
 5861                    .lsp_adapters(&language.name())
 5862                    .first()
 5863                    .cloned()
 5864            });
 5865
 5866            cx.foreground_executor().spawn(async move {
 5867                let completion_response = task.await?;
 5868                let completions = populate_labels_for_completions(
 5869                    completion_response.completions,
 5870                    language,
 5871                    lsp_adapter,
 5872                )
 5873                .await;
 5874                Ok(vec![CompletionResponse {
 5875                    completions,
 5876                    display_options: CompletionDisplayOptions::default(),
 5877                    is_incomplete: completion_response.is_incomplete,
 5878                }])
 5879            })
 5880        } else if let Some(local) = self.as_local() {
 5881            let snapshot = buffer.read(cx).snapshot();
 5882            let offset = position.to_offset(&snapshot);
 5883            let scope = snapshot.language_scope_at(offset);
 5884            let language = snapshot.language().cloned();
 5885            let completion_settings = language_settings(
 5886                language.as_ref().map(|language| language.name()),
 5887                buffer.read(cx).file(),
 5888                cx,
 5889            )
 5890            .completions
 5891            .clone();
 5892            if !completion_settings.lsp {
 5893                return Task::ready(Ok(Vec::new()));
 5894            }
 5895
 5896            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5897                local
 5898                    .language_servers_for_buffer(buffer, cx)
 5899                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5900                    .filter(|(adapter, _)| {
 5901                        scope
 5902                            .as_ref()
 5903                            .map(|scope| scope.language_allowed(&adapter.name))
 5904                            .unwrap_or(true)
 5905                    })
 5906                    .map(|(_, server)| server.server_id())
 5907                    .collect()
 5908            });
 5909
 5910            let buffer = buffer.clone();
 5911            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5912            let lsp_timeout = if lsp_timeout > 0 {
 5913                Some(Duration::from_millis(lsp_timeout))
 5914            } else {
 5915                None
 5916            };
 5917            cx.spawn(async move |this,  cx| {
 5918                let mut tasks = Vec::with_capacity(server_ids.len());
 5919                this.update(cx, |lsp_store, cx| {
 5920                    for server_id in server_ids {
 5921                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5922                        let lsp_timeout = lsp_timeout
 5923                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5924                        let mut timeout = cx.background_spawn(async move {
 5925                            match lsp_timeout {
 5926                                Some(lsp_timeout) => {
 5927                                    lsp_timeout.await;
 5928                                    true
 5929                                },
 5930                                None => false,
 5931                            }
 5932                        }).fuse();
 5933                        let mut lsp_request = lsp_store.request_lsp(
 5934                            buffer.clone(),
 5935                            LanguageServerToQuery::Other(server_id),
 5936                            GetCompletions {
 5937                                position,
 5938                                context: context.clone(),
 5939                            },
 5940                            cx,
 5941                        ).fuse();
 5942                        let new_task = cx.background_spawn(async move {
 5943                            select_biased! {
 5944                                response = lsp_request => anyhow::Ok(Some(response?)),
 5945                                timeout_happened = timeout => {
 5946                                    if timeout_happened {
 5947                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5948                                        Ok(None)
 5949                                    } else {
 5950                                        let completions = lsp_request.await?;
 5951                                        Ok(Some(completions))
 5952                                    }
 5953                                },
 5954                            }
 5955                        });
 5956                        tasks.push((lsp_adapter, new_task));
 5957                    }
 5958                })?;
 5959
 5960                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5961                    let completion_response = task.await.ok()??;
 5962                    let completions = populate_labels_for_completions(
 5963                            completion_response.completions,
 5964                            language.clone(),
 5965                            lsp_adapter,
 5966                        )
 5967                        .await;
 5968                    Some(CompletionResponse {
 5969                        completions,
 5970                        display_options: CompletionDisplayOptions::default(),
 5971                        is_incomplete: completion_response.is_incomplete,
 5972                    })
 5973                });
 5974
 5975                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5976
 5977                Ok(responses.into_iter().flatten().collect())
 5978            })
 5979        } else {
 5980            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5981        }
 5982    }
 5983
 5984    pub fn resolve_completions(
 5985        &self,
 5986        buffer: Entity<Buffer>,
 5987        completion_indices: Vec<usize>,
 5988        completions: Rc<RefCell<Box<[Completion]>>>,
 5989        cx: &mut Context<Self>,
 5990    ) -> Task<Result<bool>> {
 5991        let client = self.upstream_client();
 5992        let buffer_id = buffer.read(cx).remote_id();
 5993        let buffer_snapshot = buffer.read(cx).snapshot();
 5994
 5995        if !self.check_if_capable_for_proto_request(
 5996            &buffer,
 5997            GetCompletions::can_resolve_completions,
 5998            cx,
 5999        ) {
 6000            return Task::ready(Ok(false));
 6001        }
 6002        cx.spawn(async move |lsp_store, cx| {
 6003            let mut did_resolve = false;
 6004            if let Some((client, project_id)) = client {
 6005                for completion_index in completion_indices {
 6006                    let server_id = {
 6007                        let completion = &completions.borrow()[completion_index];
 6008                        completion.source.server_id()
 6009                    };
 6010                    if let Some(server_id) = server_id {
 6011                        if Self::resolve_completion_remote(
 6012                            project_id,
 6013                            server_id,
 6014                            buffer_id,
 6015                            completions.clone(),
 6016                            completion_index,
 6017                            client.clone(),
 6018                        )
 6019                        .await
 6020                        .log_err()
 6021                        .is_some()
 6022                        {
 6023                            did_resolve = true;
 6024                        }
 6025                    } else {
 6026                        resolve_word_completion(
 6027                            &buffer_snapshot,
 6028                            &mut completions.borrow_mut()[completion_index],
 6029                        );
 6030                    }
 6031                }
 6032            } else {
 6033                for completion_index in completion_indices {
 6034                    let server_id = {
 6035                        let completion = &completions.borrow()[completion_index];
 6036                        completion.source.server_id()
 6037                    };
 6038                    if let Some(server_id) = server_id {
 6039                        let server_and_adapter = lsp_store
 6040                            .read_with(cx, |lsp_store, _| {
 6041                                let server = lsp_store.language_server_for_id(server_id)?;
 6042                                let adapter =
 6043                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6044                                Some((server, adapter))
 6045                            })
 6046                            .ok()
 6047                            .flatten();
 6048                        let Some((server, adapter)) = server_and_adapter else {
 6049                            continue;
 6050                        };
 6051
 6052                        let resolved = Self::resolve_completion_local(
 6053                            server,
 6054                            completions.clone(),
 6055                            completion_index,
 6056                        )
 6057                        .await
 6058                        .log_err()
 6059                        .is_some();
 6060                        if resolved {
 6061                            Self::regenerate_completion_labels(
 6062                                adapter,
 6063                                &buffer_snapshot,
 6064                                completions.clone(),
 6065                                completion_index,
 6066                            )
 6067                            .await
 6068                            .log_err();
 6069                            did_resolve = true;
 6070                        }
 6071                    } else {
 6072                        resolve_word_completion(
 6073                            &buffer_snapshot,
 6074                            &mut completions.borrow_mut()[completion_index],
 6075                        );
 6076                    }
 6077                }
 6078            }
 6079
 6080            Ok(did_resolve)
 6081        })
 6082    }
 6083
 6084    async fn resolve_completion_local(
 6085        server: Arc<lsp::LanguageServer>,
 6086        completions: Rc<RefCell<Box<[Completion]>>>,
 6087        completion_index: usize,
 6088    ) -> Result<()> {
 6089        let server_id = server.server_id();
 6090        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6091            return Ok(());
 6092        }
 6093
 6094        let request = {
 6095            let completion = &completions.borrow()[completion_index];
 6096            match &completion.source {
 6097                CompletionSource::Lsp {
 6098                    lsp_completion,
 6099                    resolved,
 6100                    server_id: completion_server_id,
 6101                    ..
 6102                } => {
 6103                    if *resolved {
 6104                        return Ok(());
 6105                    }
 6106                    anyhow::ensure!(
 6107                        server_id == *completion_server_id,
 6108                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6109                    );
 6110                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6111                }
 6112                CompletionSource::BufferWord { .. }
 6113                | CompletionSource::Dap { .. }
 6114                | CompletionSource::Custom => {
 6115                    return Ok(());
 6116                }
 6117            }
 6118        };
 6119        let resolved_completion = request
 6120            .await
 6121            .into_response()
 6122            .context("resolve completion")?;
 6123
 6124        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6125        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6126
 6127        let mut completions = completions.borrow_mut();
 6128        let completion = &mut completions[completion_index];
 6129        if let CompletionSource::Lsp {
 6130            lsp_completion,
 6131            resolved,
 6132            server_id: completion_server_id,
 6133            ..
 6134        } = &mut completion.source
 6135        {
 6136            if *resolved {
 6137                return Ok(());
 6138            }
 6139            anyhow::ensure!(
 6140                server_id == *completion_server_id,
 6141                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6142            );
 6143            *lsp_completion = Box::new(resolved_completion);
 6144            *resolved = true;
 6145        }
 6146        Ok(())
 6147    }
 6148
 6149    async fn regenerate_completion_labels(
 6150        adapter: Arc<CachedLspAdapter>,
 6151        snapshot: &BufferSnapshot,
 6152        completions: Rc<RefCell<Box<[Completion]>>>,
 6153        completion_index: usize,
 6154    ) -> Result<()> {
 6155        let completion_item = completions.borrow()[completion_index]
 6156            .source
 6157            .lsp_completion(true)
 6158            .map(Cow::into_owned);
 6159        if let Some(lsp_documentation) = completion_item
 6160            .as_ref()
 6161            .and_then(|completion_item| completion_item.documentation.clone())
 6162        {
 6163            let mut completions = completions.borrow_mut();
 6164            let completion = &mut completions[completion_index];
 6165            completion.documentation = Some(lsp_documentation.into());
 6166        } else {
 6167            let mut completions = completions.borrow_mut();
 6168            let completion = &mut completions[completion_index];
 6169            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6170        }
 6171
 6172        let mut new_label = match completion_item {
 6173            Some(completion_item) => {
 6174                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6175                // So we have to update the label here anyway...
 6176                let language = snapshot.language();
 6177                match language {
 6178                    Some(language) => {
 6179                        adapter
 6180                            .labels_for_completions(
 6181                                std::slice::from_ref(&completion_item),
 6182                                language,
 6183                            )
 6184                            .await?
 6185                    }
 6186                    None => Vec::new(),
 6187                }
 6188                .pop()
 6189                .flatten()
 6190                .unwrap_or_else(|| {
 6191                    CodeLabel::fallback_for_completion(
 6192                        &completion_item,
 6193                        language.map(|language| language.as_ref()),
 6194                    )
 6195                })
 6196            }
 6197            None => CodeLabel::plain(
 6198                completions.borrow()[completion_index].new_text.clone(),
 6199                None,
 6200            ),
 6201        };
 6202        ensure_uniform_list_compatible_label(&mut new_label);
 6203
 6204        let mut completions = completions.borrow_mut();
 6205        let completion = &mut completions[completion_index];
 6206        if completion.label.filter_text() == new_label.filter_text() {
 6207            completion.label = new_label;
 6208        } else {
 6209            log::error!(
 6210                "Resolved completion changed display label from {} to {}. \
 6211                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6212                completion.label.text(),
 6213                new_label.text(),
 6214                completion.label.filter_text(),
 6215                new_label.filter_text()
 6216            );
 6217        }
 6218
 6219        Ok(())
 6220    }
 6221
 6222    async fn resolve_completion_remote(
 6223        project_id: u64,
 6224        server_id: LanguageServerId,
 6225        buffer_id: BufferId,
 6226        completions: Rc<RefCell<Box<[Completion]>>>,
 6227        completion_index: usize,
 6228        client: AnyProtoClient,
 6229    ) -> Result<()> {
 6230        let lsp_completion = {
 6231            let completion = &completions.borrow()[completion_index];
 6232            match &completion.source {
 6233                CompletionSource::Lsp {
 6234                    lsp_completion,
 6235                    resolved,
 6236                    server_id: completion_server_id,
 6237                    ..
 6238                } => {
 6239                    anyhow::ensure!(
 6240                        server_id == *completion_server_id,
 6241                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6242                    );
 6243                    if *resolved {
 6244                        return Ok(());
 6245                    }
 6246                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6247                }
 6248                CompletionSource::Custom
 6249                | CompletionSource::Dap { .. }
 6250                | CompletionSource::BufferWord { .. } => {
 6251                    return Ok(());
 6252                }
 6253            }
 6254        };
 6255        let request = proto::ResolveCompletionDocumentation {
 6256            project_id,
 6257            language_server_id: server_id.0 as u64,
 6258            lsp_completion,
 6259            buffer_id: buffer_id.into(),
 6260        };
 6261
 6262        let response = client
 6263            .request(request)
 6264            .await
 6265            .context("completion documentation resolve proto request")?;
 6266        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6267
 6268        let documentation = if response.documentation.is_empty() {
 6269            CompletionDocumentation::Undocumented
 6270        } else if response.documentation_is_markdown {
 6271            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6272        } else if response.documentation.lines().count() <= 1 {
 6273            CompletionDocumentation::SingleLine(response.documentation.into())
 6274        } else {
 6275            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6276        };
 6277
 6278        let mut completions = completions.borrow_mut();
 6279        let completion = &mut completions[completion_index];
 6280        completion.documentation = Some(documentation);
 6281        if let CompletionSource::Lsp {
 6282            insert_range,
 6283            lsp_completion,
 6284            resolved,
 6285            server_id: completion_server_id,
 6286            lsp_defaults: _,
 6287        } = &mut completion.source
 6288        {
 6289            let completion_insert_range = response
 6290                .old_insert_start
 6291                .and_then(deserialize_anchor)
 6292                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6293            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6294
 6295            if *resolved {
 6296                return Ok(());
 6297            }
 6298            anyhow::ensure!(
 6299                server_id == *completion_server_id,
 6300                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6301            );
 6302            *lsp_completion = Box::new(resolved_lsp_completion);
 6303            *resolved = true;
 6304        }
 6305
 6306        let replace_range = response
 6307            .old_replace_start
 6308            .and_then(deserialize_anchor)
 6309            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6310        if let Some((old_replace_start, old_replace_end)) = replace_range
 6311            && !response.new_text.is_empty()
 6312        {
 6313            completion.new_text = response.new_text;
 6314            completion.replace_range = old_replace_start..old_replace_end;
 6315        }
 6316
 6317        Ok(())
 6318    }
 6319
 6320    pub fn apply_additional_edits_for_completion(
 6321        &self,
 6322        buffer_handle: Entity<Buffer>,
 6323        completions: Rc<RefCell<Box<[Completion]>>>,
 6324        completion_index: usize,
 6325        push_to_history: bool,
 6326        cx: &mut Context<Self>,
 6327    ) -> Task<Result<Option<Transaction>>> {
 6328        if let Some((client, project_id)) = self.upstream_client() {
 6329            let buffer = buffer_handle.read(cx);
 6330            let buffer_id = buffer.remote_id();
 6331            cx.spawn(async move |_, cx| {
 6332                let request = {
 6333                    let completion = completions.borrow()[completion_index].clone();
 6334                    proto::ApplyCompletionAdditionalEdits {
 6335                        project_id,
 6336                        buffer_id: buffer_id.into(),
 6337                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6338                            replace_range: completion.replace_range,
 6339                            new_text: completion.new_text,
 6340                            source: completion.source,
 6341                        })),
 6342                    }
 6343                };
 6344
 6345                if let Some(transaction) = client.request(request).await?.transaction {
 6346                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6347                    buffer_handle
 6348                        .update(cx, |buffer, _| {
 6349                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6350                        })?
 6351                        .await?;
 6352                    if push_to_history {
 6353                        buffer_handle.update(cx, |buffer, _| {
 6354                            buffer.push_transaction(transaction.clone(), Instant::now());
 6355                            buffer.finalize_last_transaction();
 6356                        })?;
 6357                    }
 6358                    Ok(Some(transaction))
 6359                } else {
 6360                    Ok(None)
 6361                }
 6362            })
 6363        } else {
 6364            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6365                let completion = &completions.borrow()[completion_index];
 6366                let server_id = completion.source.server_id()?;
 6367                Some(
 6368                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6369                        .1
 6370                        .clone(),
 6371                )
 6372            }) else {
 6373                return Task::ready(Ok(None));
 6374            };
 6375
 6376            cx.spawn(async move |this, cx| {
 6377                Self::resolve_completion_local(
 6378                    server.clone(),
 6379                    completions.clone(),
 6380                    completion_index,
 6381                )
 6382                .await
 6383                .context("resolving completion")?;
 6384                let completion = completions.borrow()[completion_index].clone();
 6385                let additional_text_edits = completion
 6386                    .source
 6387                    .lsp_completion(true)
 6388                    .as_ref()
 6389                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6390                if let Some(edits) = additional_text_edits {
 6391                    let edits = this
 6392                        .update(cx, |this, cx| {
 6393                            this.as_local_mut().unwrap().edits_from_lsp(
 6394                                &buffer_handle,
 6395                                edits,
 6396                                server.server_id(),
 6397                                None,
 6398                                cx,
 6399                            )
 6400                        })?
 6401                        .await?;
 6402
 6403                    buffer_handle.update(cx, |buffer, cx| {
 6404                        buffer.finalize_last_transaction();
 6405                        buffer.start_transaction();
 6406
 6407                        for (range, text) in edits {
 6408                            let primary = &completion.replace_range;
 6409
 6410                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6411                            // and the primary completion is just an insertion (empty range), then this is likely
 6412                            // an auto-import scenario and should not be considered overlapping
 6413                            // https://github.com/zed-industries/zed/issues/26136
 6414                            let is_file_start_auto_import = {
 6415                                let snapshot = buffer.snapshot();
 6416                                let primary_start_point = primary.start.to_point(&snapshot);
 6417                                let range_start_point = range.start.to_point(&snapshot);
 6418
 6419                                let result = primary_start_point.row == 0
 6420                                    && primary_start_point.column == 0
 6421                                    && range_start_point.row == 0
 6422                                    && range_start_point.column == 0;
 6423
 6424                                result
 6425                            };
 6426
 6427                            let has_overlap = if is_file_start_auto_import {
 6428                                false
 6429                            } else {
 6430                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6431                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6432                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6433                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6434                                let result = start_within || end_within;
 6435                                result
 6436                            };
 6437
 6438                            //Skip additional edits which overlap with the primary completion edit
 6439                            //https://github.com/zed-industries/zed/pull/1871
 6440                            if !has_overlap {
 6441                                buffer.edit([(range, text)], None, cx);
 6442                            }
 6443                        }
 6444
 6445                        let transaction = if buffer.end_transaction(cx).is_some() {
 6446                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6447                            if !push_to_history {
 6448                                buffer.forget_transaction(transaction.id);
 6449                            }
 6450                            Some(transaction)
 6451                        } else {
 6452                            None
 6453                        };
 6454                        Ok(transaction)
 6455                    })?
 6456                } else {
 6457                    Ok(None)
 6458                }
 6459            })
 6460        }
 6461    }
 6462
 6463    pub fn pull_diagnostics(
 6464        &mut self,
 6465        buffer: Entity<Buffer>,
 6466        cx: &mut Context<Self>,
 6467    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6468        let buffer_id = buffer.read(cx).remote_id();
 6469
 6470        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6471            let mut suitable_capabilities = None;
 6472            // Are we capable for proto request?
 6473            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6474                &buffer,
 6475                |capabilities| {
 6476                    if let Some(caps) = &capabilities.diagnostic_provider {
 6477                        suitable_capabilities = Some(caps.clone());
 6478                        true
 6479                    } else {
 6480                        false
 6481                    }
 6482                },
 6483                cx,
 6484            );
 6485            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6486            let Some(dynamic_caps) = suitable_capabilities else {
 6487                return Task::ready(Ok(None));
 6488            };
 6489            assert!(any_server_has_diagnostics_provider);
 6490
 6491            let request = GetDocumentDiagnostics {
 6492                previous_result_id: None,
 6493                dynamic_caps,
 6494            };
 6495            let request_task = client.request_lsp(
 6496                upstream_project_id,
 6497                None,
 6498                LSP_REQUEST_TIMEOUT,
 6499                cx.background_executor().clone(),
 6500                request.to_proto(upstream_project_id, buffer.read(cx)),
 6501            );
 6502            cx.background_spawn(async move {
 6503                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6504                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6505                // Do not attempt to further process the dummy responses here.
 6506                let _response = request_task.await?;
 6507                Ok(None)
 6508            })
 6509        } else {
 6510            let servers = buffer.update(cx, |buffer, cx| {
 6511                self.language_servers_for_local_buffer(buffer, cx)
 6512                    .map(|(_, server)| server.clone())
 6513                    .collect::<Vec<_>>()
 6514            });
 6515
 6516            let pull_diagnostics = servers
 6517                .into_iter()
 6518                .flat_map(|server| {
 6519                    let result = maybe!({
 6520                        let local = self.as_local()?;
 6521                        let server_id = server.server_id();
 6522                        let providers_with_identifiers = local
 6523                            .language_server_dynamic_registrations
 6524                            .get(&server_id)
 6525                            .into_iter()
 6526                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6527                            .collect::<Vec<_>>();
 6528                        Some(
 6529                            providers_with_identifiers
 6530                                .into_iter()
 6531                                .map(|dynamic_caps| {
 6532                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6533                                    self.request_lsp(
 6534                                        buffer.clone(),
 6535                                        LanguageServerToQuery::Other(server_id),
 6536                                        GetDocumentDiagnostics {
 6537                                            previous_result_id: result_id,
 6538                                            dynamic_caps,
 6539                                        },
 6540                                        cx,
 6541                                    )
 6542                                })
 6543                                .collect::<Vec<_>>(),
 6544                        )
 6545                    });
 6546
 6547                    result.unwrap_or_default()
 6548                })
 6549                .collect::<Vec<_>>();
 6550
 6551            cx.background_spawn(async move {
 6552                let mut responses = Vec::new();
 6553                for diagnostics in join_all(pull_diagnostics).await {
 6554                    responses.extend(diagnostics?);
 6555                }
 6556                Ok(Some(responses))
 6557            })
 6558        }
 6559    }
 6560
 6561    pub fn applicable_inlay_chunks(
 6562        &mut self,
 6563        buffer: &Entity<Buffer>,
 6564        ranges: &[Range<text::Anchor>],
 6565        cx: &mut Context<Self>,
 6566    ) -> Vec<Range<BufferRow>> {
 6567        self.latest_lsp_data(buffer, cx)
 6568            .inlay_hints
 6569            .applicable_chunks(ranges)
 6570            .map(|chunk| chunk.start..chunk.end)
 6571            .collect()
 6572    }
 6573
 6574    pub fn invalidate_inlay_hints<'a>(
 6575        &'a mut self,
 6576        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6577    ) {
 6578        for buffer_id in for_buffers {
 6579            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6580                lsp_data.inlay_hints.clear();
 6581            }
 6582        }
 6583    }
 6584
 6585    pub fn inlay_hints(
 6586        &mut self,
 6587        invalidate: InvalidationStrategy,
 6588        buffer: Entity<Buffer>,
 6589        ranges: Vec<Range<text::Anchor>>,
 6590        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6591        cx: &mut Context<Self>,
 6592    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6593        let buffer_snapshot = buffer.read(cx).snapshot();
 6594        let for_server = if let InvalidationStrategy::RefreshRequested(server_id) = invalidate {
 6595            Some(server_id)
 6596        } else {
 6597            None
 6598        };
 6599        let invalidate_cache = invalidate.should_invalidate();
 6600        let next_hint_id = self.next_hint_id.clone();
 6601        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6602        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6603        let known_chunks = known_chunks
 6604            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6605            .map(|(_, known_chunks)| known_chunks)
 6606            .unwrap_or_default();
 6607
 6608        let mut hint_fetch_tasks = Vec::new();
 6609        let mut cached_inlay_hints = HashMap::default();
 6610        let mut ranges_to_query = Vec::new();
 6611        let applicable_chunks = existing_inlay_hints
 6612            .applicable_chunks(ranges.as_slice())
 6613            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6614            .collect::<Vec<_>>();
 6615        if applicable_chunks.is_empty() {
 6616            return HashMap::default();
 6617        }
 6618
 6619        let last_chunk_number = applicable_chunks.len() - 1;
 6620
 6621        for (i, row_chunk) in applicable_chunks.into_iter().enumerate() {
 6622            match (
 6623                existing_inlay_hints
 6624                    .cached_hints(&row_chunk)
 6625                    .filter(|_| !invalidate_cache)
 6626                    .cloned(),
 6627                existing_inlay_hints
 6628                    .fetched_hints(&row_chunk)
 6629                    .as_ref()
 6630                    .filter(|_| !invalidate_cache)
 6631                    .cloned(),
 6632            ) {
 6633                (None, None) => {
 6634                    let end = if last_chunk_number == i {
 6635                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6636                    } else {
 6637                        Point::new(row_chunk.end, 0)
 6638                    };
 6639                    ranges_to_query.push((
 6640                        row_chunk,
 6641                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6642                            ..buffer_snapshot.anchor_after(end),
 6643                    ));
 6644                }
 6645                (None, Some(fetched_hints)) => {
 6646                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()))
 6647                }
 6648                (Some(cached_hints), None) => {
 6649                    for (server_id, cached_hints) in cached_hints {
 6650                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6651                            cached_inlay_hints
 6652                                .entry(row_chunk.start..row_chunk.end)
 6653                                .or_insert_with(HashMap::default)
 6654                                .entry(server_id)
 6655                                .or_insert_with(Vec::new)
 6656                                .extend(cached_hints);
 6657                        }
 6658                    }
 6659                }
 6660                (Some(cached_hints), Some(fetched_hints)) => {
 6661                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()));
 6662                    for (server_id, cached_hints) in cached_hints {
 6663                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6664                            cached_inlay_hints
 6665                                .entry(row_chunk.start..row_chunk.end)
 6666                                .or_insert_with(HashMap::default)
 6667                                .entry(server_id)
 6668                                .or_insert_with(Vec::new)
 6669                                .extend(cached_hints);
 6670                        }
 6671                    }
 6672                }
 6673            }
 6674        }
 6675
 6676        let cached_chunk_data = cached_inlay_hints
 6677            .into_iter()
 6678            .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6679            .collect();
 6680        if hint_fetch_tasks.is_empty() && ranges_to_query.is_empty() {
 6681            cached_chunk_data
 6682        } else {
 6683            if invalidate_cache {
 6684                lsp_data.inlay_hints.clear();
 6685            }
 6686
 6687            for (chunk, range_to_query) in ranges_to_query {
 6688                let next_hint_id = next_hint_id.clone();
 6689                let buffer = buffer.clone();
 6690                let new_inlay_hints = cx
 6691                    .spawn(async move |lsp_store, cx| {
 6692                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6693                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6694                        })?;
 6695                        new_fetch_task
 6696                            .await
 6697                            .and_then(|new_hints_by_server| {
 6698                                lsp_store.update(cx, |lsp_store, cx| {
 6699                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6700                                    let update_cache = !lsp_data
 6701                                        .buffer_version
 6702                                        .changed_since(&buffer.read(cx).version());
 6703                                    new_hints_by_server
 6704                                        .into_iter()
 6705                                        .map(|(server_id, new_hints)| {
 6706                                            let new_hints = new_hints
 6707                                                .into_iter()
 6708                                                .map(|new_hint| {
 6709                                                    (
 6710                                                        InlayId::Hint(next_hint_id.fetch_add(
 6711                                                            1,
 6712                                                            atomic::Ordering::AcqRel,
 6713                                                        )),
 6714                                                        new_hint,
 6715                                                    )
 6716                                                })
 6717                                                .collect::<Vec<_>>();
 6718                                            if update_cache {
 6719                                                lsp_data.inlay_hints.insert_new_hints(
 6720                                                    chunk,
 6721                                                    server_id,
 6722                                                    new_hints.clone(),
 6723                                                );
 6724                                            }
 6725                                            (server_id, new_hints)
 6726                                        })
 6727                                        .collect()
 6728                                })
 6729                            })
 6730                            .map_err(Arc::new)
 6731                    })
 6732                    .shared();
 6733
 6734                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6735                *fetch_task = Some(new_inlay_hints.clone());
 6736                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6737            }
 6738
 6739            let mut combined_data = cached_chunk_data;
 6740            combined_data.extend(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6741                (
 6742                    chunk.start..chunk.end,
 6743                    cx.spawn(async move |_, _| {
 6744                        hints_fetch.await.map_err(|e| {
 6745                            if e.error_code() != ErrorCode::Internal {
 6746                                anyhow!(e.error_code())
 6747                            } else {
 6748                                anyhow!("{e:#}")
 6749                            }
 6750                        })
 6751                    }),
 6752                )
 6753            }));
 6754            combined_data
 6755        }
 6756    }
 6757
 6758    fn fetch_inlay_hints(
 6759        &mut self,
 6760        for_server: Option<LanguageServerId>,
 6761        buffer: &Entity<Buffer>,
 6762        range: Range<Anchor>,
 6763        cx: &mut Context<Self>,
 6764    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6765        let request = InlayHints {
 6766            range: range.clone(),
 6767        };
 6768        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6769            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6770                return Task::ready(Ok(HashMap::default()));
 6771            }
 6772            let request_task = upstream_client.request_lsp(
 6773                project_id,
 6774                for_server.map(|id| id.to_proto()),
 6775                LSP_REQUEST_TIMEOUT,
 6776                cx.background_executor().clone(),
 6777                request.to_proto(project_id, buffer.read(cx)),
 6778            );
 6779            let buffer = buffer.clone();
 6780            cx.spawn(async move |weak_lsp_store, cx| {
 6781                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6782                    return Ok(HashMap::default());
 6783                };
 6784                let Some(responses) = request_task.await? else {
 6785                    return Ok(HashMap::default());
 6786                };
 6787
 6788                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6789                    let lsp_store = lsp_store.clone();
 6790                    let buffer = buffer.clone();
 6791                    let cx = cx.clone();
 6792                    let request = request.clone();
 6793                    async move {
 6794                        (
 6795                            LanguageServerId::from_proto(response.server_id),
 6796                            request
 6797                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6798                                .await,
 6799                        )
 6800                    }
 6801                }))
 6802                .await;
 6803
 6804                let mut has_errors = false;
 6805                let inlay_hints = inlay_hints
 6806                    .into_iter()
 6807                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6808                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6809                        Err(e) => {
 6810                            has_errors = true;
 6811                            log::error!("{e:#}");
 6812                            None
 6813                        }
 6814                    })
 6815                    .collect::<HashMap<_, _>>();
 6816                anyhow::ensure!(
 6817                    !has_errors || !inlay_hints.is_empty(),
 6818                    "Failed to fetch inlay hints"
 6819                );
 6820                Ok(inlay_hints)
 6821            })
 6822        } else {
 6823            let inlay_hints_task = match for_server {
 6824                Some(server_id) => {
 6825                    let server_task = self.request_lsp(
 6826                        buffer.clone(),
 6827                        LanguageServerToQuery::Other(server_id),
 6828                        request,
 6829                        cx,
 6830                    );
 6831                    cx.background_spawn(async move {
 6832                        let mut responses = Vec::new();
 6833                        match server_task.await {
 6834                            Ok(response) => responses.push((server_id, response)),
 6835                            Err(e) => log::error!(
 6836                                "Error handling response for inlay hints request: {e:#}"
 6837                            ),
 6838                        }
 6839                        responses
 6840                    })
 6841                }
 6842                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6843            };
 6844            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6845            cx.background_spawn(async move {
 6846                Ok(inlay_hints_task
 6847                    .await
 6848                    .into_iter()
 6849                    .map(|(server_id, mut new_hints)| {
 6850                        new_hints.retain(|hint| {
 6851                            hint.position.is_valid(&buffer_snapshot)
 6852                                && range.start.is_valid(&buffer_snapshot)
 6853                                && range.end.is_valid(&buffer_snapshot)
 6854                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6855                                && hint.position.cmp(&range.end, &buffer_snapshot).is_le()
 6856                        });
 6857                        (server_id, new_hints)
 6858                    })
 6859                    .collect())
 6860            })
 6861        }
 6862    }
 6863
 6864    pub fn pull_diagnostics_for_buffer(
 6865        &mut self,
 6866        buffer: Entity<Buffer>,
 6867        cx: &mut Context<Self>,
 6868    ) -> Task<anyhow::Result<()>> {
 6869        let diagnostics = self.pull_diagnostics(buffer, cx);
 6870        cx.spawn(async move |lsp_store, cx| {
 6871            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6872                return Ok(());
 6873            };
 6874            lsp_store.update(cx, |lsp_store, cx| {
 6875                if lsp_store.as_local().is_none() {
 6876                    return;
 6877                }
 6878
 6879                let mut unchanged_buffers = HashSet::default();
 6880                let mut changed_buffers = HashSet::default();
 6881                let server_diagnostics_updates = diagnostics
 6882                    .into_iter()
 6883                    .filter_map(|diagnostics_set| match diagnostics_set {
 6884                        LspPullDiagnostics::Response {
 6885                            server_id,
 6886                            uri,
 6887                            diagnostics,
 6888                        } => Some((server_id, uri, diagnostics)),
 6889                        LspPullDiagnostics::Default => None,
 6890                    })
 6891                    .fold(
 6892                        HashMap::default(),
 6893                        |mut acc, (server_id, uri, diagnostics)| {
 6894                            let (result_id, diagnostics) = match diagnostics {
 6895                                PulledDiagnostics::Unchanged { result_id } => {
 6896                                    unchanged_buffers.insert(uri.clone());
 6897                                    (Some(result_id), Vec::new())
 6898                                }
 6899                                PulledDiagnostics::Changed {
 6900                                    result_id,
 6901                                    diagnostics,
 6902                                } => {
 6903                                    changed_buffers.insert(uri.clone());
 6904                                    (result_id, diagnostics)
 6905                                }
 6906                            };
 6907                            let disk_based_sources = Cow::Owned(
 6908                                lsp_store
 6909                                    .language_server_adapter_for_id(server_id)
 6910                                    .as_ref()
 6911                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6912                                    .unwrap_or(&[])
 6913                                    .to_vec(),
 6914                            );
 6915                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6916                                DocumentDiagnosticsUpdate {
 6917                                    server_id,
 6918                                    diagnostics: lsp::PublishDiagnosticsParams {
 6919                                        uri,
 6920                                        diagnostics,
 6921                                        version: None,
 6922                                    },
 6923                                    result_id,
 6924                                    disk_based_sources,
 6925                                },
 6926                            );
 6927                            acc
 6928                        },
 6929                    );
 6930
 6931                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6932                    lsp_store
 6933                        .merge_lsp_diagnostics(
 6934                            DiagnosticSourceKind::Pulled,
 6935                            diagnostic_updates,
 6936                            |buffer, old_diagnostic, cx| {
 6937                                File::from_dyn(buffer.file())
 6938                                    .and_then(|file| {
 6939                                        let abs_path = file.as_local()?.abs_path(cx);
 6940                                        lsp::Uri::from_file_path(abs_path).ok()
 6941                                    })
 6942                                    .is_none_or(|buffer_uri| {
 6943                                        unchanged_buffers.contains(&buffer_uri)
 6944                                            || match old_diagnostic.source_kind {
 6945                                                DiagnosticSourceKind::Pulled => {
 6946                                                    !changed_buffers.contains(&buffer_uri)
 6947                                                }
 6948                                                DiagnosticSourceKind::Other
 6949                                                | DiagnosticSourceKind::Pushed => true,
 6950                                            }
 6951                                    })
 6952                            },
 6953                            cx,
 6954                        )
 6955                        .log_err();
 6956                }
 6957            })
 6958        })
 6959    }
 6960
 6961    pub fn document_colors(
 6962        &mut self,
 6963        known_cache_version: Option<usize>,
 6964        buffer: Entity<Buffer>,
 6965        cx: &mut Context<Self>,
 6966    ) -> Option<DocumentColorTask> {
 6967        let version_queried_for = buffer.read(cx).version();
 6968        let buffer_id = buffer.read(cx).remote_id();
 6969
 6970        let current_language_servers = self.as_local().map(|local| {
 6971            local
 6972                .buffers_opened_in_servers
 6973                .get(&buffer_id)
 6974                .cloned()
 6975                .unwrap_or_default()
 6976        });
 6977
 6978        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6979            if let Some(cached_colors) = &lsp_data.document_colors {
 6980                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6981                    let has_different_servers =
 6982                        current_language_servers.is_some_and(|current_language_servers| {
 6983                            current_language_servers
 6984                                != cached_colors.colors.keys().copied().collect()
 6985                        });
 6986                    if !has_different_servers {
 6987                        let cache_version = cached_colors.cache_version;
 6988                        if Some(cache_version) == known_cache_version {
 6989                            return None;
 6990                        } else {
 6991                            return Some(
 6992                                Task::ready(Ok(DocumentColors {
 6993                                    colors: cached_colors
 6994                                        .colors
 6995                                        .values()
 6996                                        .flatten()
 6997                                        .cloned()
 6998                                        .collect(),
 6999                                    cache_version: Some(cache_version),
 7000                                }))
 7001                                .shared(),
 7002                            );
 7003                        }
 7004                    }
 7005                }
 7006            }
 7007        }
 7008
 7009        let color_lsp_data = self
 7010            .latest_lsp_data(&buffer, cx)
 7011            .document_colors
 7012            .get_or_insert_default();
 7013        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7014            && !version_queried_for.changed_since(updating_for)
 7015        {
 7016            return Some(running_update.clone());
 7017        }
 7018        let buffer_version_queried_for = version_queried_for.clone();
 7019        let new_task = cx
 7020            .spawn(async move |lsp_store, cx| {
 7021                cx.background_executor()
 7022                    .timer(Duration::from_millis(30))
 7023                    .await;
 7024                let fetched_colors = lsp_store
 7025                    .update(cx, |lsp_store, cx| {
 7026                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7027                    })?
 7028                    .await
 7029                    .context("fetching document colors")
 7030                    .map_err(Arc::new);
 7031                let fetched_colors = match fetched_colors {
 7032                    Ok(fetched_colors) => {
 7033                        if Some(true)
 7034                            == buffer
 7035                                .update(cx, |buffer, _| {
 7036                                    buffer.version() != buffer_version_queried_for
 7037                                })
 7038                                .ok()
 7039                        {
 7040                            return Ok(DocumentColors::default());
 7041                        }
 7042                        fetched_colors
 7043                    }
 7044                    Err(e) => {
 7045                        lsp_store
 7046                            .update(cx, |lsp_store, _| {
 7047                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7048                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7049                                        document_colors.colors_update = None;
 7050                                    }
 7051                                }
 7052                            })
 7053                            .ok();
 7054                        return Err(e);
 7055                    }
 7056                };
 7057
 7058                lsp_store
 7059                    .update(cx, |lsp_store, cx| {
 7060                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7061                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7062
 7063                        if let Some(fetched_colors) = fetched_colors {
 7064                            if lsp_data.buffer_version == buffer_version_queried_for {
 7065                                lsp_colors.colors.extend(fetched_colors);
 7066                                lsp_colors.cache_version += 1;
 7067                            } else if !lsp_data
 7068                                .buffer_version
 7069                                .changed_since(&buffer_version_queried_for)
 7070                            {
 7071                                lsp_data.buffer_version = buffer_version_queried_for;
 7072                                lsp_colors.colors = fetched_colors;
 7073                                lsp_colors.cache_version += 1;
 7074                            }
 7075                        }
 7076                        lsp_colors.colors_update = None;
 7077                        let colors = lsp_colors
 7078                            .colors
 7079                            .values()
 7080                            .flatten()
 7081                            .cloned()
 7082                            .collect::<HashSet<_>>();
 7083                        DocumentColors {
 7084                            colors,
 7085                            cache_version: Some(lsp_colors.cache_version),
 7086                        }
 7087                    })
 7088                    .map_err(Arc::new)
 7089            })
 7090            .shared();
 7091        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7092        Some(new_task)
 7093    }
 7094
 7095    fn fetch_document_colors_for_buffer(
 7096        &mut self,
 7097        buffer: &Entity<Buffer>,
 7098        cx: &mut Context<Self>,
 7099    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7100        if let Some((client, project_id)) = self.upstream_client() {
 7101            let request = GetDocumentColor {};
 7102            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7103                return Task::ready(Ok(None));
 7104            }
 7105
 7106            let request_task = client.request_lsp(
 7107                project_id,
 7108                None,
 7109                LSP_REQUEST_TIMEOUT,
 7110                cx.background_executor().clone(),
 7111                request.to_proto(project_id, buffer.read(cx)),
 7112            );
 7113            let buffer = buffer.clone();
 7114            cx.spawn(async move |lsp_store, cx| {
 7115                let Some(project) = lsp_store.upgrade() else {
 7116                    return Ok(None);
 7117                };
 7118                let colors = join_all(
 7119                    request_task
 7120                        .await
 7121                        .log_err()
 7122                        .flatten()
 7123                        .map(|response| response.payload)
 7124                        .unwrap_or_default()
 7125                        .into_iter()
 7126                        .map(|color_response| {
 7127                            let response = request.response_from_proto(
 7128                                color_response.response,
 7129                                project.clone(),
 7130                                buffer.clone(),
 7131                                cx.clone(),
 7132                            );
 7133                            async move {
 7134                                (
 7135                                    LanguageServerId::from_proto(color_response.server_id),
 7136                                    response.await.log_err().unwrap_or_default(),
 7137                                )
 7138                            }
 7139                        }),
 7140                )
 7141                .await
 7142                .into_iter()
 7143                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7144                    acc.entry(server_id)
 7145                        .or_insert_with(HashSet::default)
 7146                        .extend(colors);
 7147                    acc
 7148                });
 7149                Ok(Some(colors))
 7150            })
 7151        } else {
 7152            let document_colors_task =
 7153                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7154            cx.background_spawn(async move {
 7155                Ok(Some(
 7156                    document_colors_task
 7157                        .await
 7158                        .into_iter()
 7159                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7160                            acc.entry(server_id)
 7161                                .or_insert_with(HashSet::default)
 7162                                .extend(colors);
 7163                            acc
 7164                        })
 7165                        .into_iter()
 7166                        .collect(),
 7167                ))
 7168            })
 7169        }
 7170    }
 7171
 7172    pub fn signature_help<T: ToPointUtf16>(
 7173        &mut self,
 7174        buffer: &Entity<Buffer>,
 7175        position: T,
 7176        cx: &mut Context<Self>,
 7177    ) -> Task<Option<Vec<SignatureHelp>>> {
 7178        let position = position.to_point_utf16(buffer.read(cx));
 7179
 7180        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7181            let request = GetSignatureHelp { position };
 7182            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7183                return Task::ready(None);
 7184            }
 7185            let request_task = client.request_lsp(
 7186                upstream_project_id,
 7187                None,
 7188                LSP_REQUEST_TIMEOUT,
 7189                cx.background_executor().clone(),
 7190                request.to_proto(upstream_project_id, buffer.read(cx)),
 7191            );
 7192            let buffer = buffer.clone();
 7193            cx.spawn(async move |weak_project, cx| {
 7194                let project = weak_project.upgrade()?;
 7195                let signatures = join_all(
 7196                    request_task
 7197                        .await
 7198                        .log_err()
 7199                        .flatten()
 7200                        .map(|response| response.payload)
 7201                        .unwrap_or_default()
 7202                        .into_iter()
 7203                        .map(|response| {
 7204                            let response = GetSignatureHelp { position }.response_from_proto(
 7205                                response.response,
 7206                                project.clone(),
 7207                                buffer.clone(),
 7208                                cx.clone(),
 7209                            );
 7210                            async move { response.await.log_err().flatten() }
 7211                        }),
 7212                )
 7213                .await
 7214                .into_iter()
 7215                .flatten()
 7216                .collect();
 7217                Some(signatures)
 7218            })
 7219        } else {
 7220            let all_actions_task = self.request_multiple_lsp_locally(
 7221                buffer,
 7222                Some(position),
 7223                GetSignatureHelp { position },
 7224                cx,
 7225            );
 7226            cx.background_spawn(async move {
 7227                Some(
 7228                    all_actions_task
 7229                        .await
 7230                        .into_iter()
 7231                        .flat_map(|(_, actions)| actions)
 7232                        .collect::<Vec<_>>(),
 7233                )
 7234            })
 7235        }
 7236    }
 7237
 7238    pub fn hover(
 7239        &mut self,
 7240        buffer: &Entity<Buffer>,
 7241        position: PointUtf16,
 7242        cx: &mut Context<Self>,
 7243    ) -> Task<Option<Vec<Hover>>> {
 7244        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7245            let request = GetHover { position };
 7246            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7247                return Task::ready(None);
 7248            }
 7249            let request_task = client.request_lsp(
 7250                upstream_project_id,
 7251                None,
 7252                LSP_REQUEST_TIMEOUT,
 7253                cx.background_executor().clone(),
 7254                request.to_proto(upstream_project_id, buffer.read(cx)),
 7255            );
 7256            let buffer = buffer.clone();
 7257            cx.spawn(async move |weak_project, cx| {
 7258                let project = weak_project.upgrade()?;
 7259                let hovers = join_all(
 7260                    request_task
 7261                        .await
 7262                        .log_err()
 7263                        .flatten()
 7264                        .map(|response| response.payload)
 7265                        .unwrap_or_default()
 7266                        .into_iter()
 7267                        .map(|response| {
 7268                            let response = GetHover { position }.response_from_proto(
 7269                                response.response,
 7270                                project.clone(),
 7271                                buffer.clone(),
 7272                                cx.clone(),
 7273                            );
 7274                            async move {
 7275                                response
 7276                                    .await
 7277                                    .log_err()
 7278                                    .flatten()
 7279                                    .and_then(remove_empty_hover_blocks)
 7280                            }
 7281                        }),
 7282                )
 7283                .await
 7284                .into_iter()
 7285                .flatten()
 7286                .collect();
 7287                Some(hovers)
 7288            })
 7289        } else {
 7290            let all_actions_task = self.request_multiple_lsp_locally(
 7291                buffer,
 7292                Some(position),
 7293                GetHover { position },
 7294                cx,
 7295            );
 7296            cx.background_spawn(async move {
 7297                Some(
 7298                    all_actions_task
 7299                        .await
 7300                        .into_iter()
 7301                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7302                        .collect::<Vec<Hover>>(),
 7303                )
 7304            })
 7305        }
 7306    }
 7307
 7308    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7309        let language_registry = self.languages.clone();
 7310
 7311        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7312            let request = upstream_client.request(proto::GetProjectSymbols {
 7313                project_id: *project_id,
 7314                query: query.to_string(),
 7315            });
 7316            cx.foreground_executor().spawn(async move {
 7317                let response = request.await?;
 7318                let mut symbols = Vec::new();
 7319                let core_symbols = response
 7320                    .symbols
 7321                    .into_iter()
 7322                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7323                    .collect::<Vec<_>>();
 7324                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7325                    .await;
 7326                Ok(symbols)
 7327            })
 7328        } else if let Some(local) = self.as_local() {
 7329            struct WorkspaceSymbolsResult {
 7330                server_id: LanguageServerId,
 7331                lsp_adapter: Arc<CachedLspAdapter>,
 7332                worktree: WeakEntity<Worktree>,
 7333                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7334            }
 7335
 7336            let mut requests = Vec::new();
 7337            let mut requested_servers = BTreeSet::new();
 7338            for (seed, state) in local.language_server_ids.iter() {
 7339                let Some(worktree_handle) = self
 7340                    .worktree_store
 7341                    .read(cx)
 7342                    .worktree_for_id(seed.worktree_id, cx)
 7343                else {
 7344                    continue;
 7345                };
 7346                let worktree = worktree_handle.read(cx);
 7347                if !worktree.is_visible() {
 7348                    continue;
 7349                }
 7350
 7351                if !requested_servers.insert(state.id) {
 7352                    continue;
 7353                }
 7354
 7355                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7356                    Some(LanguageServerState::Running {
 7357                        adapter, server, ..
 7358                    }) => (adapter.clone(), server),
 7359
 7360                    _ => continue,
 7361                };
 7362                let supports_workspace_symbol_request =
 7363                    match server.capabilities().workspace_symbol_provider {
 7364                        Some(OneOf::Left(supported)) => supported,
 7365                        Some(OneOf::Right(_)) => true,
 7366                        None => false,
 7367                    };
 7368                if !supports_workspace_symbol_request {
 7369                    continue;
 7370                }
 7371                let worktree_handle = worktree_handle.clone();
 7372                let server_id = server.server_id();
 7373                requests.push(
 7374                        server
 7375                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7376                                lsp::WorkspaceSymbolParams {
 7377                                    query: query.to_string(),
 7378                                    ..Default::default()
 7379                                },
 7380                            )
 7381                            .map(move |response| {
 7382                                let lsp_symbols = response.into_response()
 7383                                    .context("workspace symbols request")
 7384                                    .log_err()
 7385                                    .flatten()
 7386                                    .map(|symbol_response| match symbol_response {
 7387                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7388                                            flat_responses.into_iter().map(|lsp_symbol| {
 7389                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7390                                            }).collect::<Vec<_>>()
 7391                                        }
 7392                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7393                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7394                                                let location = match lsp_symbol.location {
 7395                                                    OneOf::Left(location) => location,
 7396                                                    OneOf::Right(_) => {
 7397                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7398                                                        return None
 7399                                                    }
 7400                                                };
 7401                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7402                                            }).collect::<Vec<_>>()
 7403                                        }
 7404                                    }).unwrap_or_default();
 7405
 7406                                WorkspaceSymbolsResult {
 7407                                    server_id,
 7408                                    lsp_adapter,
 7409                                    worktree: worktree_handle.downgrade(),
 7410                                    lsp_symbols,
 7411                                }
 7412                            }),
 7413                    );
 7414            }
 7415
 7416            cx.spawn(async move |this, cx| {
 7417                let responses = futures::future::join_all(requests).await;
 7418                let this = match this.upgrade() {
 7419                    Some(this) => this,
 7420                    None => return Ok(Vec::new()),
 7421                };
 7422
 7423                let mut symbols = Vec::new();
 7424                for result in responses {
 7425                    let core_symbols = this.update(cx, |this, cx| {
 7426                        result
 7427                            .lsp_symbols
 7428                            .into_iter()
 7429                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7430                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7431                                let source_worktree = result.worktree.upgrade()?;
 7432                                let source_worktree_id = source_worktree.read(cx).id();
 7433
 7434                                let path = if let Some((tree, rel_path)) =
 7435                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7436                                {
 7437                                    let worktree_id = tree.read(cx).id();
 7438                                    SymbolLocation::InProject(ProjectPath {
 7439                                        worktree_id,
 7440                                        path: rel_path,
 7441                                    })
 7442                                } else {
 7443                                    SymbolLocation::OutsideProject {
 7444                                        signature: this.symbol_signature(&abs_path),
 7445                                        abs_path: abs_path.into(),
 7446                                    }
 7447                                };
 7448
 7449                                Some(CoreSymbol {
 7450                                    source_language_server_id: result.server_id,
 7451                                    language_server_name: result.lsp_adapter.name.clone(),
 7452                                    source_worktree_id,
 7453                                    path,
 7454                                    kind: symbol_kind,
 7455                                    name: symbol_name,
 7456                                    range: range_from_lsp(symbol_location.range),
 7457                                })
 7458                            })
 7459                            .collect()
 7460                    })?;
 7461
 7462                    populate_labels_for_symbols(
 7463                        core_symbols,
 7464                        &language_registry,
 7465                        Some(result.lsp_adapter),
 7466                        &mut symbols,
 7467                    )
 7468                    .await;
 7469                }
 7470
 7471                Ok(symbols)
 7472            })
 7473        } else {
 7474            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7475        }
 7476    }
 7477
 7478    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7479        let mut summary = DiagnosticSummary::default();
 7480        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7481            summary.error_count += path_summary.error_count;
 7482            summary.warning_count += path_summary.warning_count;
 7483        }
 7484        summary
 7485    }
 7486
 7487    /// Returns the diagnostic summary for a specific project path.
 7488    pub fn diagnostic_summary_for_path(
 7489        &self,
 7490        project_path: &ProjectPath,
 7491        _: &App,
 7492    ) -> DiagnosticSummary {
 7493        if let Some(summaries) = self
 7494            .diagnostic_summaries
 7495            .get(&project_path.worktree_id)
 7496            .and_then(|map| map.get(&project_path.path))
 7497        {
 7498            let (error_count, warning_count) = summaries.iter().fold(
 7499                (0, 0),
 7500                |(error_count, warning_count), (_language_server_id, summary)| {
 7501                    (
 7502                        error_count + summary.error_count,
 7503                        warning_count + summary.warning_count,
 7504                    )
 7505                },
 7506            );
 7507
 7508            DiagnosticSummary {
 7509                error_count,
 7510                warning_count,
 7511            }
 7512        } else {
 7513            DiagnosticSummary::default()
 7514        }
 7515    }
 7516
 7517    pub fn diagnostic_summaries<'a>(
 7518        &'a self,
 7519        include_ignored: bool,
 7520        cx: &'a App,
 7521    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7522        self.worktree_store
 7523            .read(cx)
 7524            .visible_worktrees(cx)
 7525            .filter_map(|worktree| {
 7526                let worktree = worktree.read(cx);
 7527                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7528            })
 7529            .flat_map(move |(worktree, summaries)| {
 7530                let worktree_id = worktree.id();
 7531                summaries
 7532                    .iter()
 7533                    .filter(move |(path, _)| {
 7534                        include_ignored
 7535                            || worktree
 7536                                .entry_for_path(path.as_ref())
 7537                                .is_some_and(|entry| !entry.is_ignored)
 7538                    })
 7539                    .flat_map(move |(path, summaries)| {
 7540                        summaries.iter().map(move |(server_id, summary)| {
 7541                            (
 7542                                ProjectPath {
 7543                                    worktree_id,
 7544                                    path: path.clone(),
 7545                                },
 7546                                *server_id,
 7547                                *summary,
 7548                            )
 7549                        })
 7550                    })
 7551            })
 7552    }
 7553
 7554    pub fn on_buffer_edited(
 7555        &mut self,
 7556        buffer: Entity<Buffer>,
 7557        cx: &mut Context<Self>,
 7558    ) -> Option<()> {
 7559        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7560            Some(
 7561                self.as_local()?
 7562                    .language_servers_for_buffer(buffer, cx)
 7563                    .map(|i| i.1.clone())
 7564                    .collect(),
 7565            )
 7566        })?;
 7567
 7568        let buffer = buffer.read(cx);
 7569        let file = File::from_dyn(buffer.file())?;
 7570        let abs_path = file.as_local()?.abs_path(cx);
 7571        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7572        let next_snapshot = buffer.text_snapshot();
 7573        for language_server in language_servers {
 7574            let language_server = language_server.clone();
 7575
 7576            let buffer_snapshots = self
 7577                .as_local_mut()
 7578                .unwrap()
 7579                .buffer_snapshots
 7580                .get_mut(&buffer.remote_id())
 7581                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7582            let previous_snapshot = buffer_snapshots.last()?;
 7583
 7584            let build_incremental_change = || {
 7585                buffer
 7586                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7587                        previous_snapshot.snapshot.version(),
 7588                    )
 7589                    .map(|edit| {
 7590                        let edit_start = edit.new.start.0;
 7591                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7592                        let new_text = next_snapshot
 7593                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7594                            .collect();
 7595                        lsp::TextDocumentContentChangeEvent {
 7596                            range: Some(lsp::Range::new(
 7597                                point_to_lsp(edit_start),
 7598                                point_to_lsp(edit_end),
 7599                            )),
 7600                            range_length: None,
 7601                            text: new_text,
 7602                        }
 7603                    })
 7604                    .collect()
 7605            };
 7606
 7607            let document_sync_kind = language_server
 7608                .capabilities()
 7609                .text_document_sync
 7610                .as_ref()
 7611                .and_then(|sync| match sync {
 7612                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7613                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7614                });
 7615
 7616            let content_changes: Vec<_> = match document_sync_kind {
 7617                Some(lsp::TextDocumentSyncKind::FULL) => {
 7618                    vec![lsp::TextDocumentContentChangeEvent {
 7619                        range: None,
 7620                        range_length: None,
 7621                        text: next_snapshot.text(),
 7622                    }]
 7623                }
 7624                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7625                _ => {
 7626                    #[cfg(any(test, feature = "test-support"))]
 7627                    {
 7628                        build_incremental_change()
 7629                    }
 7630
 7631                    #[cfg(not(any(test, feature = "test-support")))]
 7632                    {
 7633                        continue;
 7634                    }
 7635                }
 7636            };
 7637
 7638            let next_version = previous_snapshot.version + 1;
 7639            buffer_snapshots.push(LspBufferSnapshot {
 7640                version: next_version,
 7641                snapshot: next_snapshot.clone(),
 7642            });
 7643
 7644            language_server
 7645                .notify::<lsp::notification::DidChangeTextDocument>(
 7646                    lsp::DidChangeTextDocumentParams {
 7647                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7648                            uri.clone(),
 7649                            next_version,
 7650                        ),
 7651                        content_changes,
 7652                    },
 7653                )
 7654                .ok();
 7655            self.pull_workspace_diagnostics(language_server.server_id());
 7656        }
 7657
 7658        None
 7659    }
 7660
 7661    pub fn on_buffer_saved(
 7662        &mut self,
 7663        buffer: Entity<Buffer>,
 7664        cx: &mut Context<Self>,
 7665    ) -> Option<()> {
 7666        let file = File::from_dyn(buffer.read(cx).file())?;
 7667        let worktree_id = file.worktree_id(cx);
 7668        let abs_path = file.as_local()?.abs_path(cx);
 7669        let text_document = lsp::TextDocumentIdentifier {
 7670            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7671        };
 7672        let local = self.as_local()?;
 7673
 7674        for server in local.language_servers_for_worktree(worktree_id) {
 7675            if let Some(include_text) = include_text(server.as_ref()) {
 7676                let text = if include_text {
 7677                    Some(buffer.read(cx).text())
 7678                } else {
 7679                    None
 7680                };
 7681                server
 7682                    .notify::<lsp::notification::DidSaveTextDocument>(
 7683                        lsp::DidSaveTextDocumentParams {
 7684                            text_document: text_document.clone(),
 7685                            text,
 7686                        },
 7687                    )
 7688                    .ok();
 7689            }
 7690        }
 7691
 7692        let language_servers = buffer.update(cx, |buffer, cx| {
 7693            local.language_server_ids_for_buffer(buffer, cx)
 7694        });
 7695        for language_server_id in language_servers {
 7696            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7697        }
 7698
 7699        None
 7700    }
 7701
 7702    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7703        maybe!(async move {
 7704            let mut refreshed_servers = HashSet::default();
 7705            let servers = lsp_store
 7706                .update(cx, |lsp_store, cx| {
 7707                    let local = lsp_store.as_local()?;
 7708
 7709                    let servers = local
 7710                        .language_server_ids
 7711                        .iter()
 7712                        .filter_map(|(seed, state)| {
 7713                            let worktree = lsp_store
 7714                                .worktree_store
 7715                                .read(cx)
 7716                                .worktree_for_id(seed.worktree_id, cx);
 7717                            let delegate: Arc<dyn LspAdapterDelegate> =
 7718                                worktree.map(|worktree| {
 7719                                    LocalLspAdapterDelegate::new(
 7720                                        local.languages.clone(),
 7721                                        &local.environment,
 7722                                        cx.weak_entity(),
 7723                                        &worktree,
 7724                                        local.http_client.clone(),
 7725                                        local.fs.clone(),
 7726                                        cx,
 7727                                    )
 7728                                })?;
 7729                            let server_id = state.id;
 7730
 7731                            let states = local.language_servers.get(&server_id)?;
 7732
 7733                            match states {
 7734                                LanguageServerState::Starting { .. } => None,
 7735                                LanguageServerState::Running {
 7736                                    adapter, server, ..
 7737                                } => {
 7738                                    let adapter = adapter.clone();
 7739                                    let server = server.clone();
 7740                                    refreshed_servers.insert(server.name());
 7741                                    let toolchain = seed.toolchain.clone();
 7742                                    Some(cx.spawn(async move |_, cx| {
 7743                                        let settings =
 7744                                            LocalLspStore::workspace_configuration_for_adapter(
 7745                                                adapter.adapter.clone(),
 7746                                                &delegate,
 7747                                                toolchain,
 7748                                                cx,
 7749                                            )
 7750                                            .await
 7751                                            .ok()?;
 7752                                        server
 7753                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7754                                                lsp::DidChangeConfigurationParams { settings },
 7755                                            )
 7756                                            .ok()?;
 7757                                        Some(())
 7758                                    }))
 7759                                }
 7760                            }
 7761                        })
 7762                        .collect::<Vec<_>>();
 7763
 7764                    Some(servers)
 7765                })
 7766                .ok()
 7767                .flatten()?;
 7768
 7769            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7770            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7771            // to stop and unregister its language server wrapper.
 7772            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7773            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7774            let _: Vec<Option<()>> = join_all(servers).await;
 7775
 7776            Some(())
 7777        })
 7778        .await;
 7779    }
 7780
 7781    fn maintain_workspace_config(
 7782        external_refresh_requests: watch::Receiver<()>,
 7783        cx: &mut Context<Self>,
 7784    ) -> Task<Result<()>> {
 7785        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7786        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7787
 7788        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7789            *settings_changed_tx.borrow_mut() = ();
 7790        });
 7791
 7792        let mut joint_future =
 7793            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7794        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7795        // - 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).
 7796        // - 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.
 7797        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7798        // - 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,
 7799        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7800        cx.spawn(async move |this, cx| {
 7801            while let Some(()) = joint_future.next().await {
 7802                this.update(cx, |this, cx| {
 7803                    this.refresh_server_tree(cx);
 7804                })
 7805                .ok();
 7806
 7807                Self::refresh_workspace_configurations(&this, cx).await;
 7808            }
 7809
 7810            drop(settings_observation);
 7811            anyhow::Ok(())
 7812        })
 7813    }
 7814
 7815    pub fn language_servers_for_local_buffer<'a>(
 7816        &'a self,
 7817        buffer: &Buffer,
 7818        cx: &mut App,
 7819    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7820        let local = self.as_local();
 7821        let language_server_ids = local
 7822            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7823            .unwrap_or_default();
 7824
 7825        language_server_ids
 7826            .into_iter()
 7827            .filter_map(
 7828                move |server_id| match local?.language_servers.get(&server_id)? {
 7829                    LanguageServerState::Running {
 7830                        adapter, server, ..
 7831                    } => Some((adapter, server)),
 7832                    _ => None,
 7833                },
 7834            )
 7835    }
 7836
 7837    pub fn language_server_for_local_buffer<'a>(
 7838        &'a self,
 7839        buffer: &'a Buffer,
 7840        server_id: LanguageServerId,
 7841        cx: &'a mut App,
 7842    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7843        self.as_local()?
 7844            .language_servers_for_buffer(buffer, cx)
 7845            .find(|(_, s)| s.server_id() == server_id)
 7846    }
 7847
 7848    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7849        self.diagnostic_summaries.remove(&id_to_remove);
 7850        if let Some(local) = self.as_local_mut() {
 7851            let to_remove = local.remove_worktree(id_to_remove, cx);
 7852            for server in to_remove {
 7853                self.language_server_statuses.remove(&server);
 7854            }
 7855        }
 7856    }
 7857
 7858    pub fn shared(
 7859        &mut self,
 7860        project_id: u64,
 7861        downstream_client: AnyProtoClient,
 7862        _: &mut Context<Self>,
 7863    ) {
 7864        self.downstream_client = Some((downstream_client.clone(), project_id));
 7865
 7866        for (server_id, status) in &self.language_server_statuses {
 7867            if let Some(server) = self.language_server_for_id(*server_id) {
 7868                downstream_client
 7869                    .send(proto::StartLanguageServer {
 7870                        project_id,
 7871                        server: Some(proto::LanguageServer {
 7872                            id: server_id.to_proto(),
 7873                            name: status.name.to_string(),
 7874                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7875                        }),
 7876                        capabilities: serde_json::to_string(&server.capabilities())
 7877                            .expect("serializing server LSP capabilities"),
 7878                    })
 7879                    .log_err();
 7880            }
 7881        }
 7882    }
 7883
 7884    pub fn disconnected_from_host(&mut self) {
 7885        self.downstream_client.take();
 7886    }
 7887
 7888    pub fn disconnected_from_ssh_remote(&mut self) {
 7889        if let LspStoreMode::Remote(RemoteLspStore {
 7890            upstream_client, ..
 7891        }) = &mut self.mode
 7892        {
 7893            upstream_client.take();
 7894        }
 7895    }
 7896
 7897    pub(crate) fn set_language_server_statuses_from_proto(
 7898        &mut self,
 7899        project: WeakEntity<Project>,
 7900        language_servers: Vec<proto::LanguageServer>,
 7901        server_capabilities: Vec<String>,
 7902        cx: &mut Context<Self>,
 7903    ) {
 7904        let lsp_logs = cx
 7905            .try_global::<GlobalLogStore>()
 7906            .map(|lsp_store| lsp_store.0.clone());
 7907
 7908        self.language_server_statuses = language_servers
 7909            .into_iter()
 7910            .zip(server_capabilities)
 7911            .map(|(server, server_capabilities)| {
 7912                let server_id = LanguageServerId(server.id as usize);
 7913                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7914                    self.lsp_server_capabilities
 7915                        .insert(server_id, server_capabilities);
 7916                }
 7917
 7918                let name = LanguageServerName::from_proto(server.name);
 7919                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7920
 7921                if let Some(lsp_logs) = &lsp_logs {
 7922                    lsp_logs.update(cx, |lsp_logs, cx| {
 7923                        lsp_logs.add_language_server(
 7924                            // Only remote clients get their language servers set from proto
 7925                            LanguageServerKind::Remote {
 7926                                project: project.clone(),
 7927                            },
 7928                            server_id,
 7929                            Some(name.clone()),
 7930                            worktree,
 7931                            None,
 7932                            cx,
 7933                        );
 7934                    });
 7935                }
 7936
 7937                (
 7938                    server_id,
 7939                    LanguageServerStatus {
 7940                        name,
 7941                        pending_work: Default::default(),
 7942                        has_pending_diagnostic_updates: false,
 7943                        progress_tokens: Default::default(),
 7944                        worktree,
 7945                    },
 7946                )
 7947            })
 7948            .collect();
 7949    }
 7950
 7951    #[cfg(test)]
 7952    pub fn update_diagnostic_entries(
 7953        &mut self,
 7954        server_id: LanguageServerId,
 7955        abs_path: PathBuf,
 7956        result_id: Option<String>,
 7957        version: Option<i32>,
 7958        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7959        cx: &mut Context<Self>,
 7960    ) -> anyhow::Result<()> {
 7961        self.merge_diagnostic_entries(
 7962            vec![DocumentDiagnosticsUpdate {
 7963                diagnostics: DocumentDiagnostics {
 7964                    diagnostics,
 7965                    document_abs_path: abs_path,
 7966                    version,
 7967                },
 7968                result_id,
 7969                server_id,
 7970                disk_based_sources: Cow::Borrowed(&[]),
 7971            }],
 7972            |_, _, _| false,
 7973            cx,
 7974        )?;
 7975        Ok(())
 7976    }
 7977
 7978    pub fn merge_diagnostic_entries<'a>(
 7979        &mut self,
 7980        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7981        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7982        cx: &mut Context<Self>,
 7983    ) -> anyhow::Result<()> {
 7984        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7985        let mut updated_diagnostics_paths = HashMap::default();
 7986        for mut update in diagnostic_updates {
 7987            let abs_path = &update.diagnostics.document_abs_path;
 7988            let server_id = update.server_id;
 7989            let Some((worktree, relative_path)) =
 7990                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7991            else {
 7992                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7993                return Ok(());
 7994            };
 7995
 7996            let worktree_id = worktree.read(cx).id();
 7997            let project_path = ProjectPath {
 7998                worktree_id,
 7999                path: relative_path,
 8000            };
 8001
 8002            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8003                let snapshot = buffer_handle.read(cx).snapshot();
 8004                let buffer = buffer_handle.read(cx);
 8005                let reused_diagnostics = buffer
 8006                    .buffer_diagnostics(Some(server_id))
 8007                    .iter()
 8008                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8009                    .map(|v| {
 8010                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8011                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8012                        DiagnosticEntry {
 8013                            range: start..end,
 8014                            diagnostic: v.diagnostic.clone(),
 8015                        }
 8016                    })
 8017                    .collect::<Vec<_>>();
 8018
 8019                self.as_local_mut()
 8020                    .context("cannot merge diagnostics on a remote LspStore")?
 8021                    .update_buffer_diagnostics(
 8022                        &buffer_handle,
 8023                        server_id,
 8024                        update.result_id,
 8025                        update.diagnostics.version,
 8026                        update.diagnostics.diagnostics.clone(),
 8027                        reused_diagnostics.clone(),
 8028                        cx,
 8029                    )?;
 8030
 8031                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8032            }
 8033
 8034            let updated = worktree.update(cx, |worktree, cx| {
 8035                self.update_worktree_diagnostics(
 8036                    worktree.id(),
 8037                    server_id,
 8038                    project_path.path.clone(),
 8039                    update.diagnostics.diagnostics,
 8040                    cx,
 8041                )
 8042            })?;
 8043            match updated {
 8044                ControlFlow::Continue(new_summary) => {
 8045                    if let Some((project_id, new_summary)) = new_summary {
 8046                        match &mut diagnostics_summary {
 8047                            Some(diagnostics_summary) => {
 8048                                diagnostics_summary
 8049                                    .more_summaries
 8050                                    .push(proto::DiagnosticSummary {
 8051                                        path: project_path.path.as_ref().to_proto(),
 8052                                        language_server_id: server_id.0 as u64,
 8053                                        error_count: new_summary.error_count,
 8054                                        warning_count: new_summary.warning_count,
 8055                                    })
 8056                            }
 8057                            None => {
 8058                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8059                                    project_id,
 8060                                    worktree_id: worktree_id.to_proto(),
 8061                                    summary: Some(proto::DiagnosticSummary {
 8062                                        path: project_path.path.as_ref().to_proto(),
 8063                                        language_server_id: server_id.0 as u64,
 8064                                        error_count: new_summary.error_count,
 8065                                        warning_count: new_summary.warning_count,
 8066                                    }),
 8067                                    more_summaries: Vec::new(),
 8068                                })
 8069                            }
 8070                        }
 8071                    }
 8072                    updated_diagnostics_paths
 8073                        .entry(server_id)
 8074                        .or_insert_with(Vec::new)
 8075                        .push(project_path);
 8076                }
 8077                ControlFlow::Break(()) => {}
 8078            }
 8079        }
 8080
 8081        if let Some((diagnostics_summary, (downstream_client, _))) =
 8082            diagnostics_summary.zip(self.downstream_client.as_ref())
 8083        {
 8084            downstream_client.send(diagnostics_summary).log_err();
 8085        }
 8086        for (server_id, paths) in updated_diagnostics_paths {
 8087            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8088        }
 8089        Ok(())
 8090    }
 8091
 8092    fn update_worktree_diagnostics(
 8093        &mut self,
 8094        worktree_id: WorktreeId,
 8095        server_id: LanguageServerId,
 8096        path_in_worktree: Arc<RelPath>,
 8097        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8098        _: &mut Context<Worktree>,
 8099    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8100        let local = match &mut self.mode {
 8101            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8102            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8103        };
 8104
 8105        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8106        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8107        let summaries_by_server_id = summaries_for_tree
 8108            .entry(path_in_worktree.clone())
 8109            .or_default();
 8110
 8111        let old_summary = summaries_by_server_id
 8112            .remove(&server_id)
 8113            .unwrap_or_default();
 8114
 8115        let new_summary = DiagnosticSummary::new(&diagnostics);
 8116        if new_summary.is_empty() {
 8117            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8118            {
 8119                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8120                    diagnostics_by_server_id.remove(ix);
 8121                }
 8122                if diagnostics_by_server_id.is_empty() {
 8123                    diagnostics_for_tree.remove(&path_in_worktree);
 8124                }
 8125            }
 8126        } else {
 8127            summaries_by_server_id.insert(server_id, new_summary);
 8128            let diagnostics_by_server_id = diagnostics_for_tree
 8129                .entry(path_in_worktree.clone())
 8130                .or_default();
 8131            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8132                Ok(ix) => {
 8133                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8134                }
 8135                Err(ix) => {
 8136                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8137                }
 8138            }
 8139        }
 8140
 8141        if !old_summary.is_empty() || !new_summary.is_empty() {
 8142            if let Some((_, project_id)) = &self.downstream_client {
 8143                Ok(ControlFlow::Continue(Some((
 8144                    *project_id,
 8145                    proto::DiagnosticSummary {
 8146                        path: path_in_worktree.to_proto(),
 8147                        language_server_id: server_id.0 as u64,
 8148                        error_count: new_summary.error_count as u32,
 8149                        warning_count: new_summary.warning_count as u32,
 8150                    },
 8151                ))))
 8152            } else {
 8153                Ok(ControlFlow::Continue(None))
 8154            }
 8155        } else {
 8156            Ok(ControlFlow::Break(()))
 8157        }
 8158    }
 8159
 8160    pub fn open_buffer_for_symbol(
 8161        &mut self,
 8162        symbol: &Symbol,
 8163        cx: &mut Context<Self>,
 8164    ) -> Task<Result<Entity<Buffer>>> {
 8165        if let Some((client, project_id)) = self.upstream_client() {
 8166            let request = client.request(proto::OpenBufferForSymbol {
 8167                project_id,
 8168                symbol: Some(Self::serialize_symbol(symbol)),
 8169            });
 8170            cx.spawn(async move |this, cx| {
 8171                let response = request.await?;
 8172                let buffer_id = BufferId::new(response.buffer_id)?;
 8173                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8174                    .await
 8175            })
 8176        } else if let Some(local) = self.as_local() {
 8177            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8178                seed.worktree_id == symbol.source_worktree_id
 8179                    && state.id == symbol.source_language_server_id
 8180                    && symbol.language_server_name == seed.name
 8181            });
 8182            if !is_valid {
 8183                return Task::ready(Err(anyhow!(
 8184                    "language server for worktree and language not found"
 8185                )));
 8186            };
 8187
 8188            let symbol_abs_path = match &symbol.path {
 8189                SymbolLocation::InProject(project_path) => self
 8190                    .worktree_store
 8191                    .read(cx)
 8192                    .absolutize(&project_path, cx)
 8193                    .context("no such worktree"),
 8194                SymbolLocation::OutsideProject {
 8195                    abs_path,
 8196                    signature: _,
 8197                } => Ok(abs_path.to_path_buf()),
 8198            };
 8199            let symbol_abs_path = match symbol_abs_path {
 8200                Ok(abs_path) => abs_path,
 8201                Err(err) => return Task::ready(Err(err)),
 8202            };
 8203            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8204                uri
 8205            } else {
 8206                return Task::ready(Err(anyhow!("invalid symbol path")));
 8207            };
 8208
 8209            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8210        } else {
 8211            Task::ready(Err(anyhow!("no upstream client or local store")))
 8212        }
 8213    }
 8214
 8215    pub(crate) fn open_local_buffer_via_lsp(
 8216        &mut self,
 8217        abs_path: lsp::Uri,
 8218        language_server_id: LanguageServerId,
 8219        cx: &mut Context<Self>,
 8220    ) -> Task<Result<Entity<Buffer>>> {
 8221        cx.spawn(async move |lsp_store, cx| {
 8222            // Escape percent-encoded string.
 8223            let current_scheme = abs_path.scheme().to_owned();
 8224            // Uri is immutable, so we can't modify the scheme
 8225
 8226            let abs_path = abs_path
 8227                .to_file_path()
 8228                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8229            let p = abs_path.clone();
 8230            let yarn_worktree = lsp_store
 8231                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8232                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8233                        cx.spawn(async move |this, cx| {
 8234                            let t = this
 8235                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8236                                .ok()?;
 8237                            t.await
 8238                        })
 8239                    }),
 8240                    None => Task::ready(None),
 8241                })?
 8242                .await;
 8243            let (worktree_root_target, known_relative_path) =
 8244                if let Some((zip_root, relative_path)) = yarn_worktree {
 8245                    (zip_root, Some(relative_path))
 8246                } else {
 8247                    (Arc::<Path>::from(abs_path.as_path()), None)
 8248                };
 8249            let (worktree, relative_path) = if let Some(result) =
 8250                lsp_store.update(cx, |lsp_store, cx| {
 8251                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8252                        worktree_store.find_worktree(&worktree_root_target, cx)
 8253                    })
 8254                })? {
 8255                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8256                (result.0, relative_path)
 8257            } else {
 8258                let worktree = lsp_store
 8259                    .update(cx, |lsp_store, cx| {
 8260                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8261                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8262                        })
 8263                    })?
 8264                    .await?;
 8265                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8266                    lsp_store
 8267                        .update(cx, |lsp_store, cx| {
 8268                            if let Some(local) = lsp_store.as_local_mut() {
 8269                                local.register_language_server_for_invisible_worktree(
 8270                                    &worktree,
 8271                                    language_server_id,
 8272                                    cx,
 8273                                )
 8274                            }
 8275                        })
 8276                        .ok();
 8277                }
 8278                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8279                let relative_path = if let Some(known_path) = known_relative_path {
 8280                    known_path
 8281                } else {
 8282                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8283                        .into_arc()
 8284                };
 8285                (worktree, relative_path)
 8286            };
 8287            let project_path = ProjectPath {
 8288                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8289                path: relative_path,
 8290            };
 8291            lsp_store
 8292                .update(cx, |lsp_store, cx| {
 8293                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8294                        buffer_store.open_buffer(project_path, cx)
 8295                    })
 8296                })?
 8297                .await
 8298        })
 8299    }
 8300
 8301    fn request_multiple_lsp_locally<P, R>(
 8302        &mut self,
 8303        buffer: &Entity<Buffer>,
 8304        position: Option<P>,
 8305        request: R,
 8306        cx: &mut Context<Self>,
 8307    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8308    where
 8309        P: ToOffset,
 8310        R: LspCommand + Clone,
 8311        <R::LspRequest as lsp::request::Request>::Result: Send,
 8312        <R::LspRequest as lsp::request::Request>::Params: Send,
 8313    {
 8314        let Some(local) = self.as_local() else {
 8315            return Task::ready(Vec::new());
 8316        };
 8317
 8318        let snapshot = buffer.read(cx).snapshot();
 8319        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8320
 8321        let server_ids = buffer.update(cx, |buffer, cx| {
 8322            local
 8323                .language_servers_for_buffer(buffer, cx)
 8324                .filter(|(adapter, _)| {
 8325                    scope
 8326                        .as_ref()
 8327                        .map(|scope| scope.language_allowed(&adapter.name))
 8328                        .unwrap_or(true)
 8329                })
 8330                .map(|(_, server)| server.server_id())
 8331                .filter(|server_id| {
 8332                    self.as_local().is_none_or(|local| {
 8333                        local
 8334                            .buffers_opened_in_servers
 8335                            .get(&snapshot.remote_id())
 8336                            .is_some_and(|servers| servers.contains(server_id))
 8337                    })
 8338                })
 8339                .collect::<Vec<_>>()
 8340        });
 8341
 8342        let mut response_results = server_ids
 8343            .into_iter()
 8344            .map(|server_id| {
 8345                let task = self.request_lsp(
 8346                    buffer.clone(),
 8347                    LanguageServerToQuery::Other(server_id),
 8348                    request.clone(),
 8349                    cx,
 8350                );
 8351                async move { (server_id, task.await) }
 8352            })
 8353            .collect::<FuturesUnordered<_>>();
 8354
 8355        cx.background_spawn(async move {
 8356            let mut responses = Vec::with_capacity(response_results.len());
 8357            while let Some((server_id, response_result)) = response_results.next().await {
 8358                match response_result {
 8359                    Ok(response) => responses.push((server_id, response)),
 8360                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8361                }
 8362            }
 8363            responses
 8364        })
 8365    }
 8366
 8367    async fn handle_lsp_command<T: LspCommand>(
 8368        this: Entity<Self>,
 8369        envelope: TypedEnvelope<T::ProtoRequest>,
 8370        mut cx: AsyncApp,
 8371    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8372    where
 8373        <T::LspRequest as lsp::request::Request>::Params: Send,
 8374        <T::LspRequest as lsp::request::Request>::Result: Send,
 8375    {
 8376        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8377        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8378        let buffer_handle = this.update(&mut cx, |this, cx| {
 8379            this.buffer_store.read(cx).get_existing(buffer_id)
 8380        })??;
 8381        let request = T::from_proto(
 8382            envelope.payload,
 8383            this.clone(),
 8384            buffer_handle.clone(),
 8385            cx.clone(),
 8386        )
 8387        .await?;
 8388        let response = this
 8389            .update(&mut cx, |this, cx| {
 8390                this.request_lsp(
 8391                    buffer_handle.clone(),
 8392                    LanguageServerToQuery::FirstCapable,
 8393                    request,
 8394                    cx,
 8395                )
 8396            })?
 8397            .await?;
 8398        this.update(&mut cx, |this, cx| {
 8399            Ok(T::response_to_proto(
 8400                response,
 8401                this,
 8402                sender_id,
 8403                &buffer_handle.read(cx).version(),
 8404                cx,
 8405            ))
 8406        })?
 8407    }
 8408
 8409    async fn handle_lsp_query(
 8410        lsp_store: Entity<Self>,
 8411        envelope: TypedEnvelope<proto::LspQuery>,
 8412        mut cx: AsyncApp,
 8413    ) -> Result<proto::Ack> {
 8414        use proto::lsp_query::Request;
 8415        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8416        let lsp_query = envelope.payload;
 8417        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8418        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8419        match lsp_query.request.context("invalid LSP query request")? {
 8420            Request::GetReferences(get_references) => {
 8421                let position = get_references.position.clone().and_then(deserialize_anchor);
 8422                Self::query_lsp_locally::<GetReferences>(
 8423                    lsp_store,
 8424                    server_id,
 8425                    sender_id,
 8426                    lsp_request_id,
 8427                    get_references,
 8428                    position,
 8429                    &mut cx,
 8430                )
 8431                .await?;
 8432            }
 8433            Request::GetDocumentColor(get_document_color) => {
 8434                Self::query_lsp_locally::<GetDocumentColor>(
 8435                    lsp_store,
 8436                    server_id,
 8437                    sender_id,
 8438                    lsp_request_id,
 8439                    get_document_color,
 8440                    None,
 8441                    &mut cx,
 8442                )
 8443                .await?;
 8444            }
 8445            Request::GetHover(get_hover) => {
 8446                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8447                Self::query_lsp_locally::<GetHover>(
 8448                    lsp_store,
 8449                    server_id,
 8450                    sender_id,
 8451                    lsp_request_id,
 8452                    get_hover,
 8453                    position,
 8454                    &mut cx,
 8455                )
 8456                .await?;
 8457            }
 8458            Request::GetCodeActions(get_code_actions) => {
 8459                Self::query_lsp_locally::<GetCodeActions>(
 8460                    lsp_store,
 8461                    server_id,
 8462                    sender_id,
 8463                    lsp_request_id,
 8464                    get_code_actions,
 8465                    None,
 8466                    &mut cx,
 8467                )
 8468                .await?;
 8469            }
 8470            Request::GetSignatureHelp(get_signature_help) => {
 8471                let position = get_signature_help
 8472                    .position
 8473                    .clone()
 8474                    .and_then(deserialize_anchor);
 8475                Self::query_lsp_locally::<GetSignatureHelp>(
 8476                    lsp_store,
 8477                    server_id,
 8478                    sender_id,
 8479                    lsp_request_id,
 8480                    get_signature_help,
 8481                    position,
 8482                    &mut cx,
 8483                )
 8484                .await?;
 8485            }
 8486            Request::GetCodeLens(get_code_lens) => {
 8487                Self::query_lsp_locally::<GetCodeLens>(
 8488                    lsp_store,
 8489                    server_id,
 8490                    sender_id,
 8491                    lsp_request_id,
 8492                    get_code_lens,
 8493                    None,
 8494                    &mut cx,
 8495                )
 8496                .await?;
 8497            }
 8498            Request::GetDefinition(get_definition) => {
 8499                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8500                Self::query_lsp_locally::<GetDefinitions>(
 8501                    lsp_store,
 8502                    server_id,
 8503                    sender_id,
 8504                    lsp_request_id,
 8505                    get_definition,
 8506                    position,
 8507                    &mut cx,
 8508                )
 8509                .await?;
 8510            }
 8511            Request::GetDeclaration(get_declaration) => {
 8512                let position = get_declaration
 8513                    .position
 8514                    .clone()
 8515                    .and_then(deserialize_anchor);
 8516                Self::query_lsp_locally::<GetDeclarations>(
 8517                    lsp_store,
 8518                    server_id,
 8519                    sender_id,
 8520                    lsp_request_id,
 8521                    get_declaration,
 8522                    position,
 8523                    &mut cx,
 8524                )
 8525                .await?;
 8526            }
 8527            Request::GetTypeDefinition(get_type_definition) => {
 8528                let position = get_type_definition
 8529                    .position
 8530                    .clone()
 8531                    .and_then(deserialize_anchor);
 8532                Self::query_lsp_locally::<GetTypeDefinitions>(
 8533                    lsp_store,
 8534                    server_id,
 8535                    sender_id,
 8536                    lsp_request_id,
 8537                    get_type_definition,
 8538                    position,
 8539                    &mut cx,
 8540                )
 8541                .await?;
 8542            }
 8543            Request::GetImplementation(get_implementation) => {
 8544                let position = get_implementation
 8545                    .position
 8546                    .clone()
 8547                    .and_then(deserialize_anchor);
 8548                Self::query_lsp_locally::<GetImplementations>(
 8549                    lsp_store,
 8550                    server_id,
 8551                    sender_id,
 8552                    lsp_request_id,
 8553                    get_implementation,
 8554                    position,
 8555                    &mut cx,
 8556                )
 8557                .await?;
 8558            }
 8559            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8560                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8561                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8562                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8563                    this.buffer_store.read(cx).get_existing(buffer_id)
 8564                })??;
 8565                buffer
 8566                    .update(&mut cx, |buffer, _| {
 8567                        buffer.wait_for_version(version.clone())
 8568                    })?
 8569                    .await?;
 8570                lsp_store.update(&mut cx, |lsp_store, cx| {
 8571                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8572                    let key = LspKey {
 8573                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8574                        server_queried: server_id,
 8575                    };
 8576                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8577                    ) {
 8578                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8579                            lsp_requests.clear();
 8580                        };
 8581                    }
 8582
 8583                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8584                    existing_queries.insert(
 8585                        lsp_request_id,
 8586                        cx.spawn(async move |lsp_store, cx| {
 8587                            let diagnostics_pull = lsp_store
 8588                                .update(cx, |lsp_store, cx| {
 8589                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8590                                })
 8591                                .ok();
 8592                            if let Some(diagnostics_pull) = diagnostics_pull {
 8593                                match diagnostics_pull.await {
 8594                                    Ok(()) => {}
 8595                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8596                                };
 8597                            }
 8598                        }),
 8599                    );
 8600                })?;
 8601            }
 8602            Request::InlayHints(inlay_hints) => {
 8603                let query_start = inlay_hints
 8604                    .start
 8605                    .clone()
 8606                    .and_then(deserialize_anchor)
 8607                    .context("invalid inlay hints range start")?;
 8608                let query_end = inlay_hints
 8609                    .end
 8610                    .clone()
 8611                    .and_then(deserialize_anchor)
 8612                    .context("invalid inlay hints range end")?;
 8613                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8614                    &lsp_store,
 8615                    server_id,
 8616                    lsp_request_id,
 8617                    &inlay_hints,
 8618                    query_start..query_end,
 8619                    &mut cx,
 8620                )
 8621                .await
 8622                .context("preparing inlay hints request")?;
 8623                Self::query_lsp_locally::<InlayHints>(
 8624                    lsp_store,
 8625                    server_id,
 8626                    sender_id,
 8627                    lsp_request_id,
 8628                    inlay_hints,
 8629                    None,
 8630                    &mut cx,
 8631                )
 8632                .await
 8633                .context("querying for inlay hints")?
 8634            }
 8635        }
 8636        Ok(proto::Ack {})
 8637    }
 8638
 8639    async fn handle_lsp_query_response(
 8640        lsp_store: Entity<Self>,
 8641        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8642        cx: AsyncApp,
 8643    ) -> Result<()> {
 8644        lsp_store.read_with(&cx, |lsp_store, _| {
 8645            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8646                upstream_client.handle_lsp_response(envelope.clone());
 8647            }
 8648        })?;
 8649        Ok(())
 8650    }
 8651
 8652    async fn handle_apply_code_action(
 8653        this: Entity<Self>,
 8654        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8655        mut cx: AsyncApp,
 8656    ) -> Result<proto::ApplyCodeActionResponse> {
 8657        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8658        let action =
 8659            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8660        let apply_code_action = this.update(&mut cx, |this, cx| {
 8661            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8662            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8663            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8664        })??;
 8665
 8666        let project_transaction = apply_code_action.await?;
 8667        let project_transaction = this.update(&mut cx, |this, cx| {
 8668            this.buffer_store.update(cx, |buffer_store, cx| {
 8669                buffer_store.serialize_project_transaction_for_peer(
 8670                    project_transaction,
 8671                    sender_id,
 8672                    cx,
 8673                )
 8674            })
 8675        })?;
 8676        Ok(proto::ApplyCodeActionResponse {
 8677            transaction: Some(project_transaction),
 8678        })
 8679    }
 8680
 8681    async fn handle_register_buffer_with_language_servers(
 8682        this: Entity<Self>,
 8683        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8684        mut cx: AsyncApp,
 8685    ) -> Result<proto::Ack> {
 8686        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8687        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8688        this.update(&mut cx, |this, cx| {
 8689            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8690                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8691                    project_id: upstream_project_id,
 8692                    buffer_id: buffer_id.to_proto(),
 8693                    only_servers: envelope.payload.only_servers,
 8694                });
 8695            }
 8696
 8697            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8698                anyhow::bail!("buffer is not open");
 8699            };
 8700
 8701            let handle = this.register_buffer_with_language_servers(
 8702                &buffer,
 8703                envelope
 8704                    .payload
 8705                    .only_servers
 8706                    .into_iter()
 8707                    .filter_map(|selector| {
 8708                        Some(match selector.selector? {
 8709                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8710                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8711                            }
 8712                            proto::language_server_selector::Selector::Name(name) => {
 8713                                LanguageServerSelector::Name(LanguageServerName(
 8714                                    SharedString::from(name),
 8715                                ))
 8716                            }
 8717                        })
 8718                    })
 8719                    .collect(),
 8720                false,
 8721                cx,
 8722            );
 8723            this.buffer_store().update(cx, |buffer_store, _| {
 8724                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8725            });
 8726
 8727            Ok(())
 8728        })??;
 8729        Ok(proto::Ack {})
 8730    }
 8731
 8732    async fn handle_rename_project_entry(
 8733        this: Entity<Self>,
 8734        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8735        mut cx: AsyncApp,
 8736    ) -> Result<proto::ProjectEntryResponse> {
 8737        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8738        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8739        let new_path =
 8740            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8741
 8742        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8743            .update(&mut cx, |this, cx| {
 8744                let (worktree, entry) = this
 8745                    .worktree_store
 8746                    .read(cx)
 8747                    .worktree_and_entry_for_id(entry_id, cx)?;
 8748                let new_worktree = this
 8749                    .worktree_store
 8750                    .read(cx)
 8751                    .worktree_for_id(new_worktree_id, cx)?;
 8752                Some((
 8753                    this.worktree_store.clone(),
 8754                    worktree,
 8755                    new_worktree,
 8756                    entry.clone(),
 8757                ))
 8758            })?
 8759            .context("worktree not found")?;
 8760        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8761            (worktree.absolutize(&old_entry.path), worktree.id())
 8762        })?;
 8763        let new_abs_path =
 8764            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8765
 8766        let _transaction = Self::will_rename_entry(
 8767            this.downgrade(),
 8768            old_worktree_id,
 8769            &old_abs_path,
 8770            &new_abs_path,
 8771            old_entry.is_dir(),
 8772            cx.clone(),
 8773        )
 8774        .await;
 8775        let response = WorktreeStore::handle_rename_project_entry(
 8776            worktree_store,
 8777            envelope.payload,
 8778            cx.clone(),
 8779        )
 8780        .await;
 8781        this.read_with(&cx, |this, _| {
 8782            this.did_rename_entry(
 8783                old_worktree_id,
 8784                &old_abs_path,
 8785                &new_abs_path,
 8786                old_entry.is_dir(),
 8787            );
 8788        })
 8789        .ok();
 8790        response
 8791    }
 8792
 8793    async fn handle_update_diagnostic_summary(
 8794        this: Entity<Self>,
 8795        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8796        mut cx: AsyncApp,
 8797    ) -> Result<()> {
 8798        this.update(&mut cx, |lsp_store, cx| {
 8799            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8800            let mut updated_diagnostics_paths = HashMap::default();
 8801            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8802            for message_summary in envelope
 8803                .payload
 8804                .summary
 8805                .into_iter()
 8806                .chain(envelope.payload.more_summaries)
 8807            {
 8808                let project_path = ProjectPath {
 8809                    worktree_id,
 8810                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8811                };
 8812                let path = project_path.path.clone();
 8813                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8814                let summary = DiagnosticSummary {
 8815                    error_count: message_summary.error_count as usize,
 8816                    warning_count: message_summary.warning_count as usize,
 8817                };
 8818
 8819                if summary.is_empty() {
 8820                    if let Some(worktree_summaries) =
 8821                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8822                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8823                    {
 8824                        summaries.remove(&server_id);
 8825                        if summaries.is_empty() {
 8826                            worktree_summaries.remove(&path);
 8827                        }
 8828                    }
 8829                } else {
 8830                    lsp_store
 8831                        .diagnostic_summaries
 8832                        .entry(worktree_id)
 8833                        .or_default()
 8834                        .entry(path)
 8835                        .or_default()
 8836                        .insert(server_id, summary);
 8837                }
 8838
 8839                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8840                    match &mut diagnostics_summary {
 8841                        Some(diagnostics_summary) => {
 8842                            diagnostics_summary
 8843                                .more_summaries
 8844                                .push(proto::DiagnosticSummary {
 8845                                    path: project_path.path.as_ref().to_proto(),
 8846                                    language_server_id: server_id.0 as u64,
 8847                                    error_count: summary.error_count as u32,
 8848                                    warning_count: summary.warning_count as u32,
 8849                                })
 8850                        }
 8851                        None => {
 8852                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8853                                project_id: *project_id,
 8854                                worktree_id: worktree_id.to_proto(),
 8855                                summary: Some(proto::DiagnosticSummary {
 8856                                    path: project_path.path.as_ref().to_proto(),
 8857                                    language_server_id: server_id.0 as u64,
 8858                                    error_count: summary.error_count as u32,
 8859                                    warning_count: summary.warning_count as u32,
 8860                                }),
 8861                                more_summaries: Vec::new(),
 8862                            })
 8863                        }
 8864                    }
 8865                }
 8866                updated_diagnostics_paths
 8867                    .entry(server_id)
 8868                    .or_insert_with(Vec::new)
 8869                    .push(project_path);
 8870            }
 8871
 8872            if let Some((diagnostics_summary, (downstream_client, _))) =
 8873                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8874            {
 8875                downstream_client.send(diagnostics_summary).log_err();
 8876            }
 8877            for (server_id, paths) in updated_diagnostics_paths {
 8878                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8879            }
 8880            Ok(())
 8881        })?
 8882    }
 8883
 8884    async fn handle_start_language_server(
 8885        lsp_store: Entity<Self>,
 8886        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8887        mut cx: AsyncApp,
 8888    ) -> Result<()> {
 8889        let server = envelope.payload.server.context("invalid server")?;
 8890        let server_capabilities =
 8891            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8892                .with_context(|| {
 8893                    format!(
 8894                        "incorrect server capabilities {}",
 8895                        envelope.payload.capabilities
 8896                    )
 8897                })?;
 8898        lsp_store.update(&mut cx, |lsp_store, cx| {
 8899            let server_id = LanguageServerId(server.id as usize);
 8900            let server_name = LanguageServerName::from_proto(server.name.clone());
 8901            lsp_store
 8902                .lsp_server_capabilities
 8903                .insert(server_id, server_capabilities);
 8904            lsp_store.language_server_statuses.insert(
 8905                server_id,
 8906                LanguageServerStatus {
 8907                    name: server_name.clone(),
 8908                    pending_work: Default::default(),
 8909                    has_pending_diagnostic_updates: false,
 8910                    progress_tokens: Default::default(),
 8911                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8912                },
 8913            );
 8914            cx.emit(LspStoreEvent::LanguageServerAdded(
 8915                server_id,
 8916                server_name,
 8917                server.worktree_id.map(WorktreeId::from_proto),
 8918            ));
 8919            cx.notify();
 8920        })?;
 8921        Ok(())
 8922    }
 8923
 8924    async fn handle_update_language_server(
 8925        lsp_store: Entity<Self>,
 8926        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8927        mut cx: AsyncApp,
 8928    ) -> Result<()> {
 8929        lsp_store.update(&mut cx, |lsp_store, cx| {
 8930            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8931
 8932            match envelope.payload.variant.context("invalid variant")? {
 8933                proto::update_language_server::Variant::WorkStart(payload) => {
 8934                    lsp_store.on_lsp_work_start(
 8935                        language_server_id,
 8936                        payload.token,
 8937                        LanguageServerProgress {
 8938                            title: payload.title,
 8939                            is_disk_based_diagnostics_progress: false,
 8940                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8941                            message: payload.message,
 8942                            percentage: payload.percentage.map(|p| p as usize),
 8943                            last_update_at: cx.background_executor().now(),
 8944                        },
 8945                        cx,
 8946                    );
 8947                }
 8948                proto::update_language_server::Variant::WorkProgress(payload) => {
 8949                    lsp_store.on_lsp_work_progress(
 8950                        language_server_id,
 8951                        payload.token,
 8952                        LanguageServerProgress {
 8953                            title: None,
 8954                            is_disk_based_diagnostics_progress: false,
 8955                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8956                            message: payload.message,
 8957                            percentage: payload.percentage.map(|p| p as usize),
 8958                            last_update_at: cx.background_executor().now(),
 8959                        },
 8960                        cx,
 8961                    );
 8962                }
 8963
 8964                proto::update_language_server::Variant::WorkEnd(payload) => {
 8965                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8966                }
 8967
 8968                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8969                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8970                }
 8971
 8972                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8973                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8974                }
 8975
 8976                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8977                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8978                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8979                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8980                        language_server_id,
 8981                        name: envelope
 8982                            .payload
 8983                            .server_name
 8984                            .map(SharedString::new)
 8985                            .map(LanguageServerName),
 8986                        message: non_lsp,
 8987                    });
 8988                }
 8989            }
 8990
 8991            Ok(())
 8992        })?
 8993    }
 8994
 8995    async fn handle_language_server_log(
 8996        this: Entity<Self>,
 8997        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8998        mut cx: AsyncApp,
 8999    ) -> Result<()> {
 9000        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9001        let log_type = envelope
 9002            .payload
 9003            .log_type
 9004            .map(LanguageServerLogType::from_proto)
 9005            .context("invalid language server log type")?;
 9006
 9007        let message = envelope.payload.message;
 9008
 9009        this.update(&mut cx, |_, cx| {
 9010            cx.emit(LspStoreEvent::LanguageServerLog(
 9011                language_server_id,
 9012                log_type,
 9013                message,
 9014            ));
 9015        })
 9016    }
 9017
 9018    async fn handle_lsp_ext_cancel_flycheck(
 9019        lsp_store: Entity<Self>,
 9020        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9021        cx: AsyncApp,
 9022    ) -> Result<proto::Ack> {
 9023        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9024        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9025            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9026                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9027            } else {
 9028                None
 9029            }
 9030        })?;
 9031        if let Some(task) = task {
 9032            task.context("handling lsp ext cancel flycheck")?;
 9033        }
 9034
 9035        Ok(proto::Ack {})
 9036    }
 9037
 9038    async fn handle_lsp_ext_run_flycheck(
 9039        lsp_store: Entity<Self>,
 9040        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9041        mut cx: AsyncApp,
 9042    ) -> Result<proto::Ack> {
 9043        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9044        lsp_store.update(&mut cx, |lsp_store, cx| {
 9045            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9046                let text_document = if envelope.payload.current_file_only {
 9047                    let buffer_id = envelope
 9048                        .payload
 9049                        .buffer_id
 9050                        .map(|id| BufferId::new(id))
 9051                        .transpose()?;
 9052                    buffer_id
 9053                        .and_then(|buffer_id| {
 9054                            lsp_store
 9055                                .buffer_store()
 9056                                .read(cx)
 9057                                .get(buffer_id)
 9058                                .and_then(|buffer| {
 9059                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9060                                })
 9061                                .map(|path| make_text_document_identifier(&path))
 9062                        })
 9063                        .transpose()?
 9064                } else {
 9065                    None
 9066                };
 9067                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9068                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9069                )?;
 9070            }
 9071            anyhow::Ok(())
 9072        })??;
 9073
 9074        Ok(proto::Ack {})
 9075    }
 9076
 9077    async fn handle_lsp_ext_clear_flycheck(
 9078        lsp_store: Entity<Self>,
 9079        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9080        cx: AsyncApp,
 9081    ) -> Result<proto::Ack> {
 9082        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9083        lsp_store
 9084            .read_with(&cx, |lsp_store, _| {
 9085                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9086                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9087                } else {
 9088                    None
 9089                }
 9090            })
 9091            .context("handling lsp ext clear flycheck")?;
 9092
 9093        Ok(proto::Ack {})
 9094    }
 9095
 9096    pub fn disk_based_diagnostics_started(
 9097        &mut self,
 9098        language_server_id: LanguageServerId,
 9099        cx: &mut Context<Self>,
 9100    ) {
 9101        if let Some(language_server_status) =
 9102            self.language_server_statuses.get_mut(&language_server_id)
 9103        {
 9104            language_server_status.has_pending_diagnostic_updates = true;
 9105        }
 9106
 9107        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9108        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9109            language_server_id,
 9110            name: self
 9111                .language_server_adapter_for_id(language_server_id)
 9112                .map(|adapter| adapter.name()),
 9113            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9114                Default::default(),
 9115            ),
 9116        })
 9117    }
 9118
 9119    pub fn disk_based_diagnostics_finished(
 9120        &mut self,
 9121        language_server_id: LanguageServerId,
 9122        cx: &mut Context<Self>,
 9123    ) {
 9124        if let Some(language_server_status) =
 9125            self.language_server_statuses.get_mut(&language_server_id)
 9126        {
 9127            language_server_status.has_pending_diagnostic_updates = false;
 9128        }
 9129
 9130        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9131        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9132            language_server_id,
 9133            name: self
 9134                .language_server_adapter_for_id(language_server_id)
 9135                .map(|adapter| adapter.name()),
 9136            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9137                Default::default(),
 9138            ),
 9139        })
 9140    }
 9141
 9142    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9143    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9144    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9145    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9146    // the language server might take some time to publish diagnostics.
 9147    fn simulate_disk_based_diagnostics_events_if_needed(
 9148        &mut self,
 9149        language_server_id: LanguageServerId,
 9150        cx: &mut Context<Self>,
 9151    ) {
 9152        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9153
 9154        let Some(LanguageServerState::Running {
 9155            simulate_disk_based_diagnostics_completion,
 9156            adapter,
 9157            ..
 9158        }) = self
 9159            .as_local_mut()
 9160            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9161        else {
 9162            return;
 9163        };
 9164
 9165        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9166            return;
 9167        }
 9168
 9169        let prev_task =
 9170            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9171                cx.background_executor()
 9172                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9173                    .await;
 9174
 9175                this.update(cx, |this, cx| {
 9176                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9177
 9178                    if let Some(LanguageServerState::Running {
 9179                        simulate_disk_based_diagnostics_completion,
 9180                        ..
 9181                    }) = this.as_local_mut().and_then(|local_store| {
 9182                        local_store.language_servers.get_mut(&language_server_id)
 9183                    }) {
 9184                        *simulate_disk_based_diagnostics_completion = None;
 9185                    }
 9186                })
 9187                .ok();
 9188            }));
 9189
 9190        if prev_task.is_none() {
 9191            self.disk_based_diagnostics_started(language_server_id, cx);
 9192        }
 9193    }
 9194
 9195    pub fn language_server_statuses(
 9196        &self,
 9197    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9198        self.language_server_statuses
 9199            .iter()
 9200            .map(|(key, value)| (*key, value))
 9201    }
 9202
 9203    pub(super) fn did_rename_entry(
 9204        &self,
 9205        worktree_id: WorktreeId,
 9206        old_path: &Path,
 9207        new_path: &Path,
 9208        is_dir: bool,
 9209    ) {
 9210        maybe!({
 9211            let local_store = self.as_local()?;
 9212
 9213            let old_uri = lsp::Uri::from_file_path(old_path)
 9214                .ok()
 9215                .map(|uri| uri.to_string())?;
 9216            let new_uri = lsp::Uri::from_file_path(new_path)
 9217                .ok()
 9218                .map(|uri| uri.to_string())?;
 9219
 9220            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9221                let Some(filter) = local_store
 9222                    .language_server_paths_watched_for_rename
 9223                    .get(&language_server.server_id())
 9224                else {
 9225                    continue;
 9226                };
 9227
 9228                if filter.should_send_did_rename(&old_uri, is_dir) {
 9229                    language_server
 9230                        .notify::<DidRenameFiles>(RenameFilesParams {
 9231                            files: vec![FileRename {
 9232                                old_uri: old_uri.clone(),
 9233                                new_uri: new_uri.clone(),
 9234                            }],
 9235                        })
 9236                        .ok();
 9237                }
 9238            }
 9239            Some(())
 9240        });
 9241    }
 9242
 9243    pub(super) fn will_rename_entry(
 9244        this: WeakEntity<Self>,
 9245        worktree_id: WorktreeId,
 9246        old_path: &Path,
 9247        new_path: &Path,
 9248        is_dir: bool,
 9249        cx: AsyncApp,
 9250    ) -> Task<ProjectTransaction> {
 9251        let old_uri = lsp::Uri::from_file_path(old_path)
 9252            .ok()
 9253            .map(|uri| uri.to_string());
 9254        let new_uri = lsp::Uri::from_file_path(new_path)
 9255            .ok()
 9256            .map(|uri| uri.to_string());
 9257        cx.spawn(async move |cx| {
 9258            let mut tasks = vec![];
 9259            this.update(cx, |this, cx| {
 9260                let local_store = this.as_local()?;
 9261                let old_uri = old_uri?;
 9262                let new_uri = new_uri?;
 9263                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9264                    let Some(filter) = local_store
 9265                        .language_server_paths_watched_for_rename
 9266                        .get(&language_server.server_id())
 9267                    else {
 9268                        continue;
 9269                    };
 9270
 9271                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9272                        let apply_edit = cx.spawn({
 9273                            let old_uri = old_uri.clone();
 9274                            let new_uri = new_uri.clone();
 9275                            let language_server = language_server.clone();
 9276                            async move |this, cx| {
 9277                                let edit = language_server
 9278                                    .request::<WillRenameFiles>(RenameFilesParams {
 9279                                        files: vec![FileRename { old_uri, new_uri }],
 9280                                    })
 9281                                    .await
 9282                                    .into_response()
 9283                                    .context("will rename files")
 9284                                    .log_err()
 9285                                    .flatten()?;
 9286
 9287                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9288                                    this.upgrade()?,
 9289                                    edit,
 9290                                    false,
 9291                                    language_server.clone(),
 9292                                    cx,
 9293                                )
 9294                                .await
 9295                                .ok()?;
 9296                                Some(transaction)
 9297                            }
 9298                        });
 9299                        tasks.push(apply_edit);
 9300                    }
 9301                }
 9302                Some(())
 9303            })
 9304            .ok()
 9305            .flatten();
 9306            let mut merged_transaction = ProjectTransaction::default();
 9307            for task in tasks {
 9308                // Await on tasks sequentially so that the order of application of edits is deterministic
 9309                // (at least with regards to the order of registration of language servers)
 9310                if let Some(transaction) = task.await {
 9311                    for (buffer, buffer_transaction) in transaction.0 {
 9312                        merged_transaction.0.insert(buffer, buffer_transaction);
 9313                    }
 9314                }
 9315            }
 9316            merged_transaction
 9317        })
 9318    }
 9319
 9320    fn lsp_notify_abs_paths_changed(
 9321        &mut self,
 9322        server_id: LanguageServerId,
 9323        changes: Vec<PathEvent>,
 9324    ) {
 9325        maybe!({
 9326            let server = self.language_server_for_id(server_id)?;
 9327            let changes = changes
 9328                .into_iter()
 9329                .filter_map(|event| {
 9330                    let typ = match event.kind? {
 9331                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9332                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9333                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9334                    };
 9335                    Some(lsp::FileEvent {
 9336                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9337                        typ,
 9338                    })
 9339                })
 9340                .collect::<Vec<_>>();
 9341            if !changes.is_empty() {
 9342                server
 9343                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9344                        lsp::DidChangeWatchedFilesParams { changes },
 9345                    )
 9346                    .ok();
 9347            }
 9348            Some(())
 9349        });
 9350    }
 9351
 9352    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9353        self.as_local()?.language_server_for_id(id)
 9354    }
 9355
 9356    fn on_lsp_progress(
 9357        &mut self,
 9358        progress: lsp::ProgressParams,
 9359        language_server_id: LanguageServerId,
 9360        disk_based_diagnostics_progress_token: Option<String>,
 9361        cx: &mut Context<Self>,
 9362    ) {
 9363        let token = match progress.token {
 9364            lsp::NumberOrString::String(token) => token,
 9365            lsp::NumberOrString::Number(token) => {
 9366                log::info!("skipping numeric progress token {}", token);
 9367                return;
 9368            }
 9369        };
 9370
 9371        match progress.value {
 9372            lsp::ProgressParamsValue::WorkDone(progress) => {
 9373                self.handle_work_done_progress(
 9374                    progress,
 9375                    language_server_id,
 9376                    disk_based_diagnostics_progress_token,
 9377                    token,
 9378                    cx,
 9379                );
 9380            }
 9381            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9382                let identifier = token.split_once("id:").map(|(_, id)| id.to_owned());
 9383                if let Some(LanguageServerState::Running {
 9384                    workspace_diagnostics_refresh_tasks,
 9385                    ..
 9386                }) = self
 9387                    .as_local_mut()
 9388                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9389                    && let Some(workspace_diagnostics) =
 9390                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9391                {
 9392                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9393                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9394                }
 9395            }
 9396        }
 9397    }
 9398
 9399    fn handle_work_done_progress(
 9400        &mut self,
 9401        progress: lsp::WorkDoneProgress,
 9402        language_server_id: LanguageServerId,
 9403        disk_based_diagnostics_progress_token: Option<String>,
 9404        token: String,
 9405        cx: &mut Context<Self>,
 9406    ) {
 9407        let language_server_status =
 9408            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9409                status
 9410            } else {
 9411                return;
 9412            };
 9413
 9414        if !language_server_status.progress_tokens.contains(&token) {
 9415            return;
 9416        }
 9417
 9418        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9419            .as_ref()
 9420            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9421
 9422        match progress {
 9423            lsp::WorkDoneProgress::Begin(report) => {
 9424                if is_disk_based_diagnostics_progress {
 9425                    self.disk_based_diagnostics_started(language_server_id, cx);
 9426                }
 9427                self.on_lsp_work_start(
 9428                    language_server_id,
 9429                    token.clone(),
 9430                    LanguageServerProgress {
 9431                        title: Some(report.title),
 9432                        is_disk_based_diagnostics_progress,
 9433                        is_cancellable: report.cancellable.unwrap_or(false),
 9434                        message: report.message.clone(),
 9435                        percentage: report.percentage.map(|p| p as usize),
 9436                        last_update_at: cx.background_executor().now(),
 9437                    },
 9438                    cx,
 9439                );
 9440            }
 9441            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9442                language_server_id,
 9443                token,
 9444                LanguageServerProgress {
 9445                    title: None,
 9446                    is_disk_based_diagnostics_progress,
 9447                    is_cancellable: report.cancellable.unwrap_or(false),
 9448                    message: report.message,
 9449                    percentage: report.percentage.map(|p| p as usize),
 9450                    last_update_at: cx.background_executor().now(),
 9451                },
 9452                cx,
 9453            ),
 9454            lsp::WorkDoneProgress::End(_) => {
 9455                language_server_status.progress_tokens.remove(&token);
 9456                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9457                if is_disk_based_diagnostics_progress {
 9458                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9459                }
 9460            }
 9461        }
 9462    }
 9463
 9464    fn on_lsp_work_start(
 9465        &mut self,
 9466        language_server_id: LanguageServerId,
 9467        token: String,
 9468        progress: LanguageServerProgress,
 9469        cx: &mut Context<Self>,
 9470    ) {
 9471        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9472            status.pending_work.insert(token.clone(), progress.clone());
 9473            cx.notify();
 9474        }
 9475        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9476            language_server_id,
 9477            name: self
 9478                .language_server_adapter_for_id(language_server_id)
 9479                .map(|adapter| adapter.name()),
 9480            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9481                token,
 9482                title: progress.title,
 9483                message: progress.message,
 9484                percentage: progress.percentage.map(|p| p as u32),
 9485                is_cancellable: Some(progress.is_cancellable),
 9486            }),
 9487        })
 9488    }
 9489
 9490    fn on_lsp_work_progress(
 9491        &mut self,
 9492        language_server_id: LanguageServerId,
 9493        token: String,
 9494        progress: LanguageServerProgress,
 9495        cx: &mut Context<Self>,
 9496    ) {
 9497        let mut did_update = false;
 9498        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9499            match status.pending_work.entry(token.clone()) {
 9500                btree_map::Entry::Vacant(entry) => {
 9501                    entry.insert(progress.clone());
 9502                    did_update = true;
 9503                }
 9504                btree_map::Entry::Occupied(mut entry) => {
 9505                    let entry = entry.get_mut();
 9506                    if (progress.last_update_at - entry.last_update_at)
 9507                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9508                    {
 9509                        entry.last_update_at = progress.last_update_at;
 9510                        if progress.message.is_some() {
 9511                            entry.message = progress.message.clone();
 9512                        }
 9513                        if progress.percentage.is_some() {
 9514                            entry.percentage = progress.percentage;
 9515                        }
 9516                        if progress.is_cancellable != entry.is_cancellable {
 9517                            entry.is_cancellable = progress.is_cancellable;
 9518                        }
 9519                        did_update = true;
 9520                    }
 9521                }
 9522            }
 9523        }
 9524
 9525        if did_update {
 9526            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9527                language_server_id,
 9528                name: self
 9529                    .language_server_adapter_for_id(language_server_id)
 9530                    .map(|adapter| adapter.name()),
 9531                message: proto::update_language_server::Variant::WorkProgress(
 9532                    proto::LspWorkProgress {
 9533                        token,
 9534                        message: progress.message,
 9535                        percentage: progress.percentage.map(|p| p as u32),
 9536                        is_cancellable: Some(progress.is_cancellable),
 9537                    },
 9538                ),
 9539            })
 9540        }
 9541    }
 9542
 9543    fn on_lsp_work_end(
 9544        &mut self,
 9545        language_server_id: LanguageServerId,
 9546        token: String,
 9547        cx: &mut Context<Self>,
 9548    ) {
 9549        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9550            if let Some(work) = status.pending_work.remove(&token)
 9551                && !work.is_disk_based_diagnostics_progress
 9552            {
 9553                cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
 9554            }
 9555            cx.notify();
 9556        }
 9557
 9558        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9559            language_server_id,
 9560            name: self
 9561                .language_server_adapter_for_id(language_server_id)
 9562                .map(|adapter| adapter.name()),
 9563            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9564        })
 9565    }
 9566
 9567    pub async fn handle_resolve_completion_documentation(
 9568        this: Entity<Self>,
 9569        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9570        mut cx: AsyncApp,
 9571    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9572        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9573
 9574        let completion = this
 9575            .read_with(&cx, |this, cx| {
 9576                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9577                let server = this
 9578                    .language_server_for_id(id)
 9579                    .with_context(|| format!("No language server {id}"))?;
 9580
 9581                anyhow::Ok(cx.background_spawn(async move {
 9582                    let can_resolve = server
 9583                        .capabilities()
 9584                        .completion_provider
 9585                        .as_ref()
 9586                        .and_then(|options| options.resolve_provider)
 9587                        .unwrap_or(false);
 9588                    if can_resolve {
 9589                        server
 9590                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9591                            .await
 9592                            .into_response()
 9593                            .context("resolve completion item")
 9594                    } else {
 9595                        anyhow::Ok(lsp_completion)
 9596                    }
 9597                }))
 9598            })??
 9599            .await?;
 9600
 9601        let mut documentation_is_markdown = false;
 9602        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9603        let documentation = match completion.documentation {
 9604            Some(lsp::Documentation::String(text)) => text,
 9605
 9606            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9607                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9608                value
 9609            }
 9610
 9611            _ => String::new(),
 9612        };
 9613
 9614        // If we have a new buffer_id, that means we're talking to a new client
 9615        // and want to check for new text_edits in the completion too.
 9616        let mut old_replace_start = None;
 9617        let mut old_replace_end = None;
 9618        let mut old_insert_start = None;
 9619        let mut old_insert_end = None;
 9620        let mut new_text = String::default();
 9621        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9622            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9623                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9624                anyhow::Ok(buffer.read(cx).snapshot())
 9625            })??;
 9626
 9627            if let Some(text_edit) = completion.text_edit.as_ref() {
 9628                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9629
 9630                if let Some(mut edit) = edit {
 9631                    LineEnding::normalize(&mut edit.new_text);
 9632
 9633                    new_text = edit.new_text;
 9634                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9635                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9636                    if let Some(insert_range) = edit.insert_range {
 9637                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9638                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9639                    }
 9640                }
 9641            }
 9642        }
 9643
 9644        Ok(proto::ResolveCompletionDocumentationResponse {
 9645            documentation,
 9646            documentation_is_markdown,
 9647            old_replace_start,
 9648            old_replace_end,
 9649            new_text,
 9650            lsp_completion,
 9651            old_insert_start,
 9652            old_insert_end,
 9653        })
 9654    }
 9655
 9656    async fn handle_on_type_formatting(
 9657        this: Entity<Self>,
 9658        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9659        mut cx: AsyncApp,
 9660    ) -> Result<proto::OnTypeFormattingResponse> {
 9661        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9662            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9663            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9664            let position = envelope
 9665                .payload
 9666                .position
 9667                .and_then(deserialize_anchor)
 9668                .context("invalid position")?;
 9669            anyhow::Ok(this.apply_on_type_formatting(
 9670                buffer,
 9671                position,
 9672                envelope.payload.trigger.clone(),
 9673                cx,
 9674            ))
 9675        })??;
 9676
 9677        let transaction = on_type_formatting
 9678            .await?
 9679            .as_ref()
 9680            .map(language::proto::serialize_transaction);
 9681        Ok(proto::OnTypeFormattingResponse { transaction })
 9682    }
 9683
 9684    async fn handle_refresh_inlay_hints(
 9685        lsp_store: Entity<Self>,
 9686        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9687        mut cx: AsyncApp,
 9688    ) -> Result<proto::Ack> {
 9689        lsp_store.update(&mut cx, |_, cx| {
 9690            cx.emit(LspStoreEvent::RefreshInlayHints(
 9691                LanguageServerId::from_proto(envelope.payload.server_id),
 9692            ));
 9693        })?;
 9694        Ok(proto::Ack {})
 9695    }
 9696
 9697    async fn handle_pull_workspace_diagnostics(
 9698        lsp_store: Entity<Self>,
 9699        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9700        mut cx: AsyncApp,
 9701    ) -> Result<proto::Ack> {
 9702        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9703        lsp_store.update(&mut cx, |lsp_store, _| {
 9704            lsp_store.pull_workspace_diagnostics(server_id);
 9705        })?;
 9706        Ok(proto::Ack {})
 9707    }
 9708
 9709    async fn handle_get_color_presentation(
 9710        lsp_store: Entity<Self>,
 9711        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9712        mut cx: AsyncApp,
 9713    ) -> Result<proto::GetColorPresentationResponse> {
 9714        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9715        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9716            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9717        })??;
 9718
 9719        let color = envelope
 9720            .payload
 9721            .color
 9722            .context("invalid color resolve request")?;
 9723        let start = color
 9724            .lsp_range_start
 9725            .context("invalid color resolve request")?;
 9726        let end = color
 9727            .lsp_range_end
 9728            .context("invalid color resolve request")?;
 9729
 9730        let color = DocumentColor {
 9731            lsp_range: lsp::Range {
 9732                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9733                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9734            },
 9735            color: lsp::Color {
 9736                red: color.red,
 9737                green: color.green,
 9738                blue: color.blue,
 9739                alpha: color.alpha,
 9740            },
 9741            resolved: false,
 9742            color_presentations: Vec::new(),
 9743        };
 9744        let resolved_color = lsp_store
 9745            .update(&mut cx, |lsp_store, cx| {
 9746                lsp_store.resolve_color_presentation(
 9747                    color,
 9748                    buffer.clone(),
 9749                    LanguageServerId(envelope.payload.server_id as usize),
 9750                    cx,
 9751                )
 9752            })?
 9753            .await
 9754            .context("resolving color presentation")?;
 9755
 9756        Ok(proto::GetColorPresentationResponse {
 9757            presentations: resolved_color
 9758                .color_presentations
 9759                .into_iter()
 9760                .map(|presentation| proto::ColorPresentation {
 9761                    label: presentation.label.to_string(),
 9762                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9763                    additional_text_edits: presentation
 9764                        .additional_text_edits
 9765                        .into_iter()
 9766                        .map(serialize_lsp_edit)
 9767                        .collect(),
 9768                })
 9769                .collect(),
 9770        })
 9771    }
 9772
 9773    async fn handle_resolve_inlay_hint(
 9774        lsp_store: Entity<Self>,
 9775        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9776        mut cx: AsyncApp,
 9777    ) -> Result<proto::ResolveInlayHintResponse> {
 9778        let proto_hint = envelope
 9779            .payload
 9780            .hint
 9781            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9782        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9783            .context("resolved proto inlay hint conversion")?;
 9784        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9785            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9786            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9787        })??;
 9788        let response_hint = lsp_store
 9789            .update(&mut cx, |lsp_store, cx| {
 9790                lsp_store.resolve_inlay_hint(
 9791                    hint,
 9792                    buffer,
 9793                    LanguageServerId(envelope.payload.language_server_id as usize),
 9794                    cx,
 9795                )
 9796            })?
 9797            .await
 9798            .context("inlay hints fetch")?;
 9799        Ok(proto::ResolveInlayHintResponse {
 9800            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9801        })
 9802    }
 9803
 9804    async fn handle_refresh_code_lens(
 9805        this: Entity<Self>,
 9806        _: TypedEnvelope<proto::RefreshCodeLens>,
 9807        mut cx: AsyncApp,
 9808    ) -> Result<proto::Ack> {
 9809        this.update(&mut cx, |_, cx| {
 9810            cx.emit(LspStoreEvent::RefreshCodeLens);
 9811        })?;
 9812        Ok(proto::Ack {})
 9813    }
 9814
 9815    async fn handle_open_buffer_for_symbol(
 9816        this: Entity<Self>,
 9817        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9818        mut cx: AsyncApp,
 9819    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9820        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9821        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9822        let symbol = Self::deserialize_symbol(symbol)?;
 9823        this.read_with(&cx, |this, _| {
 9824            if let SymbolLocation::OutsideProject {
 9825                abs_path,
 9826                signature,
 9827            } = &symbol.path
 9828            {
 9829                let new_signature = this.symbol_signature(&abs_path);
 9830                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9831            }
 9832            Ok(())
 9833        })??;
 9834        let buffer = this
 9835            .update(&mut cx, |this, cx| {
 9836                this.open_buffer_for_symbol(
 9837                    &Symbol {
 9838                        language_server_name: symbol.language_server_name,
 9839                        source_worktree_id: symbol.source_worktree_id,
 9840                        source_language_server_id: symbol.source_language_server_id,
 9841                        path: symbol.path,
 9842                        name: symbol.name,
 9843                        kind: symbol.kind,
 9844                        range: symbol.range,
 9845                        label: CodeLabel::default(),
 9846                    },
 9847                    cx,
 9848                )
 9849            })?
 9850            .await?;
 9851
 9852        this.update(&mut cx, |this, cx| {
 9853            let is_private = buffer
 9854                .read(cx)
 9855                .file()
 9856                .map(|f| f.is_private())
 9857                .unwrap_or_default();
 9858            if is_private {
 9859                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9860            } else {
 9861                this.buffer_store
 9862                    .update(cx, |buffer_store, cx| {
 9863                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9864                    })
 9865                    .detach_and_log_err(cx);
 9866                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9867                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9868            }
 9869        })?
 9870    }
 9871
 9872    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9873        let mut hasher = Sha256::new();
 9874        hasher.update(abs_path.to_string_lossy().as_bytes());
 9875        hasher.update(self.nonce.to_be_bytes());
 9876        hasher.finalize().as_slice().try_into().unwrap()
 9877    }
 9878
 9879    pub async fn handle_get_project_symbols(
 9880        this: Entity<Self>,
 9881        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9882        mut cx: AsyncApp,
 9883    ) -> Result<proto::GetProjectSymbolsResponse> {
 9884        let symbols = this
 9885            .update(&mut cx, |this, cx| {
 9886                this.symbols(&envelope.payload.query, cx)
 9887            })?
 9888            .await?;
 9889
 9890        Ok(proto::GetProjectSymbolsResponse {
 9891            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9892        })
 9893    }
 9894
 9895    pub async fn handle_restart_language_servers(
 9896        this: Entity<Self>,
 9897        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9898        mut cx: AsyncApp,
 9899    ) -> Result<proto::Ack> {
 9900        this.update(&mut cx, |lsp_store, cx| {
 9901            let buffers =
 9902                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9903            lsp_store.restart_language_servers_for_buffers(
 9904                buffers,
 9905                envelope
 9906                    .payload
 9907                    .only_servers
 9908                    .into_iter()
 9909                    .filter_map(|selector| {
 9910                        Some(match selector.selector? {
 9911                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9912                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9913                            }
 9914                            proto::language_server_selector::Selector::Name(name) => {
 9915                                LanguageServerSelector::Name(LanguageServerName(
 9916                                    SharedString::from(name),
 9917                                ))
 9918                            }
 9919                        })
 9920                    })
 9921                    .collect(),
 9922                cx,
 9923            );
 9924        })?;
 9925
 9926        Ok(proto::Ack {})
 9927    }
 9928
 9929    pub async fn handle_stop_language_servers(
 9930        lsp_store: Entity<Self>,
 9931        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9932        mut cx: AsyncApp,
 9933    ) -> Result<proto::Ack> {
 9934        lsp_store.update(&mut cx, |lsp_store, cx| {
 9935            if envelope.payload.all
 9936                && envelope.payload.also_servers.is_empty()
 9937                && envelope.payload.buffer_ids.is_empty()
 9938            {
 9939                lsp_store.stop_all_language_servers(cx);
 9940            } else {
 9941                let buffers =
 9942                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9943                lsp_store
 9944                    .stop_language_servers_for_buffers(
 9945                        buffers,
 9946                        envelope
 9947                            .payload
 9948                            .also_servers
 9949                            .into_iter()
 9950                            .filter_map(|selector| {
 9951                                Some(match selector.selector? {
 9952                                    proto::language_server_selector::Selector::ServerId(
 9953                                        server_id,
 9954                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9955                                        server_id,
 9956                                    )),
 9957                                    proto::language_server_selector::Selector::Name(name) => {
 9958                                        LanguageServerSelector::Name(LanguageServerName(
 9959                                            SharedString::from(name),
 9960                                        ))
 9961                                    }
 9962                                })
 9963                            })
 9964                            .collect(),
 9965                        cx,
 9966                    )
 9967                    .detach_and_log_err(cx);
 9968            }
 9969        })?;
 9970
 9971        Ok(proto::Ack {})
 9972    }
 9973
 9974    pub async fn handle_cancel_language_server_work(
 9975        this: Entity<Self>,
 9976        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9977        mut cx: AsyncApp,
 9978    ) -> Result<proto::Ack> {
 9979        this.update(&mut cx, |this, cx| {
 9980            if let Some(work) = envelope.payload.work {
 9981                match work {
 9982                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9983                        let buffers =
 9984                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9985                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9986                    }
 9987                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9988                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9989                        this.cancel_language_server_work(server_id, work.token, cx);
 9990                    }
 9991                }
 9992            }
 9993        })?;
 9994
 9995        Ok(proto::Ack {})
 9996    }
 9997
 9998    fn buffer_ids_to_buffers(
 9999        &mut self,
10000        buffer_ids: impl Iterator<Item = u64>,
10001        cx: &mut Context<Self>,
10002    ) -> Vec<Entity<Buffer>> {
10003        buffer_ids
10004            .into_iter()
10005            .flat_map(|buffer_id| {
10006                self.buffer_store
10007                    .read(cx)
10008                    .get(BufferId::new(buffer_id).log_err()?)
10009            })
10010            .collect::<Vec<_>>()
10011    }
10012
10013    async fn handle_apply_additional_edits_for_completion(
10014        this: Entity<Self>,
10015        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10016        mut cx: AsyncApp,
10017    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10018        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10019            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10020            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10021            let completion = Self::deserialize_completion(
10022                envelope.payload.completion.context("invalid completion")?,
10023            )?;
10024            anyhow::Ok((buffer, completion))
10025        })??;
10026
10027        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10028            this.apply_additional_edits_for_completion(
10029                buffer,
10030                Rc::new(RefCell::new(Box::new([Completion {
10031                    replace_range: completion.replace_range,
10032                    new_text: completion.new_text,
10033                    source: completion.source,
10034                    documentation: None,
10035                    label: CodeLabel::default(),
10036                    insert_text_mode: None,
10037                    icon_path: None,
10038                    confirm: None,
10039                }]))),
10040                0,
10041                false,
10042                cx,
10043            )
10044        })?;
10045
10046        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10047            transaction: apply_additional_edits
10048                .await?
10049                .as_ref()
10050                .map(language::proto::serialize_transaction),
10051        })
10052    }
10053
10054    pub fn last_formatting_failure(&self) -> Option<&str> {
10055        self.last_formatting_failure.as_deref()
10056    }
10057
10058    pub fn reset_last_formatting_failure(&mut self) {
10059        self.last_formatting_failure = None;
10060    }
10061
10062    pub fn environment_for_buffer(
10063        &self,
10064        buffer: &Entity<Buffer>,
10065        cx: &mut Context<Self>,
10066    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10067        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10068            environment.update(cx, |env, cx| {
10069                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10070            })
10071        } else {
10072            Task::ready(None).shared()
10073        }
10074    }
10075
10076    pub fn format(
10077        &mut self,
10078        buffers: HashSet<Entity<Buffer>>,
10079        target: LspFormatTarget,
10080        push_to_history: bool,
10081        trigger: FormatTrigger,
10082        cx: &mut Context<Self>,
10083    ) -> Task<anyhow::Result<ProjectTransaction>> {
10084        let logger = zlog::scoped!("format");
10085        if self.as_local().is_some() {
10086            zlog::trace!(logger => "Formatting locally");
10087            let logger = zlog::scoped!(logger => "local");
10088            let buffers = buffers
10089                .into_iter()
10090                .map(|buffer_handle| {
10091                    let buffer = buffer_handle.read(cx);
10092                    let buffer_abs_path = File::from_dyn(buffer.file())
10093                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10094
10095                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10096                })
10097                .collect::<Vec<_>>();
10098
10099            cx.spawn(async move |lsp_store, cx| {
10100                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10101
10102                for (handle, abs_path, id) in buffers {
10103                    let env = lsp_store
10104                        .update(cx, |lsp_store, cx| {
10105                            lsp_store.environment_for_buffer(&handle, cx)
10106                        })?
10107                        .await;
10108
10109                    let ranges = match &target {
10110                        LspFormatTarget::Buffers => None,
10111                        LspFormatTarget::Ranges(ranges) => {
10112                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10113                        }
10114                    };
10115
10116                    formattable_buffers.push(FormattableBuffer {
10117                        handle,
10118                        abs_path,
10119                        env,
10120                        ranges,
10121                    });
10122                }
10123                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10124
10125                let format_timer = zlog::time!(logger => "Formatting buffers");
10126                let result = LocalLspStore::format_locally(
10127                    lsp_store.clone(),
10128                    formattable_buffers,
10129                    push_to_history,
10130                    trigger,
10131                    logger,
10132                    cx,
10133                )
10134                .await;
10135                format_timer.end();
10136
10137                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10138
10139                lsp_store.update(cx, |lsp_store, _| {
10140                    lsp_store.update_last_formatting_failure(&result);
10141                })?;
10142
10143                result
10144            })
10145        } else if let Some((client, project_id)) = self.upstream_client() {
10146            zlog::trace!(logger => "Formatting remotely");
10147            let logger = zlog::scoped!(logger => "remote");
10148            // Don't support formatting ranges via remote
10149            match target {
10150                LspFormatTarget::Buffers => {}
10151                LspFormatTarget::Ranges(_) => {
10152                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10153                    return Task::ready(Ok(ProjectTransaction::default()));
10154                }
10155            }
10156
10157            let buffer_store = self.buffer_store();
10158            cx.spawn(async move |lsp_store, cx| {
10159                zlog::trace!(logger => "Sending remote format request");
10160                let request_timer = zlog::time!(logger => "remote format request");
10161                let result = client
10162                    .request(proto::FormatBuffers {
10163                        project_id,
10164                        trigger: trigger as i32,
10165                        buffer_ids: buffers
10166                            .iter()
10167                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10168                            .collect::<Result<_>>()?,
10169                    })
10170                    .await
10171                    .and_then(|result| result.transaction.context("missing transaction"));
10172                request_timer.end();
10173
10174                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10175
10176                lsp_store.update(cx, |lsp_store, _| {
10177                    lsp_store.update_last_formatting_failure(&result);
10178                })?;
10179
10180                let transaction_response = result?;
10181                let _timer = zlog::time!(logger => "deserializing project transaction");
10182                buffer_store
10183                    .update(cx, |buffer_store, cx| {
10184                        buffer_store.deserialize_project_transaction(
10185                            transaction_response,
10186                            push_to_history,
10187                            cx,
10188                        )
10189                    })?
10190                    .await
10191            })
10192        } else {
10193            zlog::trace!(logger => "Not formatting");
10194            Task::ready(Ok(ProjectTransaction::default()))
10195        }
10196    }
10197
10198    async fn handle_format_buffers(
10199        this: Entity<Self>,
10200        envelope: TypedEnvelope<proto::FormatBuffers>,
10201        mut cx: AsyncApp,
10202    ) -> Result<proto::FormatBuffersResponse> {
10203        let sender_id = envelope.original_sender_id().unwrap_or_default();
10204        let format = this.update(&mut cx, |this, cx| {
10205            let mut buffers = HashSet::default();
10206            for buffer_id in &envelope.payload.buffer_ids {
10207                let buffer_id = BufferId::new(*buffer_id)?;
10208                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10209            }
10210            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10211            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10212        })??;
10213
10214        let project_transaction = format.await?;
10215        let project_transaction = this.update(&mut cx, |this, cx| {
10216            this.buffer_store.update(cx, |buffer_store, cx| {
10217                buffer_store.serialize_project_transaction_for_peer(
10218                    project_transaction,
10219                    sender_id,
10220                    cx,
10221                )
10222            })
10223        })?;
10224        Ok(proto::FormatBuffersResponse {
10225            transaction: Some(project_transaction),
10226        })
10227    }
10228
10229    async fn handle_apply_code_action_kind(
10230        this: Entity<Self>,
10231        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10232        mut cx: AsyncApp,
10233    ) -> Result<proto::ApplyCodeActionKindResponse> {
10234        let sender_id = envelope.original_sender_id().unwrap_or_default();
10235        let format = this.update(&mut cx, |this, cx| {
10236            let mut buffers = HashSet::default();
10237            for buffer_id in &envelope.payload.buffer_ids {
10238                let buffer_id = BufferId::new(*buffer_id)?;
10239                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10240            }
10241            let kind = match envelope.payload.kind.as_str() {
10242                "" => CodeActionKind::EMPTY,
10243                "quickfix" => CodeActionKind::QUICKFIX,
10244                "refactor" => CodeActionKind::REFACTOR,
10245                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10246                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10247                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10248                "source" => CodeActionKind::SOURCE,
10249                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10250                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10251                _ => anyhow::bail!(
10252                    "Invalid code action kind {}",
10253                    envelope.payload.kind.as_str()
10254                ),
10255            };
10256            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10257        })??;
10258
10259        let project_transaction = format.await?;
10260        let project_transaction = this.update(&mut cx, |this, cx| {
10261            this.buffer_store.update(cx, |buffer_store, cx| {
10262                buffer_store.serialize_project_transaction_for_peer(
10263                    project_transaction,
10264                    sender_id,
10265                    cx,
10266                )
10267            })
10268        })?;
10269        Ok(proto::ApplyCodeActionKindResponse {
10270            transaction: Some(project_transaction),
10271        })
10272    }
10273
10274    async fn shutdown_language_server(
10275        server_state: Option<LanguageServerState>,
10276        name: LanguageServerName,
10277        cx: &mut AsyncApp,
10278    ) {
10279        let server = match server_state {
10280            Some(LanguageServerState::Starting { startup, .. }) => {
10281                let mut timer = cx
10282                    .background_executor()
10283                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10284                    .fuse();
10285
10286                select! {
10287                    server = startup.fuse() => server,
10288                    () = timer => {
10289                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10290                        None
10291                    },
10292                }
10293            }
10294
10295            Some(LanguageServerState::Running { server, .. }) => Some(server),
10296
10297            None => None,
10298        };
10299
10300        if let Some(server) = server
10301            && let Some(shutdown) = server.shutdown()
10302        {
10303            shutdown.await;
10304        }
10305    }
10306
10307    // Returns a list of all of the worktrees which no longer have a language server and the root path
10308    // for the stopped server
10309    fn stop_local_language_server(
10310        &mut self,
10311        server_id: LanguageServerId,
10312        cx: &mut Context<Self>,
10313    ) -> Task<()> {
10314        let local = match &mut self.mode {
10315            LspStoreMode::Local(local) => local,
10316            _ => {
10317                return Task::ready(());
10318            }
10319        };
10320
10321        // Remove this server ID from all entries in the given worktree.
10322        local
10323            .language_server_ids
10324            .retain(|_, state| state.id != server_id);
10325        self.buffer_store.update(cx, |buffer_store, cx| {
10326            for buffer in buffer_store.buffers() {
10327                buffer.update(cx, |buffer, cx| {
10328                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10329                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10330                });
10331            }
10332        });
10333
10334        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10335            summaries.retain(|path, summaries_by_server_id| {
10336                if summaries_by_server_id.remove(&server_id).is_some() {
10337                    if let Some((client, project_id)) = self.downstream_client.clone() {
10338                        client
10339                            .send(proto::UpdateDiagnosticSummary {
10340                                project_id,
10341                                worktree_id: worktree_id.to_proto(),
10342                                summary: Some(proto::DiagnosticSummary {
10343                                    path: path.as_ref().to_proto(),
10344                                    language_server_id: server_id.0 as u64,
10345                                    error_count: 0,
10346                                    warning_count: 0,
10347                                }),
10348                                more_summaries: Vec::new(),
10349                            })
10350                            .log_err();
10351                    }
10352                    !summaries_by_server_id.is_empty()
10353                } else {
10354                    true
10355                }
10356            });
10357        }
10358
10359        let local = self.as_local_mut().unwrap();
10360        for diagnostics in local.diagnostics.values_mut() {
10361            diagnostics.retain(|_, diagnostics_by_server_id| {
10362                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10363                    diagnostics_by_server_id.remove(ix);
10364                    !diagnostics_by_server_id.is_empty()
10365                } else {
10366                    true
10367                }
10368            });
10369        }
10370        local.language_server_watched_paths.remove(&server_id);
10371
10372        let server_state = local.language_servers.remove(&server_id);
10373        self.cleanup_lsp_data(server_id);
10374        let name = self
10375            .language_server_statuses
10376            .remove(&server_id)
10377            .map(|status| status.name)
10378            .or_else(|| {
10379                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10380                    Some(adapter.name())
10381                } else {
10382                    None
10383                }
10384            });
10385
10386        if let Some(name) = name {
10387            log::info!("stopping language server {name}");
10388            self.languages
10389                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10390            cx.notify();
10391
10392            return cx.spawn(async move |lsp_store, cx| {
10393                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10394                lsp_store
10395                    .update(cx, |lsp_store, cx| {
10396                        lsp_store
10397                            .languages
10398                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10399                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10400                        cx.notify();
10401                    })
10402                    .ok();
10403            });
10404        }
10405
10406        if server_state.is_some() {
10407            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10408        }
10409        Task::ready(())
10410    }
10411
10412    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10413        if let Some((client, project_id)) = self.upstream_client() {
10414            let request = client.request(proto::StopLanguageServers {
10415                project_id,
10416                buffer_ids: Vec::new(),
10417                also_servers: Vec::new(),
10418                all: true,
10419            });
10420            cx.background_spawn(request).detach_and_log_err(cx);
10421        } else {
10422            let Some(local) = self.as_local_mut() else {
10423                return;
10424            };
10425            let language_servers_to_stop = local
10426                .language_server_ids
10427                .values()
10428                .map(|state| state.id)
10429                .collect();
10430            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10431            let tasks = language_servers_to_stop
10432                .into_iter()
10433                .map(|server| self.stop_local_language_server(server, cx))
10434                .collect::<Vec<_>>();
10435            cx.background_spawn(async move {
10436                futures::future::join_all(tasks).await;
10437            })
10438            .detach();
10439        }
10440    }
10441
10442    pub fn restart_language_servers_for_buffers(
10443        &mut self,
10444        buffers: Vec<Entity<Buffer>>,
10445        only_restart_servers: HashSet<LanguageServerSelector>,
10446        cx: &mut Context<Self>,
10447    ) {
10448        if let Some((client, project_id)) = self.upstream_client() {
10449            let request = client.request(proto::RestartLanguageServers {
10450                project_id,
10451                buffer_ids: buffers
10452                    .into_iter()
10453                    .map(|b| b.read(cx).remote_id().to_proto())
10454                    .collect(),
10455                only_servers: only_restart_servers
10456                    .into_iter()
10457                    .map(|selector| {
10458                        let selector = match selector {
10459                            LanguageServerSelector::Id(language_server_id) => {
10460                                proto::language_server_selector::Selector::ServerId(
10461                                    language_server_id.to_proto(),
10462                                )
10463                            }
10464                            LanguageServerSelector::Name(language_server_name) => {
10465                                proto::language_server_selector::Selector::Name(
10466                                    language_server_name.to_string(),
10467                                )
10468                            }
10469                        };
10470                        proto::LanguageServerSelector {
10471                            selector: Some(selector),
10472                        }
10473                    })
10474                    .collect(),
10475                all: false,
10476            });
10477            cx.background_spawn(request).detach_and_log_err(cx);
10478        } else {
10479            let stop_task = if only_restart_servers.is_empty() {
10480                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10481            } else {
10482                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10483            };
10484            cx.spawn(async move |lsp_store, cx| {
10485                stop_task.await;
10486                lsp_store
10487                    .update(cx, |lsp_store, cx| {
10488                        for buffer in buffers {
10489                            lsp_store.register_buffer_with_language_servers(
10490                                &buffer,
10491                                only_restart_servers.clone(),
10492                                true,
10493                                cx,
10494                            );
10495                        }
10496                    })
10497                    .ok()
10498            })
10499            .detach();
10500        }
10501    }
10502
10503    pub fn stop_language_servers_for_buffers(
10504        &mut self,
10505        buffers: Vec<Entity<Buffer>>,
10506        also_stop_servers: HashSet<LanguageServerSelector>,
10507        cx: &mut Context<Self>,
10508    ) -> Task<Result<()>> {
10509        if let Some((client, project_id)) = self.upstream_client() {
10510            let request = client.request(proto::StopLanguageServers {
10511                project_id,
10512                buffer_ids: buffers
10513                    .into_iter()
10514                    .map(|b| b.read(cx).remote_id().to_proto())
10515                    .collect(),
10516                also_servers: also_stop_servers
10517                    .into_iter()
10518                    .map(|selector| {
10519                        let selector = match selector {
10520                            LanguageServerSelector::Id(language_server_id) => {
10521                                proto::language_server_selector::Selector::ServerId(
10522                                    language_server_id.to_proto(),
10523                                )
10524                            }
10525                            LanguageServerSelector::Name(language_server_name) => {
10526                                proto::language_server_selector::Selector::Name(
10527                                    language_server_name.to_string(),
10528                                )
10529                            }
10530                        };
10531                        proto::LanguageServerSelector {
10532                            selector: Some(selector),
10533                        }
10534                    })
10535                    .collect(),
10536                all: false,
10537            });
10538            cx.background_spawn(async move {
10539                let _ = request.await?;
10540                Ok(())
10541            })
10542        } else {
10543            let task =
10544                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10545            cx.background_spawn(async move {
10546                task.await;
10547                Ok(())
10548            })
10549        }
10550    }
10551
10552    fn stop_local_language_servers_for_buffers(
10553        &mut self,
10554        buffers: &[Entity<Buffer>],
10555        also_stop_servers: HashSet<LanguageServerSelector>,
10556        cx: &mut Context<Self>,
10557    ) -> Task<()> {
10558        let Some(local) = self.as_local_mut() else {
10559            return Task::ready(());
10560        };
10561        let mut language_server_names_to_stop = BTreeSet::default();
10562        let mut language_servers_to_stop = also_stop_servers
10563            .into_iter()
10564            .flat_map(|selector| match selector {
10565                LanguageServerSelector::Id(id) => Some(id),
10566                LanguageServerSelector::Name(name) => {
10567                    language_server_names_to_stop.insert(name);
10568                    None
10569                }
10570            })
10571            .collect::<BTreeSet<_>>();
10572
10573        let mut covered_worktrees = HashSet::default();
10574        for buffer in buffers {
10575            buffer.update(cx, |buffer, cx| {
10576                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10577                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10578                    && covered_worktrees.insert(worktree_id)
10579                {
10580                    language_server_names_to_stop.retain(|name| {
10581                        let old_ids_count = language_servers_to_stop.len();
10582                        let all_language_servers_with_this_name = local
10583                            .language_server_ids
10584                            .iter()
10585                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10586                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10587                        old_ids_count == language_servers_to_stop.len()
10588                    });
10589                }
10590            });
10591        }
10592        for name in language_server_names_to_stop {
10593            language_servers_to_stop.extend(
10594                local
10595                    .language_server_ids
10596                    .iter()
10597                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10598            );
10599        }
10600
10601        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10602        let tasks = language_servers_to_stop
10603            .into_iter()
10604            .map(|server| self.stop_local_language_server(server, cx))
10605            .collect::<Vec<_>>();
10606
10607        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10608    }
10609
10610    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10611        let (worktree, relative_path) =
10612            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10613
10614        let project_path = ProjectPath {
10615            worktree_id: worktree.read(cx).id(),
10616            path: relative_path,
10617        };
10618
10619        Some(
10620            self.buffer_store()
10621                .read(cx)
10622                .get_by_path(&project_path)?
10623                .read(cx),
10624        )
10625    }
10626
10627    #[cfg(any(test, feature = "test-support"))]
10628    pub fn update_diagnostics(
10629        &mut self,
10630        server_id: LanguageServerId,
10631        diagnostics: lsp::PublishDiagnosticsParams,
10632        result_id: Option<String>,
10633        source_kind: DiagnosticSourceKind,
10634        disk_based_sources: &[String],
10635        cx: &mut Context<Self>,
10636    ) -> Result<()> {
10637        self.merge_lsp_diagnostics(
10638            source_kind,
10639            vec![DocumentDiagnosticsUpdate {
10640                diagnostics,
10641                result_id,
10642                server_id,
10643                disk_based_sources: Cow::Borrowed(disk_based_sources),
10644            }],
10645            |_, _, _| false,
10646            cx,
10647        )
10648    }
10649
10650    pub fn merge_lsp_diagnostics(
10651        &mut self,
10652        source_kind: DiagnosticSourceKind,
10653        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10654        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10655        cx: &mut Context<Self>,
10656    ) -> Result<()> {
10657        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10658        let updates = lsp_diagnostics
10659            .into_iter()
10660            .filter_map(|update| {
10661                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10662                Some(DocumentDiagnosticsUpdate {
10663                    diagnostics: self.lsp_to_document_diagnostics(
10664                        abs_path,
10665                        source_kind,
10666                        update.server_id,
10667                        update.diagnostics,
10668                        &update.disk_based_sources,
10669                    ),
10670                    result_id: update.result_id,
10671                    server_id: update.server_id,
10672                    disk_based_sources: update.disk_based_sources,
10673                })
10674            })
10675            .collect();
10676        self.merge_diagnostic_entries(updates, merge, cx)?;
10677        Ok(())
10678    }
10679
10680    fn lsp_to_document_diagnostics(
10681        &mut self,
10682        document_abs_path: PathBuf,
10683        source_kind: DiagnosticSourceKind,
10684        server_id: LanguageServerId,
10685        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10686        disk_based_sources: &[String],
10687    ) -> DocumentDiagnostics {
10688        let mut diagnostics = Vec::default();
10689        let mut primary_diagnostic_group_ids = HashMap::default();
10690        let mut sources_by_group_id = HashMap::default();
10691        let mut supporting_diagnostics = HashMap::default();
10692
10693        let adapter = self.language_server_adapter_for_id(server_id);
10694
10695        // Ensure that primary diagnostics are always the most severe
10696        lsp_diagnostics
10697            .diagnostics
10698            .sort_by_key(|item| item.severity);
10699
10700        for diagnostic in &lsp_diagnostics.diagnostics {
10701            let source = diagnostic.source.as_ref();
10702            let range = range_from_lsp(diagnostic.range);
10703            let is_supporting = diagnostic
10704                .related_information
10705                .as_ref()
10706                .is_some_and(|infos| {
10707                    infos.iter().any(|info| {
10708                        primary_diagnostic_group_ids.contains_key(&(
10709                            source,
10710                            diagnostic.code.clone(),
10711                            range_from_lsp(info.location.range),
10712                        ))
10713                    })
10714                });
10715
10716            let is_unnecessary = diagnostic
10717                .tags
10718                .as_ref()
10719                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10720
10721            let underline = self
10722                .language_server_adapter_for_id(server_id)
10723                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10724
10725            if is_supporting {
10726                supporting_diagnostics.insert(
10727                    (source, diagnostic.code.clone(), range),
10728                    (diagnostic.severity, is_unnecessary),
10729                );
10730            } else {
10731                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10732                let is_disk_based =
10733                    source.is_some_and(|source| disk_based_sources.contains(source));
10734
10735                sources_by_group_id.insert(group_id, source);
10736                primary_diagnostic_group_ids
10737                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10738
10739                diagnostics.push(DiagnosticEntry {
10740                    range,
10741                    diagnostic: Diagnostic {
10742                        source: diagnostic.source.clone(),
10743                        source_kind,
10744                        code: diagnostic.code.clone(),
10745                        code_description: diagnostic
10746                            .code_description
10747                            .as_ref()
10748                            .and_then(|d| d.href.clone()),
10749                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10750                        markdown: adapter.as_ref().and_then(|adapter| {
10751                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10752                        }),
10753                        message: diagnostic.message.trim().to_string(),
10754                        group_id,
10755                        is_primary: true,
10756                        is_disk_based,
10757                        is_unnecessary,
10758                        underline,
10759                        data: diagnostic.data.clone(),
10760                    },
10761                });
10762                if let Some(infos) = &diagnostic.related_information {
10763                    for info in infos {
10764                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10765                            let range = range_from_lsp(info.location.range);
10766                            diagnostics.push(DiagnosticEntry {
10767                                range,
10768                                diagnostic: Diagnostic {
10769                                    source: diagnostic.source.clone(),
10770                                    source_kind,
10771                                    code: diagnostic.code.clone(),
10772                                    code_description: diagnostic
10773                                        .code_description
10774                                        .as_ref()
10775                                        .and_then(|d| d.href.clone()),
10776                                    severity: DiagnosticSeverity::INFORMATION,
10777                                    markdown: adapter.as_ref().and_then(|adapter| {
10778                                        adapter.diagnostic_message_to_markdown(&info.message)
10779                                    }),
10780                                    message: info.message.trim().to_string(),
10781                                    group_id,
10782                                    is_primary: false,
10783                                    is_disk_based,
10784                                    is_unnecessary: false,
10785                                    underline,
10786                                    data: diagnostic.data.clone(),
10787                                },
10788                            });
10789                        }
10790                    }
10791                }
10792            }
10793        }
10794
10795        for entry in &mut diagnostics {
10796            let diagnostic = &mut entry.diagnostic;
10797            if !diagnostic.is_primary {
10798                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10799                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10800                    source,
10801                    diagnostic.code.clone(),
10802                    entry.range.clone(),
10803                )) {
10804                    if let Some(severity) = severity {
10805                        diagnostic.severity = severity;
10806                    }
10807                    diagnostic.is_unnecessary = is_unnecessary;
10808                }
10809            }
10810        }
10811
10812        DocumentDiagnostics {
10813            diagnostics,
10814            document_abs_path,
10815            version: lsp_diagnostics.version,
10816        }
10817    }
10818
10819    fn insert_newly_running_language_server(
10820        &mut self,
10821        adapter: Arc<CachedLspAdapter>,
10822        language_server: Arc<LanguageServer>,
10823        server_id: LanguageServerId,
10824        key: LanguageServerSeed,
10825        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10826        cx: &mut Context<Self>,
10827    ) {
10828        let Some(local) = self.as_local_mut() else {
10829            return;
10830        };
10831        // If the language server for this key doesn't match the server id, don't store the
10832        // server. Which will cause it to be dropped, killing the process
10833        if local
10834            .language_server_ids
10835            .get(&key)
10836            .map(|state| state.id != server_id)
10837            .unwrap_or(false)
10838        {
10839            return;
10840        }
10841
10842        // Update language_servers collection with Running variant of LanguageServerState
10843        // indicating that the server is up and running and ready
10844        let workspace_folders = workspace_folders.lock().clone();
10845        language_server.set_workspace_folders(workspace_folders);
10846
10847        let workspace_diagnostics_refresh_tasks = language_server
10848            .capabilities()
10849            .diagnostic_provider
10850            .and_then(|provider| {
10851                let workspace_refresher = lsp_workspace_diagnostics_refresh(
10852                    None,
10853                    provider.clone(),
10854                    language_server.clone(),
10855                    cx,
10856                )?;
10857                local
10858                    .language_server_dynamic_registrations
10859                    .entry(server_id)
10860                    .or_default()
10861                    .diagnostics
10862                    .entry(None)
10863                    .or_insert(provider);
10864                Some((None, workspace_refresher))
10865            })
10866            .into_iter()
10867            .collect();
10868        local.language_servers.insert(
10869            server_id,
10870            LanguageServerState::Running {
10871                workspace_diagnostics_refresh_tasks,
10872                adapter: adapter.clone(),
10873                server: language_server.clone(),
10874                simulate_disk_based_diagnostics_completion: None,
10875            },
10876        );
10877        local
10878            .languages
10879            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10880        if let Some(file_ops_caps) = language_server
10881            .capabilities()
10882            .workspace
10883            .as_ref()
10884            .and_then(|ws| ws.file_operations.as_ref())
10885        {
10886            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10887            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10888            if did_rename_caps.or(will_rename_caps).is_some() {
10889                let watcher = RenamePathsWatchedForServer::default()
10890                    .with_did_rename_patterns(did_rename_caps)
10891                    .with_will_rename_patterns(will_rename_caps);
10892                local
10893                    .language_server_paths_watched_for_rename
10894                    .insert(server_id, watcher);
10895            }
10896        }
10897
10898        self.language_server_statuses.insert(
10899            server_id,
10900            LanguageServerStatus {
10901                name: language_server.name(),
10902                pending_work: Default::default(),
10903                has_pending_diagnostic_updates: false,
10904                progress_tokens: Default::default(),
10905                worktree: Some(key.worktree_id),
10906            },
10907        );
10908
10909        cx.emit(LspStoreEvent::LanguageServerAdded(
10910            server_id,
10911            language_server.name(),
10912            Some(key.worktree_id),
10913        ));
10914        cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
10915
10916        let server_capabilities = language_server.capabilities();
10917        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10918            downstream_client
10919                .send(proto::StartLanguageServer {
10920                    project_id: *project_id,
10921                    server: Some(proto::LanguageServer {
10922                        id: server_id.to_proto(),
10923                        name: language_server.name().to_string(),
10924                        worktree_id: Some(key.worktree_id.to_proto()),
10925                    }),
10926                    capabilities: serde_json::to_string(&server_capabilities)
10927                        .expect("serializing server LSP capabilities"),
10928                })
10929                .log_err();
10930        }
10931        self.lsp_server_capabilities
10932            .insert(server_id, server_capabilities);
10933
10934        // Tell the language server about every open buffer in the worktree that matches the language.
10935        // Also check for buffers in worktrees that reused this server
10936        let mut worktrees_using_server = vec![key.worktree_id];
10937        if let Some(local) = self.as_local() {
10938            // Find all worktrees that have this server in their language server tree
10939            for (worktree_id, servers) in &local.lsp_tree.instances {
10940                if *worktree_id != key.worktree_id {
10941                    for server_map in servers.roots.values() {
10942                        if server_map
10943                            .values()
10944                            .any(|(node, _)| node.id() == Some(server_id))
10945                        {
10946                            worktrees_using_server.push(*worktree_id);
10947                        }
10948                    }
10949                }
10950            }
10951        }
10952
10953        let mut buffer_paths_registered = Vec::new();
10954        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10955            let mut lsp_adapters = HashMap::default();
10956            for buffer_handle in buffer_store.buffers() {
10957                let buffer = buffer_handle.read(cx);
10958                let file = match File::from_dyn(buffer.file()) {
10959                    Some(file) => file,
10960                    None => continue,
10961                };
10962                let language = match buffer.language() {
10963                    Some(language) => language,
10964                    None => continue,
10965                };
10966
10967                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10968                    || !lsp_adapters
10969                        .entry(language.name())
10970                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
10971                        .iter()
10972                        .any(|a| a.name == key.name)
10973                {
10974                    continue;
10975                }
10976                // didOpen
10977                let file = match file.as_local() {
10978                    Some(file) => file,
10979                    None => continue,
10980                };
10981
10982                let local = self.as_local_mut().unwrap();
10983
10984                let buffer_id = buffer.remote_id();
10985                if local.registered_buffers.contains_key(&buffer_id) {
10986                    let versions = local
10987                        .buffer_snapshots
10988                        .entry(buffer_id)
10989                        .or_default()
10990                        .entry(server_id)
10991                        .and_modify(|_| {
10992                            assert!(
10993                            false,
10994                            "There should not be an existing snapshot for a newly inserted buffer"
10995                        )
10996                        })
10997                        .or_insert_with(|| {
10998                            vec![LspBufferSnapshot {
10999                                version: 0,
11000                                snapshot: buffer.text_snapshot(),
11001                            }]
11002                        });
11003
11004                    let snapshot = versions.last().unwrap();
11005                    let version = snapshot.version;
11006                    let initial_snapshot = &snapshot.snapshot;
11007                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11008                    language_server.register_buffer(
11009                        uri,
11010                        adapter.language_id(&language.name()),
11011                        version,
11012                        initial_snapshot.text(),
11013                    );
11014                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11015                    local
11016                        .buffers_opened_in_servers
11017                        .entry(buffer_id)
11018                        .or_default()
11019                        .insert(server_id);
11020                }
11021                buffer_handle.update(cx, |buffer, cx| {
11022                    buffer.set_completion_triggers(
11023                        server_id,
11024                        language_server
11025                            .capabilities()
11026                            .completion_provider
11027                            .as_ref()
11028                            .and_then(|provider| {
11029                                provider
11030                                    .trigger_characters
11031                                    .as_ref()
11032                                    .map(|characters| characters.iter().cloned().collect())
11033                            })
11034                            .unwrap_or_default(),
11035                        cx,
11036                    )
11037                });
11038            }
11039        });
11040
11041        for (buffer_id, abs_path) in buffer_paths_registered {
11042            cx.emit(LspStoreEvent::LanguageServerUpdate {
11043                language_server_id: server_id,
11044                name: Some(adapter.name()),
11045                message: proto::update_language_server::Variant::RegisteredForBuffer(
11046                    proto::RegisteredForBuffer {
11047                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11048                        buffer_id: buffer_id.to_proto(),
11049                    },
11050                ),
11051            });
11052        }
11053
11054        cx.notify();
11055    }
11056
11057    pub fn language_servers_running_disk_based_diagnostics(
11058        &self,
11059    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11060        self.language_server_statuses
11061            .iter()
11062            .filter_map(|(id, status)| {
11063                if status.has_pending_diagnostic_updates {
11064                    Some(*id)
11065                } else {
11066                    None
11067                }
11068            })
11069    }
11070
11071    pub(crate) fn cancel_language_server_work_for_buffers(
11072        &mut self,
11073        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11074        cx: &mut Context<Self>,
11075    ) {
11076        if let Some((client, project_id)) = self.upstream_client() {
11077            let request = client.request(proto::CancelLanguageServerWork {
11078                project_id,
11079                work: Some(proto::cancel_language_server_work::Work::Buffers(
11080                    proto::cancel_language_server_work::Buffers {
11081                        buffer_ids: buffers
11082                            .into_iter()
11083                            .map(|b| b.read(cx).remote_id().to_proto())
11084                            .collect(),
11085                    },
11086                )),
11087            });
11088            cx.background_spawn(request).detach_and_log_err(cx);
11089        } else if let Some(local) = self.as_local() {
11090            let servers = buffers
11091                .into_iter()
11092                .flat_map(|buffer| {
11093                    buffer.update(cx, |buffer, cx| {
11094                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11095                    })
11096                })
11097                .collect::<HashSet<_>>();
11098            for server_id in servers {
11099                self.cancel_language_server_work(server_id, None, cx);
11100            }
11101        }
11102    }
11103
11104    pub(crate) fn cancel_language_server_work(
11105        &mut self,
11106        server_id: LanguageServerId,
11107        token_to_cancel: Option<String>,
11108        cx: &mut Context<Self>,
11109    ) {
11110        if let Some(local) = self.as_local() {
11111            let status = self.language_server_statuses.get(&server_id);
11112            let server = local.language_servers.get(&server_id);
11113            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11114            {
11115                for (token, progress) in &status.pending_work {
11116                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11117                        && token != token_to_cancel
11118                    {
11119                        continue;
11120                    }
11121                    if progress.is_cancellable {
11122                        server
11123                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11124                                WorkDoneProgressCancelParams {
11125                                    token: lsp::NumberOrString::String(token.clone()),
11126                                },
11127                            )
11128                            .ok();
11129                    }
11130                }
11131            }
11132        } else if let Some((client, project_id)) = self.upstream_client() {
11133            let request = client.request(proto::CancelLanguageServerWork {
11134                project_id,
11135                work: Some(
11136                    proto::cancel_language_server_work::Work::LanguageServerWork(
11137                        proto::cancel_language_server_work::LanguageServerWork {
11138                            language_server_id: server_id.to_proto(),
11139                            token: token_to_cancel,
11140                        },
11141                    ),
11142                ),
11143            });
11144            cx.background_spawn(request).detach_and_log_err(cx);
11145        }
11146    }
11147
11148    fn register_supplementary_language_server(
11149        &mut self,
11150        id: LanguageServerId,
11151        name: LanguageServerName,
11152        server: Arc<LanguageServer>,
11153        cx: &mut Context<Self>,
11154    ) {
11155        if let Some(local) = self.as_local_mut() {
11156            local
11157                .supplementary_language_servers
11158                .insert(id, (name.clone(), server));
11159            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11160        }
11161    }
11162
11163    fn unregister_supplementary_language_server(
11164        &mut self,
11165        id: LanguageServerId,
11166        cx: &mut Context<Self>,
11167    ) {
11168        if let Some(local) = self.as_local_mut() {
11169            local.supplementary_language_servers.remove(&id);
11170            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11171        }
11172    }
11173
11174    pub(crate) fn supplementary_language_servers(
11175        &self,
11176    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11177        self.as_local().into_iter().flat_map(|local| {
11178            local
11179                .supplementary_language_servers
11180                .iter()
11181                .map(|(id, (name, _))| (*id, name.clone()))
11182        })
11183    }
11184
11185    pub fn language_server_adapter_for_id(
11186        &self,
11187        id: LanguageServerId,
11188    ) -> Option<Arc<CachedLspAdapter>> {
11189        self.as_local()
11190            .and_then(|local| local.language_servers.get(&id))
11191            .and_then(|language_server_state| match language_server_state {
11192                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11193                _ => None,
11194            })
11195    }
11196
11197    pub(super) fn update_local_worktree_language_servers(
11198        &mut self,
11199        worktree_handle: &Entity<Worktree>,
11200        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11201        cx: &mut Context<Self>,
11202    ) {
11203        if changes.is_empty() {
11204            return;
11205        }
11206
11207        let Some(local) = self.as_local() else { return };
11208
11209        local.prettier_store.update(cx, |prettier_store, cx| {
11210            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11211        });
11212
11213        let worktree_id = worktree_handle.read(cx).id();
11214        let mut language_server_ids = local
11215            .language_server_ids
11216            .iter()
11217            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11218            .collect::<Vec<_>>();
11219        language_server_ids.sort();
11220        language_server_ids.dedup();
11221
11222        // let abs_path = worktree_handle.read(cx).abs_path();
11223        for server_id in &language_server_ids {
11224            if let Some(LanguageServerState::Running { server, .. }) =
11225                local.language_servers.get(server_id)
11226                && let Some(watched_paths) = local
11227                    .language_server_watched_paths
11228                    .get(server_id)
11229                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11230            {
11231                let params = lsp::DidChangeWatchedFilesParams {
11232                    changes: changes
11233                        .iter()
11234                        .filter_map(|(path, _, change)| {
11235                            if !watched_paths.is_match(path.as_std_path()) {
11236                                return None;
11237                            }
11238                            let typ = match change {
11239                                PathChange::Loaded => return None,
11240                                PathChange::Added => lsp::FileChangeType::CREATED,
11241                                PathChange::Removed => lsp::FileChangeType::DELETED,
11242                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11243                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11244                            };
11245                            let uri = lsp::Uri::from_file_path(
11246                                worktree_handle.read(cx).absolutize(&path),
11247                            )
11248                            .ok()?;
11249                            Some(lsp::FileEvent { uri, typ })
11250                        })
11251                        .collect(),
11252                };
11253                if !params.changes.is_empty() {
11254                    server
11255                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11256                        .ok();
11257                }
11258            }
11259        }
11260        for (path, _, _) in changes {
11261            if let Some(file_name) = path.file_name()
11262                && local.watched_manifest_filenames.contains(file_name)
11263            {
11264                self.request_workspace_config_refresh();
11265                break;
11266            }
11267        }
11268    }
11269
11270    pub fn wait_for_remote_buffer(
11271        &mut self,
11272        id: BufferId,
11273        cx: &mut Context<Self>,
11274    ) -> Task<Result<Entity<Buffer>>> {
11275        self.buffer_store.update(cx, |buffer_store, cx| {
11276            buffer_store.wait_for_remote_buffer(id, cx)
11277        })
11278    }
11279
11280    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11281        let mut result = proto::Symbol {
11282            language_server_name: symbol.language_server_name.0.to_string(),
11283            source_worktree_id: symbol.source_worktree_id.to_proto(),
11284            language_server_id: symbol.source_language_server_id.to_proto(),
11285            name: symbol.name.clone(),
11286            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11287            start: Some(proto::PointUtf16 {
11288                row: symbol.range.start.0.row,
11289                column: symbol.range.start.0.column,
11290            }),
11291            end: Some(proto::PointUtf16 {
11292                row: symbol.range.end.0.row,
11293                column: symbol.range.end.0.column,
11294            }),
11295            worktree_id: Default::default(),
11296            path: Default::default(),
11297            signature: Default::default(),
11298        };
11299        match &symbol.path {
11300            SymbolLocation::InProject(path) => {
11301                result.worktree_id = path.worktree_id.to_proto();
11302                result.path = path.path.to_proto();
11303            }
11304            SymbolLocation::OutsideProject {
11305                abs_path,
11306                signature,
11307            } => {
11308                result.path = abs_path.to_string_lossy().into_owned();
11309                result.signature = signature.to_vec();
11310            }
11311        }
11312        result
11313    }
11314
11315    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11316        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11317        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11318        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11319
11320        let path = if serialized_symbol.signature.is_empty() {
11321            SymbolLocation::InProject(ProjectPath {
11322                worktree_id,
11323                path: RelPath::from_proto(&serialized_symbol.path)
11324                    .context("invalid symbol path")?,
11325            })
11326        } else {
11327            SymbolLocation::OutsideProject {
11328                abs_path: Path::new(&serialized_symbol.path).into(),
11329                signature: serialized_symbol
11330                    .signature
11331                    .try_into()
11332                    .map_err(|_| anyhow!("invalid signature"))?,
11333            }
11334        };
11335
11336        let start = serialized_symbol.start.context("invalid start")?;
11337        let end = serialized_symbol.end.context("invalid end")?;
11338        Ok(CoreSymbol {
11339            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11340            source_worktree_id,
11341            source_language_server_id: LanguageServerId::from_proto(
11342                serialized_symbol.language_server_id,
11343            ),
11344            path,
11345            name: serialized_symbol.name,
11346            range: Unclipped(PointUtf16::new(start.row, start.column))
11347                ..Unclipped(PointUtf16::new(end.row, end.column)),
11348            kind,
11349        })
11350    }
11351
11352    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11353        let mut serialized_completion = proto::Completion {
11354            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11355            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11356            new_text: completion.new_text.clone(),
11357            ..proto::Completion::default()
11358        };
11359        match &completion.source {
11360            CompletionSource::Lsp {
11361                insert_range,
11362                server_id,
11363                lsp_completion,
11364                lsp_defaults,
11365                resolved,
11366            } => {
11367                let (old_insert_start, old_insert_end) = insert_range
11368                    .as_ref()
11369                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11370                    .unzip();
11371
11372                serialized_completion.old_insert_start = old_insert_start;
11373                serialized_completion.old_insert_end = old_insert_end;
11374                serialized_completion.source = proto::completion::Source::Lsp as i32;
11375                serialized_completion.server_id = server_id.0 as u64;
11376                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11377                serialized_completion.lsp_defaults = lsp_defaults
11378                    .as_deref()
11379                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11380                serialized_completion.resolved = *resolved;
11381            }
11382            CompletionSource::BufferWord {
11383                word_range,
11384                resolved,
11385            } => {
11386                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11387                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11388                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11389                serialized_completion.resolved = *resolved;
11390            }
11391            CompletionSource::Custom => {
11392                serialized_completion.source = proto::completion::Source::Custom as i32;
11393                serialized_completion.resolved = true;
11394            }
11395            CompletionSource::Dap { sort_text } => {
11396                serialized_completion.source = proto::completion::Source::Dap as i32;
11397                serialized_completion.sort_text = Some(sort_text.clone());
11398            }
11399        }
11400
11401        serialized_completion
11402    }
11403
11404    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11405        let old_replace_start = completion
11406            .old_replace_start
11407            .and_then(deserialize_anchor)
11408            .context("invalid old start")?;
11409        let old_replace_end = completion
11410            .old_replace_end
11411            .and_then(deserialize_anchor)
11412            .context("invalid old end")?;
11413        let insert_range = {
11414            match completion.old_insert_start.zip(completion.old_insert_end) {
11415                Some((start, end)) => {
11416                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11417                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11418                    Some(start..end)
11419                }
11420                None => None,
11421            }
11422        };
11423        Ok(CoreCompletion {
11424            replace_range: old_replace_start..old_replace_end,
11425            new_text: completion.new_text,
11426            source: match proto::completion::Source::from_i32(completion.source) {
11427                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11428                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11429                    insert_range,
11430                    server_id: LanguageServerId::from_proto(completion.server_id),
11431                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11432                    lsp_defaults: completion
11433                        .lsp_defaults
11434                        .as_deref()
11435                        .map(serde_json::from_slice)
11436                        .transpose()?,
11437                    resolved: completion.resolved,
11438                },
11439                Some(proto::completion::Source::BufferWord) => {
11440                    let word_range = completion
11441                        .buffer_word_start
11442                        .and_then(deserialize_anchor)
11443                        .context("invalid buffer word start")?
11444                        ..completion
11445                            .buffer_word_end
11446                            .and_then(deserialize_anchor)
11447                            .context("invalid buffer word end")?;
11448                    CompletionSource::BufferWord {
11449                        word_range,
11450                        resolved: completion.resolved,
11451                    }
11452                }
11453                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11454                    sort_text: completion
11455                        .sort_text
11456                        .context("expected sort text to exist")?,
11457                },
11458                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11459            },
11460        })
11461    }
11462
11463    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11464        let (kind, lsp_action) = match &action.lsp_action {
11465            LspAction::Action(code_action) => (
11466                proto::code_action::Kind::Action as i32,
11467                serde_json::to_vec(code_action).unwrap(),
11468            ),
11469            LspAction::Command(command) => (
11470                proto::code_action::Kind::Command as i32,
11471                serde_json::to_vec(command).unwrap(),
11472            ),
11473            LspAction::CodeLens(code_lens) => (
11474                proto::code_action::Kind::CodeLens as i32,
11475                serde_json::to_vec(code_lens).unwrap(),
11476            ),
11477        };
11478
11479        proto::CodeAction {
11480            server_id: action.server_id.0 as u64,
11481            start: Some(serialize_anchor(&action.range.start)),
11482            end: Some(serialize_anchor(&action.range.end)),
11483            lsp_action,
11484            kind,
11485            resolved: action.resolved,
11486        }
11487    }
11488
11489    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11490        let start = action
11491            .start
11492            .and_then(deserialize_anchor)
11493            .context("invalid start")?;
11494        let end = action
11495            .end
11496            .and_then(deserialize_anchor)
11497            .context("invalid end")?;
11498        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11499            Some(proto::code_action::Kind::Action) => {
11500                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11501            }
11502            Some(proto::code_action::Kind::Command) => {
11503                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11504            }
11505            Some(proto::code_action::Kind::CodeLens) => {
11506                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11507            }
11508            None => anyhow::bail!("Unknown action kind {}", action.kind),
11509        };
11510        Ok(CodeAction {
11511            server_id: LanguageServerId(action.server_id as usize),
11512            range: start..end,
11513            resolved: action.resolved,
11514            lsp_action,
11515        })
11516    }
11517
11518    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11519        match &formatting_result {
11520            Ok(_) => self.last_formatting_failure = None,
11521            Err(error) => {
11522                let error_string = format!("{error:#}");
11523                log::error!("Formatting failed: {error_string}");
11524                self.last_formatting_failure
11525                    .replace(error_string.lines().join(" "));
11526            }
11527        }
11528    }
11529
11530    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11531        self.lsp_server_capabilities.remove(&for_server);
11532        for lsp_data in self.lsp_data.values_mut() {
11533            lsp_data.remove_server_data(for_server);
11534        }
11535        if let Some(local) = self.as_local_mut() {
11536            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11537            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11538                buffer_servers.remove(&for_server);
11539            }
11540        }
11541    }
11542
11543    pub fn result_id(
11544        &self,
11545        server_id: LanguageServerId,
11546        buffer_id: BufferId,
11547        cx: &App,
11548    ) -> Option<String> {
11549        let abs_path = self
11550            .buffer_store
11551            .read(cx)
11552            .get(buffer_id)
11553            .and_then(|b| File::from_dyn(b.read(cx).file()))
11554            .map(|f| f.abs_path(cx))?;
11555        self.as_local()?
11556            .buffer_pull_diagnostics_result_ids
11557            .get(&server_id)?
11558            .get(&abs_path)?
11559            .clone()
11560    }
11561
11562    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11563        let Some(local) = self.as_local() else {
11564            return HashMap::default();
11565        };
11566        local
11567            .buffer_pull_diagnostics_result_ids
11568            .get(&server_id)
11569            .into_iter()
11570            .flatten()
11571            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11572            .collect()
11573    }
11574
11575    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11576        if let Some(LanguageServerState::Running {
11577            workspace_diagnostics_refresh_tasks,
11578            ..
11579        }) = self
11580            .as_local_mut()
11581            .and_then(|local| local.language_servers.get_mut(&server_id))
11582        {
11583            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11584                diagnostics.refresh_tx.try_send(()).ok();
11585            }
11586        }
11587    }
11588
11589    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11590        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11591            return;
11592        };
11593        let Some(local) = self.as_local_mut() else {
11594            return;
11595        };
11596
11597        for server_id in buffer.update(cx, |buffer, cx| {
11598            local.language_server_ids_for_buffer(buffer, cx)
11599        }) {
11600            if let Some(LanguageServerState::Running {
11601                workspace_diagnostics_refresh_tasks,
11602                ..
11603            }) = local.language_servers.get_mut(&server_id)
11604            {
11605                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11606                    diagnostics.refresh_tx.try_send(()).ok();
11607                }
11608            }
11609        }
11610    }
11611
11612    fn apply_workspace_diagnostic_report(
11613        &mut self,
11614        server_id: LanguageServerId,
11615        report: lsp::WorkspaceDiagnosticReportResult,
11616        cx: &mut Context<Self>,
11617    ) {
11618        let workspace_diagnostics =
11619            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11620        let mut unchanged_buffers = HashSet::default();
11621        let mut changed_buffers = HashSet::default();
11622        let workspace_diagnostics_updates = workspace_diagnostics
11623            .into_iter()
11624            .filter_map(
11625                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11626                    LspPullDiagnostics::Response {
11627                        server_id,
11628                        uri,
11629                        diagnostics,
11630                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11631                    LspPullDiagnostics::Default => None,
11632                },
11633            )
11634            .fold(
11635                HashMap::default(),
11636                |mut acc, (server_id, uri, diagnostics, version)| {
11637                    let (result_id, diagnostics) = match diagnostics {
11638                        PulledDiagnostics::Unchanged { result_id } => {
11639                            unchanged_buffers.insert(uri.clone());
11640                            (Some(result_id), Vec::new())
11641                        }
11642                        PulledDiagnostics::Changed {
11643                            result_id,
11644                            diagnostics,
11645                        } => {
11646                            changed_buffers.insert(uri.clone());
11647                            (result_id, diagnostics)
11648                        }
11649                    };
11650                    let disk_based_sources = Cow::Owned(
11651                        self.language_server_adapter_for_id(server_id)
11652                            .as_ref()
11653                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11654                            .unwrap_or(&[])
11655                            .to_vec(),
11656                    );
11657                    acc.entry(server_id)
11658                        .or_insert_with(Vec::new)
11659                        .push(DocumentDiagnosticsUpdate {
11660                            server_id,
11661                            diagnostics: lsp::PublishDiagnosticsParams {
11662                                uri,
11663                                diagnostics,
11664                                version,
11665                            },
11666                            result_id,
11667                            disk_based_sources,
11668                        });
11669                    acc
11670                },
11671            );
11672
11673        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11674            self.merge_lsp_diagnostics(
11675                DiagnosticSourceKind::Pulled,
11676                diagnostic_updates,
11677                |buffer, old_diagnostic, cx| {
11678                    File::from_dyn(buffer.file())
11679                        .and_then(|file| {
11680                            let abs_path = file.as_local()?.abs_path(cx);
11681                            lsp::Uri::from_file_path(abs_path).ok()
11682                        })
11683                        .is_none_or(|buffer_uri| {
11684                            unchanged_buffers.contains(&buffer_uri)
11685                                || match old_diagnostic.source_kind {
11686                                    DiagnosticSourceKind::Pulled => {
11687                                        !changed_buffers.contains(&buffer_uri)
11688                                    }
11689                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11690                                        true
11691                                    }
11692                                }
11693                        })
11694                },
11695                cx,
11696            )
11697            .log_err();
11698        }
11699    }
11700
11701    fn register_server_capabilities(
11702        &mut self,
11703        server_id: LanguageServerId,
11704        params: lsp::RegistrationParams,
11705        cx: &mut Context<Self>,
11706    ) -> anyhow::Result<()> {
11707        let server = self
11708            .language_server_for_id(server_id)
11709            .with_context(|| format!("no server {server_id} found"))?;
11710        for reg in params.registrations {
11711            match reg.method.as_str() {
11712                "workspace/didChangeWatchedFiles" => {
11713                    if let Some(options) = reg.register_options {
11714                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11715                            let caps = serde_json::from_value(options)?;
11716                            local_lsp_store
11717                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11718                            true
11719                        } else {
11720                            false
11721                        };
11722                        if notify {
11723                            notify_server_capabilities_updated(&server, cx);
11724                        }
11725                    }
11726                }
11727                "workspace/didChangeConfiguration" => {
11728                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11729                }
11730                "workspace/didChangeWorkspaceFolders" => {
11731                    // In this case register options is an empty object, we can ignore it
11732                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11733                        supported: Some(true),
11734                        change_notifications: Some(OneOf::Right(reg.id)),
11735                    };
11736                    server.update_capabilities(|capabilities| {
11737                        capabilities
11738                            .workspace
11739                            .get_or_insert_default()
11740                            .workspace_folders = Some(caps);
11741                    });
11742                    notify_server_capabilities_updated(&server, cx);
11743                }
11744                "workspace/symbol" => {
11745                    let options = parse_register_capabilities(reg)?;
11746                    server.update_capabilities(|capabilities| {
11747                        capabilities.workspace_symbol_provider = Some(options);
11748                    });
11749                    notify_server_capabilities_updated(&server, cx);
11750                }
11751                "workspace/fileOperations" => {
11752                    if let Some(options) = reg.register_options {
11753                        let caps = serde_json::from_value(options)?;
11754                        server.update_capabilities(|capabilities| {
11755                            capabilities
11756                                .workspace
11757                                .get_or_insert_default()
11758                                .file_operations = Some(caps);
11759                        });
11760                        notify_server_capabilities_updated(&server, cx);
11761                    }
11762                }
11763                "workspace/executeCommand" => {
11764                    if let Some(options) = reg.register_options {
11765                        let options = serde_json::from_value(options)?;
11766                        server.update_capabilities(|capabilities| {
11767                            capabilities.execute_command_provider = Some(options);
11768                        });
11769                        notify_server_capabilities_updated(&server, cx);
11770                    }
11771                }
11772                "textDocument/rangeFormatting" => {
11773                    let options = parse_register_capabilities(reg)?;
11774                    server.update_capabilities(|capabilities| {
11775                        capabilities.document_range_formatting_provider = Some(options);
11776                    });
11777                    notify_server_capabilities_updated(&server, cx);
11778                }
11779                "textDocument/onTypeFormatting" => {
11780                    if let Some(options) = reg
11781                        .register_options
11782                        .map(serde_json::from_value)
11783                        .transpose()?
11784                    {
11785                        server.update_capabilities(|capabilities| {
11786                            capabilities.document_on_type_formatting_provider = Some(options);
11787                        });
11788                        notify_server_capabilities_updated(&server, cx);
11789                    }
11790                }
11791                "textDocument/formatting" => {
11792                    let options = parse_register_capabilities(reg)?;
11793                    server.update_capabilities(|capabilities| {
11794                        capabilities.document_formatting_provider = Some(options);
11795                    });
11796                    notify_server_capabilities_updated(&server, cx);
11797                }
11798                "textDocument/rename" => {
11799                    let options = parse_register_capabilities(reg)?;
11800                    server.update_capabilities(|capabilities| {
11801                        capabilities.rename_provider = Some(options);
11802                    });
11803                    notify_server_capabilities_updated(&server, cx);
11804                }
11805                "textDocument/inlayHint" => {
11806                    let options = parse_register_capabilities(reg)?;
11807                    server.update_capabilities(|capabilities| {
11808                        capabilities.inlay_hint_provider = Some(options);
11809                    });
11810                    notify_server_capabilities_updated(&server, cx);
11811                }
11812                "textDocument/documentSymbol" => {
11813                    let options = parse_register_capabilities(reg)?;
11814                    server.update_capabilities(|capabilities| {
11815                        capabilities.document_symbol_provider = Some(options);
11816                    });
11817                    notify_server_capabilities_updated(&server, cx);
11818                }
11819                "textDocument/codeAction" => {
11820                    let options = parse_register_capabilities(reg)?;
11821                    let provider = match options {
11822                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11823                        OneOf::Right(caps) => caps,
11824                    };
11825                    server.update_capabilities(|capabilities| {
11826                        capabilities.code_action_provider = Some(provider);
11827                    });
11828                    notify_server_capabilities_updated(&server, cx);
11829                }
11830                "textDocument/definition" => {
11831                    let options = parse_register_capabilities(reg)?;
11832                    server.update_capabilities(|capabilities| {
11833                        capabilities.definition_provider = Some(options);
11834                    });
11835                    notify_server_capabilities_updated(&server, cx);
11836                }
11837                "textDocument/completion" => {
11838                    if let Some(caps) = reg
11839                        .register_options
11840                        .map(serde_json::from_value)
11841                        .transpose()?
11842                    {
11843                        server.update_capabilities(|capabilities| {
11844                            capabilities.completion_provider = Some(caps);
11845                        });
11846                        notify_server_capabilities_updated(&server, cx);
11847                    }
11848                }
11849                "textDocument/hover" => {
11850                    let options = parse_register_capabilities(reg)?;
11851                    let provider = match options {
11852                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11853                        OneOf::Right(caps) => caps,
11854                    };
11855                    server.update_capabilities(|capabilities| {
11856                        capabilities.hover_provider = Some(provider);
11857                    });
11858                    notify_server_capabilities_updated(&server, cx);
11859                }
11860                "textDocument/signatureHelp" => {
11861                    if let Some(caps) = reg
11862                        .register_options
11863                        .map(serde_json::from_value)
11864                        .transpose()?
11865                    {
11866                        server.update_capabilities(|capabilities| {
11867                            capabilities.signature_help_provider = Some(caps);
11868                        });
11869                        notify_server_capabilities_updated(&server, cx);
11870                    }
11871                }
11872                "textDocument/didChange" => {
11873                    if let Some(sync_kind) = reg
11874                        .register_options
11875                        .and_then(|opts| opts.get("syncKind").cloned())
11876                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11877                        .transpose()?
11878                    {
11879                        server.update_capabilities(|capabilities| {
11880                            let mut sync_options =
11881                                Self::take_text_document_sync_options(capabilities);
11882                            sync_options.change = Some(sync_kind);
11883                            capabilities.text_document_sync =
11884                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11885                        });
11886                        notify_server_capabilities_updated(&server, cx);
11887                    }
11888                }
11889                "textDocument/didSave" => {
11890                    if let Some(include_text) = reg
11891                        .register_options
11892                        .map(|opts| {
11893                            let transpose = opts
11894                                .get("includeText")
11895                                .cloned()
11896                                .map(serde_json::from_value::<Option<bool>>)
11897                                .transpose();
11898                            match transpose {
11899                                Ok(value) => Ok(value.flatten()),
11900                                Err(e) => Err(e),
11901                            }
11902                        })
11903                        .transpose()?
11904                    {
11905                        server.update_capabilities(|capabilities| {
11906                            let mut sync_options =
11907                                Self::take_text_document_sync_options(capabilities);
11908                            sync_options.save =
11909                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11910                                    include_text,
11911                                }));
11912                            capabilities.text_document_sync =
11913                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11914                        });
11915                        notify_server_capabilities_updated(&server, cx);
11916                    }
11917                }
11918                "textDocument/codeLens" => {
11919                    if let Some(caps) = reg
11920                        .register_options
11921                        .map(serde_json::from_value)
11922                        .transpose()?
11923                    {
11924                        server.update_capabilities(|capabilities| {
11925                            capabilities.code_lens_provider = Some(caps);
11926                        });
11927                        notify_server_capabilities_updated(&server, cx);
11928                    }
11929                }
11930                "textDocument/diagnostic" => {
11931                    if let Some(caps) = reg
11932                        .register_options
11933                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
11934                        .transpose()?
11935                    {
11936                        let local = self
11937                            .as_local_mut()
11938                            .context("Expected LSP Store to be local")?;
11939                        let state = local
11940                            .language_servers
11941                            .get_mut(&server_id)
11942                            .context("Could not obtain Language Servers state")?;
11943                        local
11944                            .language_server_dynamic_registrations
11945                            .get_mut(&server_id)
11946                            .and_then(|registrations| {
11947                                registrations
11948                                    .diagnostics
11949                                    .insert(Some(reg.id.clone()), caps.clone())
11950                            });
11951
11952                        let mut can_now_provide_diagnostics = false;
11953                        if let LanguageServerState::Running {
11954                            workspace_diagnostics_refresh_tasks,
11955                            ..
11956                        } = state
11957                            && let Some(task) = lsp_workspace_diagnostics_refresh(
11958                                Some(reg.id.clone()),
11959                                caps.clone(),
11960                                server.clone(),
11961                                cx,
11962                            )
11963                        {
11964                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
11965                            can_now_provide_diagnostics = true;
11966                        }
11967
11968                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
11969                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
11970                        // as it'll think that they're not supported.
11971                        if can_now_provide_diagnostics {
11972                            server.update_capabilities(|capabilities| {
11973                                debug_assert!(capabilities.diagnostic_provider.is_none());
11974                                capabilities.diagnostic_provider = Some(caps);
11975                            });
11976                        }
11977
11978                        notify_server_capabilities_updated(&server, cx);
11979                    }
11980                }
11981                "textDocument/documentColor" => {
11982                    let options = parse_register_capabilities(reg)?;
11983                    let provider = match options {
11984                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11985                        OneOf::Right(caps) => caps,
11986                    };
11987                    server.update_capabilities(|capabilities| {
11988                        capabilities.color_provider = Some(provider);
11989                    });
11990                    notify_server_capabilities_updated(&server, cx);
11991                }
11992                _ => log::warn!("unhandled capability registration: {reg:?}"),
11993            }
11994        }
11995
11996        Ok(())
11997    }
11998
11999    fn unregister_server_capabilities(
12000        &mut self,
12001        server_id: LanguageServerId,
12002        params: lsp::UnregistrationParams,
12003        cx: &mut Context<Self>,
12004    ) -> anyhow::Result<()> {
12005        let server = self
12006            .language_server_for_id(server_id)
12007            .with_context(|| format!("no server {server_id} found"))?;
12008        for unreg in params.unregisterations.iter() {
12009            match unreg.method.as_str() {
12010                "workspace/didChangeWatchedFiles" => {
12011                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12012                        local_lsp_store
12013                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12014                        true
12015                    } else {
12016                        false
12017                    };
12018                    if notify {
12019                        notify_server_capabilities_updated(&server, cx);
12020                    }
12021                }
12022                "workspace/didChangeConfiguration" => {
12023                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12024                }
12025                "workspace/didChangeWorkspaceFolders" => {
12026                    server.update_capabilities(|capabilities| {
12027                        capabilities
12028                            .workspace
12029                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12030                                workspace_folders: None,
12031                                file_operations: None,
12032                            })
12033                            .workspace_folders = None;
12034                    });
12035                    notify_server_capabilities_updated(&server, cx);
12036                }
12037                "workspace/symbol" => {
12038                    server.update_capabilities(|capabilities| {
12039                        capabilities.workspace_symbol_provider = None
12040                    });
12041                    notify_server_capabilities_updated(&server, cx);
12042                }
12043                "workspace/fileOperations" => {
12044                    server.update_capabilities(|capabilities| {
12045                        capabilities
12046                            .workspace
12047                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12048                                workspace_folders: None,
12049                                file_operations: None,
12050                            })
12051                            .file_operations = None;
12052                    });
12053                    notify_server_capabilities_updated(&server, cx);
12054                }
12055                "workspace/executeCommand" => {
12056                    server.update_capabilities(|capabilities| {
12057                        capabilities.execute_command_provider = None;
12058                    });
12059                    notify_server_capabilities_updated(&server, cx);
12060                }
12061                "textDocument/rangeFormatting" => {
12062                    server.update_capabilities(|capabilities| {
12063                        capabilities.document_range_formatting_provider = None
12064                    });
12065                    notify_server_capabilities_updated(&server, cx);
12066                }
12067                "textDocument/onTypeFormatting" => {
12068                    server.update_capabilities(|capabilities| {
12069                        capabilities.document_on_type_formatting_provider = None;
12070                    });
12071                    notify_server_capabilities_updated(&server, cx);
12072                }
12073                "textDocument/formatting" => {
12074                    server.update_capabilities(|capabilities| {
12075                        capabilities.document_formatting_provider = None;
12076                    });
12077                    notify_server_capabilities_updated(&server, cx);
12078                }
12079                "textDocument/rename" => {
12080                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12081                    notify_server_capabilities_updated(&server, cx);
12082                }
12083                "textDocument/codeAction" => {
12084                    server.update_capabilities(|capabilities| {
12085                        capabilities.code_action_provider = None;
12086                    });
12087                    notify_server_capabilities_updated(&server, cx);
12088                }
12089                "textDocument/definition" => {
12090                    server.update_capabilities(|capabilities| {
12091                        capabilities.definition_provider = None;
12092                    });
12093                    notify_server_capabilities_updated(&server, cx);
12094                }
12095                "textDocument/completion" => {
12096                    server.update_capabilities(|capabilities| {
12097                        capabilities.completion_provider = None;
12098                    });
12099                    notify_server_capabilities_updated(&server, cx);
12100                }
12101                "textDocument/hover" => {
12102                    server.update_capabilities(|capabilities| {
12103                        capabilities.hover_provider = None;
12104                    });
12105                    notify_server_capabilities_updated(&server, cx);
12106                }
12107                "textDocument/signatureHelp" => {
12108                    server.update_capabilities(|capabilities| {
12109                        capabilities.signature_help_provider = None;
12110                    });
12111                    notify_server_capabilities_updated(&server, cx);
12112                }
12113                "textDocument/didChange" => {
12114                    server.update_capabilities(|capabilities| {
12115                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12116                        sync_options.change = None;
12117                        capabilities.text_document_sync =
12118                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12119                    });
12120                    notify_server_capabilities_updated(&server, cx);
12121                }
12122                "textDocument/didSave" => {
12123                    server.update_capabilities(|capabilities| {
12124                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12125                        sync_options.save = None;
12126                        capabilities.text_document_sync =
12127                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12128                    });
12129                    notify_server_capabilities_updated(&server, cx);
12130                }
12131                "textDocument/codeLens" => {
12132                    server.update_capabilities(|capabilities| {
12133                        capabilities.code_lens_provider = None;
12134                    });
12135                    notify_server_capabilities_updated(&server, cx);
12136                }
12137                "textDocument/diagnostic" => {
12138                    let local = self
12139                        .as_local_mut()
12140                        .context("Expected LSP Store to be local")?;
12141
12142                    let state = local
12143                        .language_servers
12144                        .get_mut(&server_id)
12145                        .context("Could not obtain Language Servers state")?;
12146                    let options = local
12147                        .language_server_dynamic_registrations
12148                        .get_mut(&server_id)
12149                        .with_context(|| {
12150                            format!("Expected dynamic registration to exist for server {server_id}")
12151                        })?.diagnostics
12152                        .remove(&Some(unreg.id.clone()))
12153                        .with_context(|| format!(
12154                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12155                            unreg.id)
12156                        )?;
12157
12158                    let mut has_any_diagnostic_providers_still = true;
12159                    if let Some(identifier) = diagnostic_identifier(&options)
12160                        && let LanguageServerState::Running {
12161                            workspace_diagnostics_refresh_tasks,
12162                            ..
12163                        } = state
12164                    {
12165                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12166                        has_any_diagnostic_providers_still =
12167                            !workspace_diagnostics_refresh_tasks.is_empty();
12168                    }
12169
12170                    if !has_any_diagnostic_providers_still {
12171                        server.update_capabilities(|capabilities| {
12172                            debug_assert!(capabilities.diagnostic_provider.is_some());
12173                            capabilities.diagnostic_provider = None;
12174                        });
12175                    }
12176
12177                    notify_server_capabilities_updated(&server, cx);
12178                }
12179                "textDocument/documentColor" => {
12180                    server.update_capabilities(|capabilities| {
12181                        capabilities.color_provider = None;
12182                    });
12183                    notify_server_capabilities_updated(&server, cx);
12184                }
12185                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12186            }
12187        }
12188
12189        Ok(())
12190    }
12191
12192    async fn deduplicate_range_based_lsp_requests<T>(
12193        lsp_store: &Entity<Self>,
12194        server_id: Option<LanguageServerId>,
12195        lsp_request_id: LspRequestId,
12196        proto_request: &T::ProtoRequest,
12197        range: Range<Anchor>,
12198        cx: &mut AsyncApp,
12199    ) -> Result<()>
12200    where
12201        T: LspCommand,
12202        T::ProtoRequest: proto::LspRequestMessage,
12203    {
12204        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12205        let version = deserialize_version(proto_request.buffer_version());
12206        let buffer = lsp_store.update(cx, |this, cx| {
12207            this.buffer_store.read(cx).get_existing(buffer_id)
12208        })??;
12209        buffer
12210            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12211            .await?;
12212        lsp_store.update(cx, |lsp_store, cx| {
12213            let lsp_data = lsp_store
12214                .lsp_data
12215                .entry(buffer_id)
12216                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12217            let chunks_queried_for = lsp_data
12218                .inlay_hints
12219                .applicable_chunks(&[range])
12220                .collect::<Vec<_>>();
12221            match chunks_queried_for.as_slice() {
12222                &[chunk] => {
12223                    let key = LspKey {
12224                        request_type: TypeId::of::<T>(),
12225                        server_queried: server_id,
12226                    };
12227                    let previous_request = lsp_data
12228                        .chunk_lsp_requests
12229                        .entry(key)
12230                        .or_default()
12231                        .insert(chunk, lsp_request_id);
12232                    if let Some((previous_request, running_requests)) =
12233                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12234                    {
12235                        running_requests.remove(&previous_request);
12236                    }
12237                }
12238                _ambiguous_chunks => {
12239                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12240                    // there, a buffer version-based check will be performed and outdated requests discarded.
12241                }
12242            }
12243            anyhow::Ok(())
12244        })??;
12245
12246        Ok(())
12247    }
12248
12249    async fn query_lsp_locally<T>(
12250        lsp_store: Entity<Self>,
12251        for_server_id: Option<LanguageServerId>,
12252        sender_id: proto::PeerId,
12253        lsp_request_id: LspRequestId,
12254        proto_request: T::ProtoRequest,
12255        position: Option<Anchor>,
12256        cx: &mut AsyncApp,
12257    ) -> Result<()>
12258    where
12259        T: LspCommand + Clone,
12260        T::ProtoRequest: proto::LspRequestMessage,
12261        <T::ProtoRequest as proto::RequestMessage>::Response:
12262            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12263    {
12264        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12265        let version = deserialize_version(proto_request.buffer_version());
12266        let buffer = lsp_store.update(cx, |this, cx| {
12267            this.buffer_store.read(cx).get_existing(buffer_id)
12268        })??;
12269        buffer
12270            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12271            .await?;
12272        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12273        let request =
12274            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12275        let key = LspKey {
12276            request_type: TypeId::of::<T>(),
12277            server_queried: for_server_id,
12278        };
12279        lsp_store.update(cx, |lsp_store, cx| {
12280            let request_task = match for_server_id {
12281                Some(server_id) => {
12282                    let server_task = lsp_store.request_lsp(
12283                        buffer.clone(),
12284                        LanguageServerToQuery::Other(server_id),
12285                        request.clone(),
12286                        cx,
12287                    );
12288                    cx.background_spawn(async move {
12289                        let mut responses = Vec::new();
12290                        match server_task.await {
12291                            Ok(response) => responses.push((server_id, response)),
12292                            Err(e) => log::error!(
12293                                "Error handling response for request {request:?}: {e:#}"
12294                            ),
12295                        }
12296                        responses
12297                    })
12298                }
12299                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12300            };
12301            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12302            if T::ProtoRequest::stop_previous_requests() {
12303                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12304                    lsp_requests.clear();
12305                }
12306            }
12307            lsp_data.lsp_requests.entry(key).or_default().insert(
12308                lsp_request_id,
12309                cx.spawn(async move |lsp_store, cx| {
12310                    let response = request_task.await;
12311                    lsp_store
12312                        .update(cx, |lsp_store, cx| {
12313                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12314                            {
12315                                let response = response
12316                                    .into_iter()
12317                                    .map(|(server_id, response)| {
12318                                        (
12319                                            server_id.to_proto(),
12320                                            T::response_to_proto(
12321                                                response,
12322                                                lsp_store,
12323                                                sender_id,
12324                                                &buffer_version,
12325                                                cx,
12326                                            )
12327                                            .into(),
12328                                        )
12329                                    })
12330                                    .collect::<HashMap<_, _>>();
12331                                match client.send_lsp_response::<T::ProtoRequest>(
12332                                    project_id,
12333                                    lsp_request_id,
12334                                    response,
12335                                ) {
12336                                    Ok(()) => {}
12337                                    Err(e) => {
12338                                        log::error!("Failed to send LSP response: {e:#}",)
12339                                    }
12340                                }
12341                            }
12342                        })
12343                        .ok();
12344                }),
12345            );
12346        })?;
12347        Ok(())
12348    }
12349
12350    fn take_text_document_sync_options(
12351        capabilities: &mut lsp::ServerCapabilities,
12352    ) -> lsp::TextDocumentSyncOptions {
12353        match capabilities.text_document_sync.take() {
12354            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12355            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12356                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12357                sync_options.change = Some(sync_kind);
12358                sync_options
12359            }
12360            None => lsp::TextDocumentSyncOptions::default(),
12361        }
12362    }
12363
12364    #[cfg(any(test, feature = "test-support"))]
12365    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12366        Some(
12367            self.lsp_data
12368                .get_mut(&buffer_id)?
12369                .code_lens
12370                .take()?
12371                .update
12372                .take()?
12373                .1,
12374        )
12375    }
12376
12377    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12378        self.downstream_client.clone()
12379    }
12380
12381    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12382        self.worktree_store.clone()
12383    }
12384
12385    /// Gets what's stored in the LSP data for the given buffer.
12386    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12387        self.lsp_data.get_mut(&buffer_id)
12388    }
12389
12390    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12391    /// new [`BufferLspData`] will be created to replace the previous state.
12392    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12393        let (buffer_id, buffer_version) =
12394            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12395        let lsp_data = self
12396            .lsp_data
12397            .entry(buffer_id)
12398            .or_insert_with(|| BufferLspData::new(buffer, cx));
12399        if buffer_version.changed_since(&lsp_data.buffer_version) {
12400            *lsp_data = BufferLspData::new(buffer, cx);
12401        }
12402        lsp_data
12403    }
12404}
12405
12406// Registration with registerOptions as null, should fallback to true.
12407// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12408fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12409    reg: lsp::Registration,
12410) -> Result<OneOf<bool, T>> {
12411    Ok(match reg.register_options {
12412        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12413        None => OneOf::Left(true),
12414    })
12415}
12416
12417fn subscribe_to_binary_statuses(
12418    languages: &Arc<LanguageRegistry>,
12419    cx: &mut Context<'_, LspStore>,
12420) -> Task<()> {
12421    let mut server_statuses = languages.language_server_binary_statuses();
12422    cx.spawn(async move |lsp_store, cx| {
12423        while let Some((server_name, binary_status)) = server_statuses.next().await {
12424            if lsp_store
12425                .update(cx, |_, cx| {
12426                    let mut message = None;
12427                    let binary_status = match binary_status {
12428                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12429                        BinaryStatus::CheckingForUpdate => {
12430                            proto::ServerBinaryStatus::CheckingForUpdate
12431                        }
12432                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12433                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12434                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12435                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12436                        BinaryStatus::Failed { error } => {
12437                            message = Some(error);
12438                            proto::ServerBinaryStatus::Failed
12439                        }
12440                    };
12441                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12442                        // Binary updates are about the binary that might not have any language server id at that point.
12443                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12444                        language_server_id: LanguageServerId(0),
12445                        name: Some(server_name),
12446                        message: proto::update_language_server::Variant::StatusUpdate(
12447                            proto::StatusUpdate {
12448                                message,
12449                                status: Some(proto::status_update::Status::Binary(
12450                                    binary_status as i32,
12451                                )),
12452                            },
12453                        ),
12454                    });
12455                })
12456                .is_err()
12457            {
12458                break;
12459            }
12460        }
12461    })
12462}
12463
12464fn lsp_workspace_diagnostics_refresh(
12465    registration_id: Option<String>,
12466    options: DiagnosticServerCapabilities,
12467    server: Arc<LanguageServer>,
12468    cx: &mut Context<'_, LspStore>,
12469) -> Option<WorkspaceRefreshTask> {
12470    let identifier = diagnostic_identifier(&options)?;
12471
12472    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12473    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12474    refresh_tx.try_send(()).ok();
12475
12476    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12477        let mut attempts = 0;
12478        let max_attempts = 50;
12479        let mut requests = 0;
12480
12481        loop {
12482            let Some(()) = refresh_rx.recv().await else {
12483                return;
12484            };
12485
12486            'request: loop {
12487                requests += 1;
12488                if attempts > max_attempts {
12489                    log::error!(
12490                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12491                    );
12492                    return;
12493                }
12494                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12495                cx.background_executor()
12496                    .timer(Duration::from_millis(backoff_millis))
12497                    .await;
12498                attempts += 1;
12499
12500                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12501                    lsp_store
12502                        .all_result_ids(server.server_id())
12503                        .into_iter()
12504                        .filter_map(|(abs_path, result_id)| {
12505                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12506                            Some(lsp::PreviousResultId {
12507                                uri,
12508                                value: result_id,
12509                            })
12510                        })
12511                        .collect()
12512                }) else {
12513                    return;
12514                };
12515
12516                let token = if let Some(identifier) = &registration_id {
12517                    format!(
12518                        "workspace/diagnostic/{}/{requests}/id:{identifier}",
12519                        server.server_id(),
12520                    )
12521                } else {
12522                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12523                };
12524
12525                progress_rx.try_recv().ok();
12526                let timer =
12527                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12528                let progress = pin!(progress_rx.recv().fuse());
12529                let response_result = server
12530                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12531                        lsp::WorkspaceDiagnosticParams {
12532                            previous_result_ids,
12533                            identifier: identifier.clone(),
12534                            work_done_progress_params: Default::default(),
12535                            partial_result_params: lsp::PartialResultParams {
12536                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12537                            },
12538                        },
12539                        select(timer, progress).then(|either| match either {
12540                            Either::Left((message, ..)) => ready(message).left_future(),
12541                            Either::Right(..) => pending::<String>().right_future(),
12542                        }),
12543                    )
12544                    .await;
12545
12546                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12547                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12548                match response_result {
12549                    ConnectionResult::Timeout => {
12550                        log::error!("Timeout during workspace diagnostics pull");
12551                        continue 'request;
12552                    }
12553                    ConnectionResult::ConnectionReset => {
12554                        log::error!("Server closed a workspace diagnostics pull request");
12555                        continue 'request;
12556                    }
12557                    ConnectionResult::Result(Err(e)) => {
12558                        log::error!("Error during workspace diagnostics pull: {e:#}");
12559                        break 'request;
12560                    }
12561                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12562                        attempts = 0;
12563                        if lsp_store
12564                            .update(cx, |lsp_store, cx| {
12565                                lsp_store.apply_workspace_diagnostic_report(
12566                                    server.server_id(),
12567                                    pulled_diagnostics,
12568                                    cx,
12569                                )
12570                            })
12571                            .is_err()
12572                        {
12573                            return;
12574                        }
12575                        break 'request;
12576                    }
12577                }
12578            }
12579        }
12580    });
12581
12582    Some(WorkspaceRefreshTask {
12583        refresh_tx,
12584        progress_tx,
12585        task: workspace_query_language_server,
12586    })
12587}
12588
12589fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12590    match &options {
12591        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12592            if !diagnostic_options.workspace_diagnostics {
12593                return None;
12594            }
12595            Some(diagnostic_options.identifier.clone())
12596        }
12597        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12598            let diagnostic_options = &registration_options.diagnostic_options;
12599            if !diagnostic_options.workspace_diagnostics {
12600                return None;
12601            }
12602            Some(diagnostic_options.identifier.clone())
12603        }
12604    }
12605}
12606
12607fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12608    let CompletionSource::BufferWord {
12609        word_range,
12610        resolved,
12611    } = &mut completion.source
12612    else {
12613        return;
12614    };
12615    if *resolved {
12616        return;
12617    }
12618
12619    if completion.new_text
12620        != snapshot
12621            .text_for_range(word_range.clone())
12622            .collect::<String>()
12623    {
12624        return;
12625    }
12626
12627    let mut offset = 0;
12628    for chunk in snapshot.chunks(word_range.clone(), true) {
12629        let end_offset = offset + chunk.text.len();
12630        if let Some(highlight_id) = chunk.syntax_highlight_id {
12631            completion
12632                .label
12633                .runs
12634                .push((offset..end_offset, highlight_id));
12635        }
12636        offset = end_offset;
12637    }
12638    *resolved = true;
12639}
12640
12641impl EventEmitter<LspStoreEvent> for LspStore {}
12642
12643fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12644    hover
12645        .contents
12646        .retain(|hover_block| !hover_block.text.trim().is_empty());
12647    if hover.contents.is_empty() {
12648        None
12649    } else {
12650        Some(hover)
12651    }
12652}
12653
12654async fn populate_labels_for_completions(
12655    new_completions: Vec<CoreCompletion>,
12656    language: Option<Arc<Language>>,
12657    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12658) -> Vec<Completion> {
12659    let lsp_completions = new_completions
12660        .iter()
12661        .filter_map(|new_completion| {
12662            new_completion
12663                .source
12664                .lsp_completion(true)
12665                .map(|lsp_completion| lsp_completion.into_owned())
12666        })
12667        .collect::<Vec<_>>();
12668
12669    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12670        lsp_adapter
12671            .labels_for_completions(&lsp_completions, language)
12672            .await
12673            .log_err()
12674            .unwrap_or_default()
12675    } else {
12676        Vec::new()
12677    }
12678    .into_iter()
12679    .fuse();
12680
12681    let mut completions = Vec::new();
12682    for completion in new_completions {
12683        match completion.source.lsp_completion(true) {
12684            Some(lsp_completion) => {
12685                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12686
12687                let mut label = labels.next().flatten().unwrap_or_else(|| {
12688                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12689                });
12690                ensure_uniform_list_compatible_label(&mut label);
12691                completions.push(Completion {
12692                    label,
12693                    documentation,
12694                    replace_range: completion.replace_range,
12695                    new_text: completion.new_text,
12696                    insert_text_mode: lsp_completion.insert_text_mode,
12697                    source: completion.source,
12698                    icon_path: None,
12699                    confirm: None,
12700                });
12701            }
12702            None => {
12703                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12704                ensure_uniform_list_compatible_label(&mut label);
12705                completions.push(Completion {
12706                    label,
12707                    documentation: None,
12708                    replace_range: completion.replace_range,
12709                    new_text: completion.new_text,
12710                    source: completion.source,
12711                    insert_text_mode: None,
12712                    icon_path: None,
12713                    confirm: None,
12714                });
12715            }
12716        }
12717    }
12718    completions
12719}
12720
12721#[derive(Debug)]
12722pub enum LanguageServerToQuery {
12723    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12724    FirstCapable,
12725    /// Query a specific language server.
12726    Other(LanguageServerId),
12727}
12728
12729#[derive(Default)]
12730struct RenamePathsWatchedForServer {
12731    did_rename: Vec<RenameActionPredicate>,
12732    will_rename: Vec<RenameActionPredicate>,
12733}
12734
12735impl RenamePathsWatchedForServer {
12736    fn with_did_rename_patterns(
12737        mut self,
12738        did_rename: Option<&FileOperationRegistrationOptions>,
12739    ) -> Self {
12740        if let Some(did_rename) = did_rename {
12741            self.did_rename = did_rename
12742                .filters
12743                .iter()
12744                .filter_map(|filter| filter.try_into().log_err())
12745                .collect();
12746        }
12747        self
12748    }
12749    fn with_will_rename_patterns(
12750        mut self,
12751        will_rename: Option<&FileOperationRegistrationOptions>,
12752    ) -> Self {
12753        if let Some(will_rename) = will_rename {
12754            self.will_rename = will_rename
12755                .filters
12756                .iter()
12757                .filter_map(|filter| filter.try_into().log_err())
12758                .collect();
12759        }
12760        self
12761    }
12762
12763    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12764        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12765    }
12766    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12767        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12768    }
12769}
12770
12771impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12772    type Error = globset::Error;
12773    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12774        Ok(Self {
12775            kind: ops.pattern.matches.clone(),
12776            glob: GlobBuilder::new(&ops.pattern.glob)
12777                .case_insensitive(
12778                    ops.pattern
12779                        .options
12780                        .as_ref()
12781                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12782                )
12783                .build()?
12784                .compile_matcher(),
12785        })
12786    }
12787}
12788struct RenameActionPredicate {
12789    glob: GlobMatcher,
12790    kind: Option<FileOperationPatternKind>,
12791}
12792
12793impl RenameActionPredicate {
12794    // Returns true if language server should be notified
12795    fn eval(&self, path: &str, is_dir: bool) -> bool {
12796        self.kind.as_ref().is_none_or(|kind| {
12797            let expected_kind = if is_dir {
12798                FileOperationPatternKind::Folder
12799            } else {
12800                FileOperationPatternKind::File
12801            };
12802            kind == &expected_kind
12803        }) && self.glob.is_match(path)
12804    }
12805}
12806
12807#[derive(Default)]
12808struct LanguageServerWatchedPaths {
12809    worktree_paths: HashMap<WorktreeId, GlobSet>,
12810    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12811}
12812
12813#[derive(Default)]
12814struct LanguageServerWatchedPathsBuilder {
12815    worktree_paths: HashMap<WorktreeId, GlobSet>,
12816    abs_paths: HashMap<Arc<Path>, GlobSet>,
12817}
12818
12819impl LanguageServerWatchedPathsBuilder {
12820    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12821        self.worktree_paths.insert(worktree_id, glob_set);
12822    }
12823    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12824        self.abs_paths.insert(path, glob_set);
12825    }
12826    fn build(
12827        self,
12828        fs: Arc<dyn Fs>,
12829        language_server_id: LanguageServerId,
12830        cx: &mut Context<LspStore>,
12831    ) -> LanguageServerWatchedPaths {
12832        let project = cx.weak_entity();
12833
12834        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12835        let abs_paths = self
12836            .abs_paths
12837            .into_iter()
12838            .map(|(abs_path, globset)| {
12839                let task = cx.spawn({
12840                    let abs_path = abs_path.clone();
12841                    let fs = fs.clone();
12842
12843                    let lsp_store = project.clone();
12844                    async move |_, cx| {
12845                        maybe!(async move {
12846                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12847                            while let Some(update) = push_updates.0.next().await {
12848                                let action = lsp_store
12849                                    .update(cx, |this, _| {
12850                                        let Some(local) = this.as_local() else {
12851                                            return ControlFlow::Break(());
12852                                        };
12853                                        let Some(watcher) = local
12854                                            .language_server_watched_paths
12855                                            .get(&language_server_id)
12856                                        else {
12857                                            return ControlFlow::Break(());
12858                                        };
12859                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12860                                            "Watched abs path is not registered with a watcher",
12861                                        );
12862                                        let matching_entries = update
12863                                            .into_iter()
12864                                            .filter(|event| globs.is_match(&event.path))
12865                                            .collect::<Vec<_>>();
12866                                        this.lsp_notify_abs_paths_changed(
12867                                            language_server_id,
12868                                            matching_entries,
12869                                        );
12870                                        ControlFlow::Continue(())
12871                                    })
12872                                    .ok()?;
12873
12874                                if action.is_break() {
12875                                    break;
12876                                }
12877                            }
12878                            Some(())
12879                        })
12880                        .await;
12881                    }
12882                });
12883                (abs_path, (globset, task))
12884            })
12885            .collect();
12886        LanguageServerWatchedPaths {
12887            worktree_paths: self.worktree_paths,
12888            abs_paths,
12889        }
12890    }
12891}
12892
12893struct LspBufferSnapshot {
12894    version: i32,
12895    snapshot: TextBufferSnapshot,
12896}
12897
12898/// A prompt requested by LSP server.
12899#[derive(Clone, Debug)]
12900pub struct LanguageServerPromptRequest {
12901    pub level: PromptLevel,
12902    pub message: String,
12903    pub actions: Vec<MessageActionItem>,
12904    pub lsp_name: String,
12905    pub(crate) response_channel: Sender<MessageActionItem>,
12906}
12907
12908impl LanguageServerPromptRequest {
12909    pub async fn respond(self, index: usize) -> Option<()> {
12910        if let Some(response) = self.actions.into_iter().nth(index) {
12911            self.response_channel.send(response).await.ok()
12912        } else {
12913            None
12914        }
12915    }
12916}
12917impl PartialEq for LanguageServerPromptRequest {
12918    fn eq(&self, other: &Self) -> bool {
12919        self.message == other.message && self.actions == other.actions
12920    }
12921}
12922
12923#[derive(Clone, Debug, PartialEq)]
12924pub enum LanguageServerLogType {
12925    Log(MessageType),
12926    Trace { verbose_info: Option<String> },
12927    Rpc { received: bool },
12928}
12929
12930impl LanguageServerLogType {
12931    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12932        match self {
12933            Self::Log(log_type) => {
12934                use proto::log_message::LogLevel;
12935                let level = match *log_type {
12936                    MessageType::ERROR => LogLevel::Error,
12937                    MessageType::WARNING => LogLevel::Warning,
12938                    MessageType::INFO => LogLevel::Info,
12939                    MessageType::LOG => LogLevel::Log,
12940                    other => {
12941                        log::warn!("Unknown lsp log message type: {other:?}");
12942                        LogLevel::Log
12943                    }
12944                };
12945                proto::language_server_log::LogType::Log(proto::LogMessage {
12946                    level: level as i32,
12947                })
12948            }
12949            Self::Trace { verbose_info } => {
12950                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12951                    verbose_info: verbose_info.to_owned(),
12952                })
12953            }
12954            Self::Rpc { received } => {
12955                let kind = if *received {
12956                    proto::rpc_message::Kind::Received
12957                } else {
12958                    proto::rpc_message::Kind::Sent
12959                };
12960                let kind = kind as i32;
12961                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12962            }
12963        }
12964    }
12965
12966    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12967        use proto::log_message::LogLevel;
12968        use proto::rpc_message;
12969        match log_type {
12970            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12971                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12972                    LogLevel::Error => MessageType::ERROR,
12973                    LogLevel::Warning => MessageType::WARNING,
12974                    LogLevel::Info => MessageType::INFO,
12975                    LogLevel::Log => MessageType::LOG,
12976                },
12977            ),
12978            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12979                verbose_info: trace_message.verbose_info,
12980            },
12981            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12982                received: match rpc_message::Kind::from_i32(message.kind)
12983                    .unwrap_or(rpc_message::Kind::Received)
12984                {
12985                    rpc_message::Kind::Received => true,
12986                    rpc_message::Kind::Sent => false,
12987                },
12988            },
12989        }
12990    }
12991}
12992
12993pub struct WorkspaceRefreshTask {
12994    refresh_tx: mpsc::Sender<()>,
12995    progress_tx: mpsc::Sender<()>,
12996    #[allow(dead_code)]
12997    task: Task<()>,
12998}
12999
13000pub enum LanguageServerState {
13001    Starting {
13002        startup: Task<Option<Arc<LanguageServer>>>,
13003        /// List of language servers that will be added to the workspace once it's initialization completes.
13004        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13005    },
13006
13007    Running {
13008        adapter: Arc<CachedLspAdapter>,
13009        server: Arc<LanguageServer>,
13010        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13011        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13012    },
13013}
13014
13015impl LanguageServerState {
13016    fn add_workspace_folder(&self, uri: Uri) {
13017        match self {
13018            LanguageServerState::Starting {
13019                pending_workspace_folders,
13020                ..
13021            } => {
13022                pending_workspace_folders.lock().insert(uri);
13023            }
13024            LanguageServerState::Running { server, .. } => {
13025                server.add_workspace_folder(uri);
13026            }
13027        }
13028    }
13029    fn _remove_workspace_folder(&self, uri: Uri) {
13030        match self {
13031            LanguageServerState::Starting {
13032                pending_workspace_folders,
13033                ..
13034            } => {
13035                pending_workspace_folders.lock().remove(&uri);
13036            }
13037            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13038        }
13039    }
13040}
13041
13042impl std::fmt::Debug for LanguageServerState {
13043    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13044        match self {
13045            LanguageServerState::Starting { .. } => {
13046                f.debug_struct("LanguageServerState::Starting").finish()
13047            }
13048            LanguageServerState::Running { .. } => {
13049                f.debug_struct("LanguageServerState::Running").finish()
13050            }
13051        }
13052    }
13053}
13054
13055#[derive(Clone, Debug, Serialize)]
13056pub struct LanguageServerProgress {
13057    pub is_disk_based_diagnostics_progress: bool,
13058    pub is_cancellable: bool,
13059    pub title: Option<String>,
13060    pub message: Option<String>,
13061    pub percentage: Option<usize>,
13062    #[serde(skip_serializing)]
13063    pub last_update_at: Instant,
13064}
13065
13066#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13067pub struct DiagnosticSummary {
13068    pub error_count: usize,
13069    pub warning_count: usize,
13070}
13071
13072impl DiagnosticSummary {
13073    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13074        let mut this = Self {
13075            error_count: 0,
13076            warning_count: 0,
13077        };
13078
13079        for entry in diagnostics {
13080            if entry.diagnostic.is_primary {
13081                match entry.diagnostic.severity {
13082                    DiagnosticSeverity::ERROR => this.error_count += 1,
13083                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13084                    _ => {}
13085                }
13086            }
13087        }
13088
13089        this
13090    }
13091
13092    pub fn is_empty(&self) -> bool {
13093        self.error_count == 0 && self.warning_count == 0
13094    }
13095
13096    pub fn to_proto(
13097        self,
13098        language_server_id: LanguageServerId,
13099        path: &RelPath,
13100    ) -> proto::DiagnosticSummary {
13101        proto::DiagnosticSummary {
13102            path: path.to_proto(),
13103            language_server_id: language_server_id.0 as u64,
13104            error_count: self.error_count as u32,
13105            warning_count: self.warning_count as u32,
13106        }
13107    }
13108}
13109
13110#[derive(Clone, Debug)]
13111pub enum CompletionDocumentation {
13112    /// There is no documentation for this completion.
13113    Undocumented,
13114    /// A single line of documentation.
13115    SingleLine(SharedString),
13116    /// Multiple lines of plain text documentation.
13117    MultiLinePlainText(SharedString),
13118    /// Markdown documentation.
13119    MultiLineMarkdown(SharedString),
13120    /// Both single line and multiple lines of plain text documentation.
13121    SingleLineAndMultiLinePlainText {
13122        single_line: SharedString,
13123        plain_text: Option<SharedString>,
13124    },
13125}
13126
13127impl CompletionDocumentation {
13128    #[cfg(any(test, feature = "test-support"))]
13129    pub fn text(&self) -> SharedString {
13130        match self {
13131            CompletionDocumentation::Undocumented => "".into(),
13132            CompletionDocumentation::SingleLine(s) => s.clone(),
13133            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13134            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13135            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13136                single_line.clone()
13137            }
13138        }
13139    }
13140}
13141
13142impl From<lsp::Documentation> for CompletionDocumentation {
13143    fn from(docs: lsp::Documentation) -> Self {
13144        match docs {
13145            lsp::Documentation::String(text) => {
13146                if text.lines().count() <= 1 {
13147                    CompletionDocumentation::SingleLine(text.into())
13148                } else {
13149                    CompletionDocumentation::MultiLinePlainText(text.into())
13150                }
13151            }
13152
13153            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13154                lsp::MarkupKind::PlainText => {
13155                    if value.lines().count() <= 1 {
13156                        CompletionDocumentation::SingleLine(value.into())
13157                    } else {
13158                        CompletionDocumentation::MultiLinePlainText(value.into())
13159                    }
13160                }
13161
13162                lsp::MarkupKind::Markdown => {
13163                    CompletionDocumentation::MultiLineMarkdown(value.into())
13164                }
13165            },
13166        }
13167    }
13168}
13169
13170pub enum ResolvedHint {
13171    Resolved(InlayHint),
13172    Resolving(Shared<Task<()>>),
13173}
13174
13175fn glob_literal_prefix(glob: &Path) -> PathBuf {
13176    glob.components()
13177        .take_while(|component| match component {
13178            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13179            _ => true,
13180        })
13181        .collect()
13182}
13183
13184pub struct SshLspAdapter {
13185    name: LanguageServerName,
13186    binary: LanguageServerBinary,
13187    initialization_options: Option<String>,
13188    code_action_kinds: Option<Vec<CodeActionKind>>,
13189}
13190
13191impl SshLspAdapter {
13192    pub fn new(
13193        name: LanguageServerName,
13194        binary: LanguageServerBinary,
13195        initialization_options: Option<String>,
13196        code_action_kinds: Option<String>,
13197    ) -> Self {
13198        Self {
13199            name,
13200            binary,
13201            initialization_options,
13202            code_action_kinds: code_action_kinds
13203                .as_ref()
13204                .and_then(|c| serde_json::from_str(c).ok()),
13205        }
13206    }
13207}
13208
13209impl LspInstaller for SshLspAdapter {
13210    type BinaryVersion = ();
13211    async fn check_if_user_installed(
13212        &self,
13213        _: &dyn LspAdapterDelegate,
13214        _: Option<Toolchain>,
13215        _: &AsyncApp,
13216    ) -> Option<LanguageServerBinary> {
13217        Some(self.binary.clone())
13218    }
13219
13220    async fn cached_server_binary(
13221        &self,
13222        _: PathBuf,
13223        _: &dyn LspAdapterDelegate,
13224    ) -> Option<LanguageServerBinary> {
13225        None
13226    }
13227
13228    async fn fetch_latest_server_version(
13229        &self,
13230        _: &dyn LspAdapterDelegate,
13231        _: bool,
13232        _: &mut AsyncApp,
13233    ) -> Result<()> {
13234        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13235    }
13236
13237    async fn fetch_server_binary(
13238        &self,
13239        _: (),
13240        _: PathBuf,
13241        _: &dyn LspAdapterDelegate,
13242    ) -> Result<LanguageServerBinary> {
13243        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13244    }
13245}
13246
13247#[async_trait(?Send)]
13248impl LspAdapter for SshLspAdapter {
13249    fn name(&self) -> LanguageServerName {
13250        self.name.clone()
13251    }
13252
13253    async fn initialization_options(
13254        self: Arc<Self>,
13255        _: &Arc<dyn LspAdapterDelegate>,
13256    ) -> Result<Option<serde_json::Value>> {
13257        let Some(options) = &self.initialization_options else {
13258            return Ok(None);
13259        };
13260        let result = serde_json::from_str(options)?;
13261        Ok(result)
13262    }
13263
13264    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13265        self.code_action_kinds.clone()
13266    }
13267}
13268
13269pub fn language_server_settings<'a>(
13270    delegate: &'a dyn LspAdapterDelegate,
13271    language: &LanguageServerName,
13272    cx: &'a App,
13273) -> Option<&'a LspSettings> {
13274    language_server_settings_for(
13275        SettingsLocation {
13276            worktree_id: delegate.worktree_id(),
13277            path: RelPath::empty(),
13278        },
13279        language,
13280        cx,
13281    )
13282}
13283
13284pub(crate) fn language_server_settings_for<'a>(
13285    location: SettingsLocation<'a>,
13286    language: &LanguageServerName,
13287    cx: &'a App,
13288) -> Option<&'a LspSettings> {
13289    ProjectSettings::get(Some(location), cx).lsp.get(language)
13290}
13291
13292pub struct LocalLspAdapterDelegate {
13293    lsp_store: WeakEntity<LspStore>,
13294    worktree: worktree::Snapshot,
13295    fs: Arc<dyn Fs>,
13296    http_client: Arc<dyn HttpClient>,
13297    language_registry: Arc<LanguageRegistry>,
13298    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13299}
13300
13301impl LocalLspAdapterDelegate {
13302    pub fn new(
13303        language_registry: Arc<LanguageRegistry>,
13304        environment: &Entity<ProjectEnvironment>,
13305        lsp_store: WeakEntity<LspStore>,
13306        worktree: &Entity<Worktree>,
13307        http_client: Arc<dyn HttpClient>,
13308        fs: Arc<dyn Fs>,
13309        cx: &mut App,
13310    ) -> Arc<Self> {
13311        let load_shell_env_task = environment.update(cx, |env, cx| {
13312            env.get_worktree_environment(worktree.clone(), cx)
13313        });
13314
13315        Arc::new(Self {
13316            lsp_store,
13317            worktree: worktree.read(cx).snapshot(),
13318            fs,
13319            http_client,
13320            language_registry,
13321            load_shell_env_task,
13322        })
13323    }
13324
13325    fn from_local_lsp(
13326        local: &LocalLspStore,
13327        worktree: &Entity<Worktree>,
13328        cx: &mut App,
13329    ) -> Arc<Self> {
13330        Self::new(
13331            local.languages.clone(),
13332            &local.environment,
13333            local.weak.clone(),
13334            worktree,
13335            local.http_client.clone(),
13336            local.fs.clone(),
13337            cx,
13338        )
13339    }
13340}
13341
13342#[async_trait]
13343impl LspAdapterDelegate for LocalLspAdapterDelegate {
13344    fn show_notification(&self, message: &str, cx: &mut App) {
13345        self.lsp_store
13346            .update(cx, |_, cx| {
13347                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13348            })
13349            .ok();
13350    }
13351
13352    fn http_client(&self) -> Arc<dyn HttpClient> {
13353        self.http_client.clone()
13354    }
13355
13356    fn worktree_id(&self) -> WorktreeId {
13357        self.worktree.id()
13358    }
13359
13360    fn worktree_root_path(&self) -> &Path {
13361        self.worktree.abs_path().as_ref()
13362    }
13363
13364    async fn shell_env(&self) -> HashMap<String, String> {
13365        let task = self.load_shell_env_task.clone();
13366        task.await.unwrap_or_default()
13367    }
13368
13369    async fn npm_package_installed_version(
13370        &self,
13371        package_name: &str,
13372    ) -> Result<Option<(PathBuf, String)>> {
13373        let local_package_directory = self.worktree_root_path();
13374        let node_modules_directory = local_package_directory.join("node_modules");
13375
13376        if let Some(version) =
13377            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13378        {
13379            return Ok(Some((node_modules_directory, version)));
13380        }
13381        let Some(npm) = self.which("npm".as_ref()).await else {
13382            log::warn!(
13383                "Failed to find npm executable for {:?}",
13384                local_package_directory
13385            );
13386            return Ok(None);
13387        };
13388
13389        let env = self.shell_env().await;
13390        let output = util::command::new_smol_command(&npm)
13391            .args(["root", "-g"])
13392            .envs(env)
13393            .current_dir(local_package_directory)
13394            .output()
13395            .await?;
13396        let global_node_modules =
13397            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13398
13399        if let Some(version) =
13400            read_package_installed_version(global_node_modules.clone(), package_name).await?
13401        {
13402            return Ok(Some((global_node_modules, version)));
13403        }
13404        return Ok(None);
13405    }
13406
13407    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13408        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13409        if self.fs.is_file(&worktree_abs_path).await {
13410            worktree_abs_path.pop();
13411        }
13412
13413        let env = self.shell_env().await;
13414
13415        let shell_path = env.get("PATH").cloned();
13416
13417        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13418    }
13419
13420    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13421        let mut working_dir = self.worktree_root_path().to_path_buf();
13422        if self.fs.is_file(&working_dir).await {
13423            working_dir.pop();
13424        }
13425        let output = util::command::new_smol_command(&command.path)
13426            .args(command.arguments)
13427            .envs(command.env.clone().unwrap_or_default())
13428            .current_dir(working_dir)
13429            .output()
13430            .await?;
13431
13432        anyhow::ensure!(
13433            output.status.success(),
13434            "{}, stdout: {:?}, stderr: {:?}",
13435            output.status,
13436            String::from_utf8_lossy(&output.stdout),
13437            String::from_utf8_lossy(&output.stderr)
13438        );
13439        Ok(())
13440    }
13441
13442    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13443        self.language_registry
13444            .update_lsp_binary_status(server_name, status);
13445    }
13446
13447    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13448        self.language_registry
13449            .all_lsp_adapters()
13450            .into_iter()
13451            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13452            .collect()
13453    }
13454
13455    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13456        let dir = self.language_registry.language_server_download_dir(name)?;
13457
13458        if !dir.exists() {
13459            smol::fs::create_dir_all(&dir)
13460                .await
13461                .context("failed to create container directory")
13462                .log_err()?;
13463        }
13464
13465        Some(dir)
13466    }
13467
13468    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13469        let entry = self
13470            .worktree
13471            .entry_for_path(path)
13472            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13473        let abs_path = self.worktree.absolutize(&entry.path);
13474        self.fs.load(&abs_path).await
13475    }
13476}
13477
13478async fn populate_labels_for_symbols(
13479    symbols: Vec<CoreSymbol>,
13480    language_registry: &Arc<LanguageRegistry>,
13481    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13482    output: &mut Vec<Symbol>,
13483) {
13484    #[allow(clippy::mutable_key_type)]
13485    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13486
13487    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13488    for symbol in symbols {
13489        let Some(file_name) = symbol.path.file_name() else {
13490            continue;
13491        };
13492        let language = language_registry
13493            .load_language_for_file_path(Path::new(file_name))
13494            .await
13495            .ok()
13496            .or_else(|| {
13497                unknown_paths.insert(file_name.into());
13498                None
13499            });
13500        symbols_by_language
13501            .entry(language)
13502            .or_default()
13503            .push(symbol);
13504    }
13505
13506    for unknown_path in unknown_paths {
13507        log::info!("no language found for symbol in file {unknown_path:?}");
13508    }
13509
13510    let mut label_params = Vec::new();
13511    for (language, mut symbols) in symbols_by_language {
13512        label_params.clear();
13513        label_params.extend(
13514            symbols
13515                .iter_mut()
13516                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13517        );
13518
13519        let mut labels = Vec::new();
13520        if let Some(language) = language {
13521            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13522                language_registry
13523                    .lsp_adapters(&language.name())
13524                    .first()
13525                    .cloned()
13526            });
13527            if let Some(lsp_adapter) = lsp_adapter {
13528                labels = lsp_adapter
13529                    .labels_for_symbols(&label_params, &language)
13530                    .await
13531                    .log_err()
13532                    .unwrap_or_default();
13533            }
13534        }
13535
13536        for ((symbol, (name, _)), label) in symbols
13537            .into_iter()
13538            .zip(label_params.drain(..))
13539            .zip(labels.into_iter().chain(iter::repeat(None)))
13540        {
13541            output.push(Symbol {
13542                language_server_name: symbol.language_server_name,
13543                source_worktree_id: symbol.source_worktree_id,
13544                source_language_server_id: symbol.source_language_server_id,
13545                path: symbol.path,
13546                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13547                name,
13548                kind: symbol.kind,
13549                range: symbol.range,
13550            });
13551        }
13552    }
13553}
13554
13555fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13556    match server.capabilities().text_document_sync.as_ref()? {
13557        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13558            // Server wants didSave but didn't specify includeText.
13559            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13560            // Server doesn't want didSave at all.
13561            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13562            // Server provided SaveOptions.
13563            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13564                Some(save_options.include_text.unwrap_or(false))
13565            }
13566        },
13567        // We do not have any save info. Kind affects didChange only.
13568        lsp::TextDocumentSyncCapability::Kind(_) => None,
13569    }
13570}
13571
13572/// Completion items are displayed in a `UniformList`.
13573/// Usually, those items are single-line strings, but in LSP responses,
13574/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13575/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13576/// 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,
13577/// breaking the completions menu presentation.
13578///
13579/// 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.
13580fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13581    let mut new_text = String::with_capacity(label.text.len());
13582    let mut offset_map = vec![0; label.text.len() + 1];
13583    let mut last_char_was_space = false;
13584    let mut new_idx = 0;
13585    let chars = label.text.char_indices().fuse();
13586    let mut newlines_removed = false;
13587
13588    for (idx, c) in chars {
13589        offset_map[idx] = new_idx;
13590
13591        match c {
13592            '\n' if last_char_was_space => {
13593                newlines_removed = true;
13594            }
13595            '\t' | ' ' if last_char_was_space => {}
13596            '\n' if !last_char_was_space => {
13597                new_text.push(' ');
13598                new_idx += 1;
13599                last_char_was_space = true;
13600                newlines_removed = true;
13601            }
13602            ' ' | '\t' => {
13603                new_text.push(' ');
13604                new_idx += 1;
13605                last_char_was_space = true;
13606            }
13607            _ => {
13608                new_text.push(c);
13609                new_idx += c.len_utf8();
13610                last_char_was_space = false;
13611            }
13612        }
13613    }
13614    offset_map[label.text.len()] = new_idx;
13615
13616    // Only modify the label if newlines were removed.
13617    if !newlines_removed {
13618        return;
13619    }
13620
13621    let last_index = new_idx;
13622    let mut run_ranges_errors = Vec::new();
13623    label.runs.retain_mut(|(range, _)| {
13624        match offset_map.get(range.start) {
13625            Some(&start) => range.start = start,
13626            None => {
13627                run_ranges_errors.push(range.clone());
13628                return false;
13629            }
13630        }
13631
13632        match offset_map.get(range.end) {
13633            Some(&end) => range.end = end,
13634            None => {
13635                run_ranges_errors.push(range.clone());
13636                range.end = last_index;
13637            }
13638        }
13639        true
13640    });
13641    if !run_ranges_errors.is_empty() {
13642        log::error!(
13643            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13644            label.text
13645        );
13646    }
13647
13648    let mut wrong_filter_range = None;
13649    if label.filter_range == (0..label.text.len()) {
13650        label.filter_range = 0..new_text.len();
13651    } else {
13652        let mut original_filter_range = Some(label.filter_range.clone());
13653        match offset_map.get(label.filter_range.start) {
13654            Some(&start) => label.filter_range.start = start,
13655            None => {
13656                wrong_filter_range = original_filter_range.take();
13657                label.filter_range.start = last_index;
13658            }
13659        }
13660
13661        match offset_map.get(label.filter_range.end) {
13662            Some(&end) => label.filter_range.end = end,
13663            None => {
13664                wrong_filter_range = original_filter_range.take();
13665                label.filter_range.end = last_index;
13666            }
13667        }
13668    }
13669    if let Some(wrong_filter_range) = wrong_filter_range {
13670        log::error!(
13671            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13672            label.text
13673        );
13674    }
13675
13676    label.text = new_text;
13677}
13678
13679#[cfg(test)]
13680mod tests {
13681    use language::HighlightId;
13682
13683    use super::*;
13684
13685    #[test]
13686    fn test_glob_literal_prefix() {
13687        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13688        assert_eq!(
13689            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13690            Path::new("node_modules")
13691        );
13692        assert_eq!(
13693            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13694            Path::new("foo")
13695        );
13696        assert_eq!(
13697            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13698            Path::new("foo/bar/baz.js")
13699        );
13700
13701        #[cfg(target_os = "windows")]
13702        {
13703            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13704            assert_eq!(
13705                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13706                Path::new("node_modules")
13707            );
13708            assert_eq!(
13709                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13710                Path::new("foo")
13711            );
13712            assert_eq!(
13713                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13714                Path::new("foo/bar/baz.js")
13715            );
13716        }
13717    }
13718
13719    #[test]
13720    fn test_multi_len_chars_normalization() {
13721        let mut label = CodeLabel::new(
13722            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13723            0..6,
13724            vec![(0..6, HighlightId(1))],
13725        );
13726        ensure_uniform_list_compatible_label(&mut label);
13727        assert_eq!(
13728            label,
13729            CodeLabel::new(
13730                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13731                0..6,
13732                vec![(0..6, HighlightId(1))],
13733            )
13734        );
13735    }
13736}